1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20 // make sure word alignment is OFF!
21
22 #include "rt_def.h"
23 #include "rt_sound.h"
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <time.h>
28
29 #ifdef DOS
30 #include <io.h>
31 #include <conio.h>
32 #include <dos.h>
33 #else
34 #include <errno.h>
35 #endif
36
37 #include "states.h"
38 #include "watcom.h"
39 #include "rt_ted.h"
40 #include "_rt_ted.h"
41 #include "w_wad.h"
42 #include "z_zone.h"
43 #include "rt_util.h"
44 #include "lumpy.h"
45 #include "rt_vid.h"
46 #include "rt_actor.h"
47 #include "rt_stat.h"
48 #include "rt_menu.h"
49 #include "rt_draw.h"
50 #include "rt_com.h"
51 #include "rt_main.h"
52 #include "rt_door.h"
53 #include "rt_playr.h"
54 #include "rt_view.h"
55 #include "rt_str.h"
56 #include "isr.h"
57 #include "rt_floor.h"
58 #include "rt_game.h"
59 #include "rt_rand.h"
60 #include "rt_cfg.h"
61 #include "develop.h"
62 #include "modexlib.h"
63 #include "engine.h"
64 #include "rt_debug.h"
65 #include "rt_scale.h"
66 #include "rt_net.h"
67 //MED
68 #include "memcheck.h"
69
70
71
72
73 //========================================
74 // GLOBAL VARIABLES
75 //========================================
76
77
78
79 teamtype TEAM[MAXPLAYERS];
80 int numareatiles[NUMAREAS+1];
81 int shapestart,shapestop;
82 _2dvec SPAWNLOC[MAXSPAWNLOCATIONS],FIRST,SECOND;
83 int NUMSPAWNLOCATIONS,numteams=0;
84 wall_t walls[MAXWALLTILES];
85 str_clock Clocks[MAXCLOCKS];
86 int numclocks;
87 int LightsInArea[NUMAREAS+1];
88
89 int maxheight;
90 int nominalheight;
91 int elevatorstart;
92 int gunsstart;
93 int fog;
94 int lightsource;
95 int SNAKELEVEL;
96 int whichpath;
97
98 word *mapplanes[3];
99 int mapwidth;
100 int mapheight;
101 int lastlevelloaded=-1;
102
103 boolean insetupgame;
104 boolean ISRTL = false;
105
106 unsigned MapSpecials = 0;
107
108 char LevelName[80];
109
110 //========================================
111 // LOCAL VARIABLES
112 //========================================
113
114 static cachetype * cachelist;
115 static word cacheindex;
116 static boolean CachingStarted=false;
117 char * ROTTMAPS = STANDARDGAMELEVELS;
118 char * BATTMAPS = STANDARDBATTLELEVELS;
119
120 static char NormalWeaponTiles[ 10 ] =
121 {
122 46, 48, 49, 50, 51, 52, 53, 54, 55, 56
123 };
124 static char SharewareWeaponTiles[ 7 ] =
125 {
126 48, 49, 50, 51, 52, 53, 54
127 };
128
129 static char CacheStrings[MAXSILLYSTRINGS][80]=
130 {
131 {"Ready yourself\nfor destruction!\0\0"},
132 {"Here comes the enemy!\0\0"},
133 {"Hope you wrote\nyour will!\0\0"},
134 {"Did you bring your\nextra bullets?\0\0"},
135 {"Try not to bleed\non the rug.\0\0"},
136 {"Let's see...bandages,\ntape, splints,...\0\0"},
137 {"Couldn't we just\ntalk this over?\0\0"},
138 {"Cache as cache can...\0\0"},
139 {"You are smart.\nMake us strong.\0\0"},
140 {"Bleh!\0\0"},
141 {"I am as far\nabove you...\0\0"},
142 {"Just keep thinkin':\nBut it's loadin' COOL\nstuff...\0\0"},
143 {"Guess which line\nwill win!\0\0"},
144 {"Oh, no. Not again.\0\0"},
145 {"Wait! I'm not ready!\nToo late.\0\0"},
146 {"Hope this doesn't\ncrash.\0\0"},
147 {"Have a sandwich.\0\0"},
148 {"Smoke 'em if\nya got 'em...and\nif ya like cancer.\0\0"},
149 {"Ummmmm...\0\0"},
150 {"Bang! Bang! Bang!\nFreeze!\0\0"},
151 {"You have the right\nto...DIE.\0\0"},
152 {"Insert funny phrase\nhere.\0\0"},
153 {"Blood, bullets,\nnicely decorated\nhallways.\0\0"},
154 {"You are to be killed,\nnot hurt.\0\0"},
155 {"It's time for you to\ngo down the stairs!\0\0"},
156 {"This game, like,\nrules and stuff.\0\0"},
157 {"We get money for this!\nHa ha ha ha!\0\0"},
158 {"Let's not start any\nreligious wars...\0\0"},
159 {"I don't wanna start\nno ting...\0\0"},
160 {"Ah, another sacrifice!\0\0"},
161 {"If you were dead,\nyou'd be the\nsame thing.\0\0"},
162 {"This Game isn't\nhuman; it can't\nbe reasoned with!\0\0"}
163 };
164
165 void SetupGameLevel (void);
166 void ScanInfoPlane(void);
167
168 void DrawPreCache( void );
169 void InitializePlayerstates(void);
170 void SetupSnakePath(void);
171 void SetupRandomActors(void);
172 void SetupActors(void);
173 void SetupStatics(void);
174 void LoftSprites( void );
175 int GetLumpForTile(int tile);
176
177 //========================================
178
179 /*
180 ======================
181 =
182 = SortPreCache
183 = Sort the Precache for cachelevel precedence using a HEAPSORT
184 =
185 ======================
186 */
187 #define SGN(x) ((x>0) ? (1) : ((x==0) ? (0) : (-1)))
188
189 /*--------------------------------------------------------------------------*/
CompareTags(s1p,s2p)190 int CompareTags(s1p,s2p) cachetype *s1p,*s2p;
191 {
192 // Sort according to lump
193 if (DoPanicMapping()==true)
194 return SGN(s1p->cachelevel-s2p->cachelevel);
195 // Sort according to cachelevel
196 else
197 return SGN(s1p->lump-s2p->lump);
198 }
199
SwitchCacheEntries(s1p,s2p)200 void SwitchCacheEntries(s1p,s2p) cachetype *s1p,*s2p;
201 {
202 cachetype temp;
203
204 temp=*s1p;
205 *s1p=*s2p;
206 *s2p=temp;
207 }
208
209
210
SortPreCache(void)211 void SortPreCache( void )
212 {
213 hsort((char *)cachelist,cacheindex,sizeof(cachetype),&CompareTags,&SwitchCacheEntries);
214 }
215
216 //========================================
217
218
219 /*
220 ======================
221 =
222 = SetupPreCache
223 = Setup the cache for pre-cacheing
224 =
225 ======================
226 */
SetupPreCache(void)227 void SetupPreCache( void )
228 {
229
230 CachingStarted=true;
231 cacheindex=0;
232 cachelist=(cachetype *)SafeMalloc(MAXPRECACHE*(sizeof(cachetype)));
233 DrawPreCache();
234 }
235
236
237 /*
238 ======================
239 =
240 = ShutdownPreCache
241 = Setup the cache for pre-cacheing
242 =
243 ======================
244 */
ShutdownPreCache(void)245 void ShutdownPreCache( void )
246 {
247
248 CachingStarted=false;
249 SafeFree((byte *)cachelist);
250 }
251
252
253 /*
254 ======================
255 =
256 = PreCacheLump
257 = precache the lump and check to see if it is already tagged
258 =
259 ======================
260 */
PreCacheLump(int lump,int level)261 void PreCacheLump( int lump, int level )
262 {
263 int i;
264
265 if (CachingStarted==false)
266 return;
267 if (!W_LumpLength(lump))
268 {
269 #if (PRECACHETEST == 1)
270 SoftError("Tried to precache a label, lump = %ld tag=%ld maskednum=%ld\n",lump, level, maskednum);
271 #endif
272 return;
273 }
274 for (i=1;i<cacheindex;i++)
275 if (cachelist[i].lump==lump)
276 return;
277 cachelist[cacheindex].lump=lump;
278 cachelist[cacheindex++].cachelevel=level;
279 if (cacheindex==MAXPRECACHE)
280 Error("MaxPreCache reached\n");
281 }
282
283
284
285 /*
286 ======================
287 =
288 = PreCacheGroup
289 = precache the lump and check to see if it is already tagged
290 =
291 ======================
292 */
PreCacheGroup(int start,int end)293 void PreCacheGroup( int start, int end )
294 {
295 int i;
296 int j;
297 int k;
298 int found;
299
300 if (CachingStarted==false)
301 return;
302 k=cacheindex;
303 for (j=start;j<=end;j++)
304 {
305 if (!W_LumpLength(j))
306 {
307 #if (PRECACHETEST == 1)
308 SoftError("Tried to precache a label, lump = %ld\n",j);
309 #endif
310 continue;
311 }
312 found=0;
313 for (i=1;i<k;i++)
314 if (cachelist[i].lump==j)
315 {
316 found=1;
317 break;
318 }
319 if (found==0)
320 {
321 cachelist[cacheindex].lump=j;
322 cachelist[cacheindex++].cachelevel=PU_CACHEACTORS;
323
324 if (cacheindex==MAXPRECACHE)
325 Error("MaxPreCache reached\n");
326 }
327 }
328
329 }
330
331
332 /*
333 ======================
334 =
335 = PreCachePlayers
336 = precache the lump and check to see if it is already tagged
337 =
338 ======================
339 */
PreCachePlayers(void)340 void PreCachePlayers(void )
341 {
342 int start;
343 int end;
344 int i;
345 playertype*pstate;
346
347 for(i=0;i<numplayers;i++)
348 {if (i!=consoleplayer) // don't cache consoleplayer
349 {pstate = &PLAYERSTATE[i];
350 start=W_GetNumForName("CASSHO11")+(pstate->player*REMOTEOFFSET);
351 end =W_GetNumForName("CASWDEAD")+(pstate->player*REMOTEOFFSET);
352 PreCacheGroup(start,end);
353 }
354 }
355 }
356
357
358
359
PreCachePlayerSound(void)360 void PreCachePlayerSound(void)
361 {
362 switch (locplayerstate->player)
363 {
364 case 0:
365 SD_PreCacheSound(SD_PLAYERTCSND);
366
367 break;
368 case 1:
369 SD_PreCacheSound(SD_PLAYERTBSND);
370
371 break;
372 case 2:
373 SD_PreCacheSound(SD_PLAYERDWSND);
374
375 break;
376 case 3:
377 SD_PreCacheSound(SD_PLAYERLNSND);
378
379 break;
380 case 4:
381 SD_PreCacheSound(SD_PLAYERIPFSND);
382 break;
383 }
384 }
385
386
387 #define IS_ALTERNATE_ACTOR(ob) \
388 ((ob->shapeoffset - deathshapeoffset[ob->obclass]) > 0)\
389
390 /*
391 ======================
392 =
393 = PreCacheActor
394 = precache the lump and check to see if it is already tagged
395 =
396 ======================
397 */
PreCacheActor(int actor,int which)398 void PreCacheActor( int actor, int which )
399 {
400 int start;
401 int end;
402
403 switch (actor)
404 {
405 case lowguardobj:
406 if (IS_ALTERNATE_ACTOR(new))
407 {
408 start = SD_LOWGUARD2SEESND;
409 end = SD_LOWGUARD2SEE3SND;
410 SD_PreCacheSoundGroup(start,end);
411
412 start = SD_LOWGUARD2DIESND;
413 end = SD_LOWGUARD2DIESND;
414 SD_PreCacheSoundGroup(start,end);
415
416 start = SD_LOWGUARDFIRESND;
417 end = SD_SNEAKYSPRINGFSND;
418 SD_PreCacheSoundGroup(start,end);
419
420 start=W_GetNumForName("MARSHOO1");
421 end =W_GetNumForName("MNGRISE4");
422 //end =W_GetNumForName("MARUSE28");
423 }
424
425 else
426 {start = SD_LOWGUARD1SEESND;
427 end = SD_LOWGUARD1SEE3SND;
428 SD_PreCacheSoundGroup(start,end);
429
430 start = SD_LOWGUARD1DIESND;
431 end = SD_LOWGUARD1DIESND;
432 SD_PreCacheSoundGroup(start,end);
433
434 start = SD_LOWGUARDFIRESND;
435 end = SD_SNEAKYSPRINGFSND;
436 SD_PreCacheSoundGroup(start,end);
437
438 start=W_GetNumForName("LWGSHOO1");
439 end = W_GetNumForName("SNGRISE4");
440 //end =W_GetNumForName("LOWUSE28");
441 }
442
443 break;
444 case highguardobj:
445
446 start = SD_HIGHGUARD1SEESND;
447 end = SD_HIGHGUARDDIESND;
448 SD_PreCacheSoundGroup(start,end);
449
450 if (IS_ALTERNATE_ACTOR(new))
451 {
452 start=W_GetNumForName("HIGSHOO1");
453 end =W_GetNumForName("HIGWDEAD");
454 //end =W_GetNumForName("HIHUSE28");
455 }
456 else
457 {
458 start=W_GetNumForName("HG2SHOO1");
459 end =W_GetNumForName("HG2WDEAD");
460 //end =W_GetNumForName("H2HUSE28");
461 }
462 break;
463
464 case overpatrolobj:
465
466 start=W_GetNumForName("OBBOLO1");
467 end =W_GetNumForName("OBBOLO4");
468 PreCacheGroup(start,end);
469 start=W_GetNumForName("NET1");
470 end =W_GetNumForName("NET4");
471 PreCacheGroup(start,end);
472
473 start = SD_OVERP1SEESND;
474 end = SD_OVERPDIESND;
475 SD_PreCacheSoundGroup(start,end);
476 SD_PreCacheSoundGroup(SD_NETWIGGLESND,SD_NETFALLSND);
477
478 if (IS_ALTERNATE_ACTOR(new))
479 {
480 start=W_GetNumForName("PATSHOO1");
481 end =W_GetNumForName("PATDEAD");
482
483 //end =W_GetNumForName("OBPUSE28");
484 }
485
486 else
487 {
488 start=W_GetNumForName("OBPSHOO1");
489 end =W_GetNumForName("OBPDEAD");
490
491 //end =W_GetNumForName("PATUSE28");
492 }
493
494 break;
495 case strikeguardobj:
496
497
498 start = SD_STRIKE1SEESND;
499 end = SD_STRIKEDIESND;
500 SD_PreCacheSoundGroup(start,end);
501
502 if (IS_ALTERNATE_ACTOR(new))
503 {
504 start=W_GetNumForName("XYGSHOO1");
505 end =W_GetNumForName("XYLROLL6");
506 //end =W_GetNumForName("XYUSE28");
507 }
508
509 else
510 {
511 start=W_GetNumForName("ANGSHOO1");
512 end =W_GetNumForName("ANLROLL6");
513 //end =W_GetNumForName("ANUSE28");
514 }
515
516 break;
517
518 case blitzguardobj:
519
520 start = SD_BLITZ1SEESND;
521 end = SD_BLITZDIESND;
522 SD_PreCacheSoundGroup(start,end);
523
524 if (IS_ALTERNATE_ACTOR(new))
525 {
526 start=W_GetNumForName("WIGSHOO1");
527 end =W_GetNumForName("WIHUSE28");
528 }
529
530 else
531 {
532 start=W_GetNumForName("LIGSHOO1");
533 end =W_GetNumForName("LIPEAD11");
534 }
535
536 break;
537
538 case triadenforcerobj:
539
540 start = SD_ENFORCERSEESND;
541 end = SD_ENFORCERDIESND;
542 SD_PreCacheSoundGroup(start,end);
543
544 start=W_GetNumForName("TEGREN1");
545 end =W_GetNumForName("TGRENF6");
546 PreCacheGroup(start,end);
547 start=W_GetNumForName("TRISHOO1");
548 end =W_GetNumForName("TRIWDEAD");
549 //end =W_GetNumForName("TRIUSE28");
550 break;
551 case deathmonkobj:
552
553
554 start = SD_MONKSEESND;
555 end = SD_MONKDIESND;
556 SD_PreCacheSoundGroup(start,end);
557
558 start=W_GetNumForName("MONKDR1");
559 end =W_GetNumForName("MONDEAD");
560 //end =W_GetNumForName("MONUSE28");
561 break;
562
563
564 case dfiremonkobj:
565
566 start = SD_FIREMONKSEESND;
567 end = SD_FIREMONKDIESND;
568 SD_PreCacheSoundGroup(start,end);
569
570 start = W_GetNumForName("MONFIRE1");
571 end = W_GetNumForName("MONFIRE4");
572 PreCacheGroup(start,end);
573
574
575 if (IS_ALTERNATE_ACTOR(new))
576 {
577 start=W_GetNumForName("MRKKSH1");
578 end =W_GetNumForName("MRKDEAD7");
579 }
580
581 else
582 {
583 start=W_GetNumForName("ALLKSH1");
584 end =W_GetNumForName("ALLDEAD7");
585 }
586
587 break;
588
589 case roboguardobj:
590
591 start = SD_ROBOTSEESND;
592 end = SD_ROBOTDIESND;
593 SD_PreCacheSoundGroup(start,end);
594 start=W_GetNumForName("ROBOGRD1");
595 end =W_GetNumForName("ROBGRD16");
596 break;
597
598 case b_darianobj:
599
600 PreCachePlayerSound();
601
602 start = SD_DARIANSEESND;
603 end = SD_DARIANSAY3;
604 SD_PreCacheSoundGroup(start,end);
605
606
607 start=W_GetNumForName("DARSHOO1");
608 end =W_GetNumForName("DARUSE28");
609 break;
610
611
612 case b_heinrichobj:
613
614 PreCachePlayerSound();
615
616 start = SD_KRISTSEESND;
617 end = SD_KRISTSAY3;
618 SD_PreCacheSoundGroup(start,end);
619
620 start=W_GetNumForName("MINE1");
621 end =W_GetNumForName("MINE4");
622 PreCacheGroup(start,end);
623 start=W_GetNumForName("HSIT1");
624 end =W_GetNumForName("HDOPE8");
625 break;
626
627 case b_darkmonkobj:
628
629 start = SD_DARKMONKSEESND;
630 end = SD_DARKMONKSAY3;
631 SD_PreCacheSoundGroup(start,end);
632
633 start=W_GetNumForName("LIGNING1");
634 end =W_GetNumForName("FSPARK4");
635 PreCacheGroup(start,end);
636 start=W_GetNumForName("TOMS1");
637 end =W_GetNumForName("TOHRH8");
638 break;
639
640 case b_darksnakeobj:
641
642 PreCachePlayerSound();
643
644 start = SD_SNAKESEESND;
645 end = SD_SNAKESAY3;
646 SD_PreCacheSoundGroup(start,end);
647
648 start=W_GetNumForName("TOMRH1");
649 end =W_GetNumForName("TOHRH8");
650 case b_robobossobj:
651
652 PreCachePlayerSound();
653
654 start = SD_NMESEESND;
655 end = SD_NMESEESND;
656 SD_PreCacheSoundGroup(start,end);
657
658 start=W_GetNumForName("RHEAD101");
659 end =W_GetNumForName("NMESAUC4");
660 break;
661 case patrolgunobj:
662
663 start = SD_EMPLACEMENTSEESND;
664 end = SD_BIGEMPLACEFIRESND;
665 SD_PreCacheSoundGroup(start,end);
666
667
668 start=W_GetNumForName("GUNEMP1");
669 end =W_GetNumForName("GUNEMPF8");
670 PreCacheGroup(start,end);
671 start=W_GetNumForName("GRISE11");
672 end =W_GetNumForName("GDEAD2");
673 break;
674
675 case wallopobj:
676 start=W_GetNumForName("BSTAR1");
677 end =W_GetNumForName("BSTAR4");
678 PreCacheGroup(start,end);
679 start=W_GetNumForName("BCRAFT1");
680 end =W_GetNumForName("BCRAFT16");
681 break;
682
683 case wallfireobj:
684
685 SD_PreCacheSound(SD_FIRECHUTESND);
686 SD_PreCacheSound(SD_FIREBALLSND);
687 SD_PreCacheSound(SD_FIREBALLHITSND);
688
689 start = W_GetNumForName("CRFIRE11");
690 end = W_GetNumForName("CREXP5");
691
692 case pillarobj:
693
694 start=W_GetNumForName("PUSHCOL1");
695 end =W_GetNumForName("PSHCOL1A");
696 //end =W_GetNumForName("PUSHCOL3");
697 break;
698
699 case firejetobj:
700
701 SD_PreCacheSound(SD_FIREJETSND);
702
703 if (which)
704 {
705 start=W_GetNumForName("FJUP0");
706 end =W_GetNumForName("FJUP22");
707 }
708 #if (SHAREWARE == 0)
709 else
710 {
711 start=W_GetNumForName("FJDOWN0");
712 end =W_GetNumForName("FJDOWN22");
713 }
714 #endif
715
716 break;
717
718 case bladeobj:
719
720 SD_PreCacheSound(SD_BLADESPINSND);
721
722
723 #if (SHAREWARE == 0)
724
725
726 if (which&2)
727 {
728 if (which&1)
729 {
730 start=W_GetNumForName("SPSTUP1");
731 end =W_GetNumForName("SPSTUP16");
732 }
733 else
734 {
735 start=W_GetNumForName("SPSTDN1");
736 end =W_GetNumForName("SPSTDN16");
737 }
738 }
739 else
740 {
741 if (which&1)
742 {
743 start=W_GetNumForName("UBLADE1");
744 end =W_GetNumForName("UBLADE9");
745 }
746 else
747 {
748 start=W_GetNumForName("DBLADE1");
749 end =W_GetNumForName("DBLADE9");
750 }
751 }
752 #else
753 start=W_GetNumForName("UBLADE1");
754 end =W_GetNumForName("UBLADE9");
755 #endif
756
757 break;
758 case crushcolobj:
759
760 SD_PreCacheSound(SD_CYLINDERMOVESND);
761 if (which)
762 {
763 start=W_GetNumForName("CRDOWN1");
764 end =W_GetNumForName("CRDOWN8");
765 }
766 #if (SHAREWARE == 0)
767 else
768 {
769 start=W_GetNumForName("CRUP1");
770 end =W_GetNumForName("CRUP8");
771 }
772 #endif
773 break;
774
775 case boulderobj:
776 start=W_GetNumForName("BOL11");
777 end =W_GetNumForName("BSINK9");
778 SD_PreCacheSound(SD_BOULDERHITSND);
779 SD_PreCacheSound(SD_BOULDERROLLSND);
780 SD_PreCacheSound(SD_BOULDERFALLSND);
781
782 break;
783
784 case spearobj:
785 SD_PreCacheSound(SD_SPEARSTABSND);
786
787 if (which)
788 {
789 start=W_GetNumForName("SPEARUP1");
790 end =W_GetNumForName("SPERUP16");
791 }
792 #if (SHAREWARE == 0)
793 else
794 {
795 start=W_GetNumForName("SPEARDN1");
796 end =W_GetNumForName("SPERDN16");
797 }
798 #endif
799
800 break;
801
802 case gasgrateobj:
803
804 start = SD_GASSTARTSND;
805 end = SD_GASMASKSND;
806 SD_PreCacheSoundGroup(start,end);
807 if ((locplayerstate->player == 1) || (locplayerstate->player == 3))
808 SD_PreCacheSound(SD_PLAYERCOUGHFSND);
809 else
810 SD_PreCacheSound(SD_PLAYERCOUGHMSND);
811 start=-1;
812 end=-1;
813 break;
814
815 case springobj:
816
817 SD_PreCacheSound(SD_SPRINGBOARDSND);
818
819 start=W_GetNumForName("SPRING1");
820 end =W_GetNumForName("SPRING9");
821 break;
822 default:
823 return;
824 break;
825 }
826 if ((start>=0) && (end>=0))
827 PreCacheGroup(start,end);
828 }
829
830
831
832 /*
833 ======================
834 =
835 = MiscPreCache
836 = precache the lump and check to see if it is already tagged
837 =
838 ======================
839 */
MiscPreCache(void)840 void MiscPreCache( void )
841 {
842 int start;
843 int end;
844
845 //essential sounds
846
847 SD_PreCacheSoundGroup(SD_HITWALLSND,SD_PLAYERDWHURTSND);
848 SD_PreCacheSoundGroup(SD_RICOCHET1SND,SD_RICOCHET3SND);
849 SD_PreCacheSound(SD_ATKPISTOLSND);
850 SD_PreCacheSoundGroup(SD_PLAYERBURNEDSND,SD_PLAYERLANDSND);
851 SD_PreCacheSoundGroup(SD_EXPLODEFLOORSND,SD_EXPLODESND);
852
853 if (lightning==true)
854 SD_PreCacheSound(SD_LIGHTNINGSND);
855
856 SD_PreCacheSound(SD_BODYLANDSND);
857 SD_PreCacheSound(SD_GIBSPLASHSND);
858 SD_PreCacheSound(SD_ACTORLANDSND);
859 SD_PreCacheSound(SD_ACTORSQUISHSND);
860
861
862 // cache in bullet hole graphics
863 start=W_GetNumForName("BULLETHO");
864 end=W_GetNumForName("ALTBHO");
865 PreCacheGroup(start,end);
866
867
868 // cache in explosions
869
870 if (DoPanicMapping()==true)
871 {
872 start=W_GetNumForName("EXPLOS1");
873 end =W_GetNumForName("EXPLOS20");
874 PreCacheGroup(start,end);
875 }
876 else
877 {
878 start=W_GetNumForName("EXPLOS1");
879 end =W_GetNumForName("GREXP25");
880 PreCacheGroup(start,end);
881 }
882
883 // cache in misc player sprites
884 start=W_GetNumForName("BLOODS1");
885 end =W_GetNumForName("PLATFRM5");
886 PreCacheGroup(start,end);
887
888 // cache in missile smoke
889 start=W_GetNumForName("MISSMO11");
890 end =W_GetNumForName("MISSMO14");
891 PreCacheGroup(start,end);
892
893 #if (DEVELOPMENT == 1)
894 // cache in all weapon sounds
895 SD_PreCacheSoundGroup(SD_ATKPISTOLSND,SD_LOSEMODESND);
896
897 // cache in misc player weapons
898 #if (SHAREWARE == 0)
899 start=W_GetNumForName("KNIFE1");
900 end =W_GetNumForName("DOGPAW4");
901 PreCacheGroup(start,end);
902 // cache in kinetic sphere
903 start=W_GetNumForName("KSPHERE1");
904 end =W_GetNumForName("KSPHERE4");
905 PreCacheGroup(start,end);
906
907 #else
908 start=W_GetNumForName("MPIST11");
909 end =W_GetNumForName("GODHAND8");
910 PreCacheGroup(start,end);
911 #endif
912
913
914 // cache in god mode stuff
915
916 PreCacheGroup(W_GetNumForName("VAPO1"),
917 W_GetNumForName("LITSOUL"));
918
919 PreCacheGroup(W_GetNumForName("GODFIRE1"),
920 W_GetNumForName("GODFIRE4"));
921
922
923 #endif
924 // cache in player's gun
925
926 // cache in rubble
927 start=W_GetNumForName("RUBBLE1");
928 end =W_GetNumForName("RUBBLE10");
929 PreCacheGroup(start,end);
930
931 // cache in guts
932 start=W_GetNumForName("GUTS1");
933 end =W_GetNumForName("GUTS12");
934 PreCacheGroup(start,end);
935
936 // cache in player missile
937 start=W_GetNumForName("BJMISS1");
938 end =W_GetNumForName("BJMISS16");
939 PreCacheGroup(start,end);
940
941 if (gamestate.violence >= vl_high)
942 { // cache in all gibs
943 if (DoPanicMapping()==true)
944 {
945 start = W_GetNumForName("ORGAN1");
946 end = W_GetNumForName("ORGAN12");
947 }
948 else
949 {
950 start = W_GetNumForName("PART1");
951 end = W_GetNumForName("GEYE3");
952 }
953 PreCacheGroup(start,end);
954 }
955 }
956
957
958 /*
959 ========================
960 =
961 = IsChristmas
962 =
963 ========================
964 */
965
IsChristmas(void)966 boolean IsChristmas(void)
967 {
968 struct dosdate_t date;
969
970 _dos_getdate(&date);
971
972 if (((date.day == 24) || (date.day == 25)) && //Christmas
973 (date.month == 12)
974 )
975 return true;
976
977 return false;
978
979 }
980
981
982 /*
983 ========================
984 =
985 = CheckHolidays
986 =
987 ========================
988 */
989
CheckHolidays(void)990 void CheckHolidays(void)
991 {
992 struct dosdate_t date;
993
994 _dos_getdate(&date);
995
996
997 if (IsChristmas())
998 DrawNormalSprite(0,0,W_GetNumForName("santahat"));
999
1000 else if ((date.month == 5) && (date.day == 5)) // Cinco de Mayo
1001 DrawNormalSprite(0,0,W_GetNumForName("sombrero"));
1002
1003 else if ((date.month == 7) && (date.day == 4)) // 4th of July
1004 DrawNormalSprite(0,0,W_GetNumForName("amflag"));
1005
1006 else if ((date.month == 10) && (date.day == 31)) // Halloween
1007 DrawNormalSprite(0,0,W_GetNumForName("witchhat"));
1008
1009 else if ((date.month == 4) && (date.dayofweek == 0)) //Easter
1010 {
1011 int i;
1012
1013 for(i=15;i<=21;i++)
1014 {
1015 if (date.day == i)
1016 DrawNormalSprite(0,0,W_GetNumForName("esterhat"));
1017 }
1018 }
1019 }
1020
1021
1022 /*
1023 ======================
1024 =
1025 = DrawPreCache
1026 =
1027 ======================
1028 */
1029 extern boolean dopefish;
DrawPreCache(void)1030 void DrawPreCache( void )
1031 {
1032 if (loadedgame==false)
1033 {
1034 char temp[80];
1035 int width, height, num;
1036 char buf[30];
1037
1038 if ( BATTLEMODE )
1039 {
1040 VL_DrawPostPic (W_GetNumForName("trilogo"));
1041 VWB_TBar ( 30, 23, 260, 82 );
1042 ShowBattleOptions( false, 56, 26 );
1043
1044 DrawPlayers ();
1045 }
1046 else
1047 {
1048 pic_t * pic;
1049 pic=(pic_t *)W_CacheLumpName("mmbk",PU_CACHE, Cvt_pic_t, 1);
1050 VWB_DrawPic (0, 0, pic);
1051
1052 CheckHolidays();
1053 }
1054
1055 DrawNormalSprite (PRECACHEBARX, PRECACHEBARY, W_GetNumForName ("cachebar"));
1056
1057 CurrentFont=smallfont;
1058
1059 PrintY = PRECACHEESTRINGY;
1060 PrintX = PRECACHEESTRINGX;
1061
1062 memset (&buf[0], 0, sizeof (buf));
1063
1064 if ( !BATTLEMODE )
1065 {
1066 memcpy (&buf[0], "EPISODE ", 8);
1067 itoa (gamestate.episode,&buf[8],10);
1068 }
1069 else
1070 memcpy (&buf[0], "COMM-BAT", 8);
1071
1072 US_MeasureStr (&width, &height, &buf[0]);
1073 VWB_TBar (PrintX-2, PrintY-2, width+4, height+4);
1074 US_BufPrint (&buf[0]);
1075
1076
1077 PrintY = PRECACHEASTRINGY;
1078
1079 memset (&buf[0], 0, sizeof (buf));
1080 memcpy (&buf[0], "AREA ", 5);
1081
1082 if ( !BATTLEMODE )
1083 {
1084 itoa( GetLevel( gamestate.episode, gamestate.mapon ),
1085 &buf[ 5 ], 10 );
1086 }
1087 else
1088 {
1089 itoa( gamestate.mapon + 1, &buf[ 5 ], 10 );
1090 }
1091 US_MeasureStr (&width, &height, &buf[0]);
1092 PrintX = (300-width);
1093 VWB_TBar (PrintX-2, PrintY-2, width+4, height+4);
1094 US_BufPrint (&buf[0]);
1095
1096
1097 PrintY = PRECACHESTRINGY;
1098
1099 num = (RandomNumber ("PreCacheString", 0)) % MAXSILLYSTRINGS;
1100
1101 if ((dopefish==true) || (tedlevel == true))
1102 strcpy (temp, &(CacheStrings[num][0]));
1103 else
1104 strcpy (temp, &(LevelName[0]));
1105
1106 US_MeasureStr (&width, &height, &temp[0]);
1107
1108 PrintX = (320-width) >> 1;
1109 PrintY = PRECACHESTRINGY;
1110 VWB_TBar (PrintX-2, PrintY-2, width+4, height+4);
1111
1112 US_BufPrint (&temp[0]);
1113
1114 VW_UpdateScreen();
1115
1116 MenuFadeIn ();
1117 }
1118 }
1119
1120 #define CACHETICDELAY (6)
1121 /*
1122 ======================
1123 =
1124 = PreCache
1125 = precache all the lumps for the level
1126 =
1127 ======================
1128 */
PreCache(void)1129 void PreCache( void )
1130 {
1131 int i;
1132 int total;
1133 byte * dummy;
1134 int maxheapsize;
1135 int newheap;
1136
1137 int currentmem;
1138 int currentcache;
1139 int lastmem=0;
1140 int lastcache=0;
1141 int ticdelay;
1142 unsigned tempbuf;
1143
1144 #if defined(PLATFORM_MACOSX)
1145 #warning "Precaching is disabled. Fix."
1146 // Precaching confuses the byteswapping code, since we have
1147 // no simple way of knowing the type of each resource.
1148 return;
1149 #endif
1150
1151 if (CachingStarted==false)
1152 {
1153 if (loadedgame==false)
1154 {
1155 ClearGraphicsScreen();
1156 MenuFadeIn ();
1157 }
1158 return;
1159 }
1160
1161 MiscPreCache();
1162
1163 SortPreCache();
1164
1165 if (loadedgame==false)
1166 {
1167 maxheapsize=Z_HeapSize();
1168 total=0;
1169
1170 tempbuf=bufferofs;
1171 bufferofs=displayofs;
1172 ticdelay=CACHETICDELAY;
1173 for (i=1;i<cacheindex;i++)
1174 {
1175 dummy=W_CacheLumpNum(cachelist[i].lump,cachelist[i].cachelevel, CvtFixme, 1);
1176 total+=W_LumpLength(cachelist[i].lump);
1177 newheap=Z_UsedHeap();
1178 currentmem=(newheap*MAXLEDS)/maxheapsize;
1179 while (lastmem<=currentmem)
1180 {
1181 DrawNormalSprite (PRECACHEBARX+PRECACHELED1X+(lastmem<<2),
1182 PRECACHEBARY+PRECACHELED1Y,
1183 W_GetNumForName ("led1"));
1184 lastmem++;
1185 }
1186 currentcache=(i*MAXLEDS)/(cacheindex+1);
1187 while (lastcache<=currentcache)
1188 {
1189 DrawNormalSprite (PRECACHEBARX+PRECACHELED2X+(lastcache<<2),
1190 PRECACHEBARY+PRECACHELED2Y,
1191 W_GetNumForName ("led2"));
1192 lastcache++;
1193 ticdelay--;
1194 if (ticdelay==0)
1195 {
1196 extern boolean dopefish;
1197
1198 if ( dopefish==true )
1199 {
1200 SD_PlayPitchedSound ( SD_DOPEFISHSND, 255, 0 );
1201 }
1202 ticdelay=CACHETICDELAY;
1203 }
1204 }
1205 }
1206 bufferofs=tempbuf;
1207 ShutdownPreCache ();
1208
1209 if ( BATTLEMODE )
1210 {
1211 int width,height;
1212 char buf[30];
1213
1214 CurrentFont = smallfont;
1215 strcpy( buf, "Press Any Key" );
1216 US_MeasureStr (&width, &height, &buf[ 0 ] );
1217 PrintX = (320-width) / 2;
1218 PrintY = 162;
1219 VWB_TBar (PrintX-2, PrintY-2, width+4, height+4);
1220 US_BufPrint (&buf[0]);
1221 VW_UpdateScreen();
1222
1223 IN_StartAck();
1224 while (!IN_CheckAck ())
1225 ;
1226 }
1227
1228 #if (DEVELOPMENT == 1)
1229 tempbuf=bufferofs;
1230 bufferofs=displayofs;
1231 CurrentFont = smallfont;
1232 US_CenterWindow(30,6);
1233 PrintY+=6;
1234 US_Print("Max Heap Size:");
1235 US_PrintUnsigned(maxheapsize);
1236 US_Print("\n");
1237 US_Print("Used Heap Size:");
1238 US_PrintUnsigned(newheap);
1239 US_Print("\n");
1240 US_Print("Percentage Used:");
1241 US_PrintUnsigned(newheap*100/maxheapsize);
1242 US_Print("\n");
1243 US_Print("TotalPrecached:");
1244 US_PrintUnsigned(total);
1245 bufferofs=tempbuf;
1246 I_Delay (40);
1247 #endif
1248 #if (PRECACHETEST == 1)
1249 SoftError("Max Heap Size: %ld\n",maxheapsize);
1250 SoftError("Used Heap Size: %ld\n",newheap);
1251 SoftError("TotalPrecached: %ld\n",total);
1252 #endif
1253 }
1254 else
1255 {
1256 for (i=1;i<cacheindex;i++)
1257 {
1258 dummy=W_CacheLumpNum(cachelist[i].lump,cachelist[i].cachelevel, CvtNull, 1);
1259 DoLoadGameAction ();
1260 }
1261 ShutdownPreCache ();
1262 }
1263 if (CheckParm("LEVELSIZE")!=0)
1264 {
1265 OpenMapDebug();
1266
1267 MapDebug("Map Number %ld\n",gamestate.mapon);
1268 MapDebug("sizeoflevel=%ld\n",Z_UsedLevelHeap());
1269 }
1270 #if (PRECACHETEST == 1)
1271 SoftError("<<<<<<<<<<<<<<<<<<<<<<<Precaching done\n");
1272 #endif
1273 }
1274
1275
1276
1277 /*
1278 ======================
1279 =
1280 = CA_RLEWexpand
1281 = length is EXPANDED length
1282 =
1283 ======================
1284 */
1285
CA_RLEWexpand(word * source,word * dest,long length,unsigned rlewtag)1286 void CA_RLEWexpand (word *source, word *dest,long length, unsigned rlewtag)
1287 {
1288 word value,count,i;
1289 word *end;
1290
1291 end = dest + length;
1292 //
1293 // expand it
1294 //
1295 do
1296 {
1297 value = IntelShort(*source++);
1298 if (value != rlewtag)
1299 //
1300 // uncompressed
1301 //
1302 *dest++=value;
1303 else
1304 {
1305 //
1306 // compressed string
1307 //
1308 count = IntelShort(*source++);
1309 value = IntelShort(*source++);
1310 for (i=1;i<=count;i++)
1311 *dest++ = value;
1312 }
1313 } while (dest<end);
1314 }
1315
1316 /*
1317 ======================
1318 =
1319 = CheckRTLVersion
1320 =
1321 ======================
1322 */
1323
CheckRTLVersion(char * filename)1324 void CheckRTLVersion
1325 (
1326 char *filename
1327 )
1328
1329 {
1330 int filehandle;
1331 char RTLSignature[ 4 ];
1332 unsigned long RTLVersion;
1333
1334 filehandle = SafeOpenRead( filename );
1335
1336 //
1337 // Load RTL signature
1338 //
1339 SafeRead( filehandle, RTLSignature, sizeof( RTLSignature ) );
1340
1341 if ( ( strcmp( RTLSignature, COMMBAT_SIGNATURE ) != 0 ) &&
1342 ( strcmp( RTLSignature, NORMAL_SIGNATURE ) != 0 ) )
1343 {
1344 Error( "The file '%s' is not a valid level file.", filename );
1345 }
1346
1347 //
1348 // Check the version number
1349 //
1350 SafeRead( filehandle, &RTLVersion, sizeof( RTLVersion ) );
1351 SwapIntelLong(&RTLVersion);
1352 if ( RTLVersion > RTL_VERSION )
1353 {
1354 Error(
1355 "The file '%s' is a version %d.%d %s file.\n"
1356 "The highest this version of ROTT can load is %d.%d.", filename,
1357 RTLVersion >> 8, RTLVersion & 0xff, RTLSignature,
1358 RTL_VERSION >> 8, RTL_VERSION & 0xff );
1359 }
1360
1361 close( filehandle );
1362 }
1363
1364
1365 /*
1366 ======================
1367 =
1368 = ReadROTTMap
1369 =
1370 ======================
1371 */
1372
ReadROTTMap(char * filename,int mapnum)1373 void ReadROTTMap
1374 (
1375 char *filename,
1376 int mapnum
1377 )
1378
1379 {
1380 RTLMAP RTLMap;
1381 int filehandle;
1382 long pos;
1383 long compressed;
1384 long expanded;
1385 int plane;
1386 byte *buffer;
1387
1388 CheckRTLVersion( filename );
1389 filehandle = SafeOpenRead( filename );
1390
1391 //
1392 // Load map header
1393 //
1394 lseek( filehandle, RTL_HEADER_OFFSET + mapnum * sizeof( RTLMap ),
1395 SEEK_SET );
1396 SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) );
1397
1398 SwapIntelLong((long *)&RTLMap.used);
1399 SwapIntelLong((long *)&RTLMap.CRC);
1400 SwapIntelLong((long *)&RTLMap.RLEWtag);
1401 SwapIntelLong((long *)&RTLMap.MapSpecials);
1402 SwapIntelLongArray((long *)&RTLMap.planestart, NUMPLANES);
1403 SwapIntelLongArray((long *)&RTLMap.planelength, NUMPLANES);
1404
1405 if ( !RTLMap.used )
1406 {
1407 Error( "ReadROTTMap: Tried to load a non existent map!" );
1408 }
1409
1410 #if ( SHAREWARE == 1 )
1411 if ( RTLMap.RLEWtag == REGISTERED_TAG )
1412 {
1413 Error( "Can't use maps from the registered game in shareware version." );
1414 }
1415
1416 if ( RTLMap.RLEWtag != SHAREWARE_TAG )
1417 {
1418 Error( "Can't use modified maps in shareware version." );
1419 }
1420 #endif
1421
1422 mapwidth = 128;
1423 mapheight = 128;
1424
1425 // Get special map flags
1426 MapSpecials = RTLMap.MapSpecials;
1427
1428 //
1429 // load the planes in
1430 //
1431 expanded = mapwidth * mapheight * 2;
1432
1433 for( plane = 0; plane <= 2; plane++ )
1434 {
1435 pos = RTLMap.planestart[ plane ];
1436 compressed = RTLMap.planelength[ plane ];
1437 buffer = SafeMalloc( compressed );
1438 lseek( filehandle, pos, SEEK_SET );
1439 SafeRead( filehandle, buffer, compressed );
1440
1441 mapplanes[ plane ] = Z_Malloc( expanded, PU_LEVEL, &mapplanes[ plane ] );
1442
1443 //
1444 // unRLEW, skipping expanded length
1445 //
1446 #if ( SHAREWARE == 1 )
1447 CA_RLEWexpand( ( word * )buffer, ( word * )mapplanes[ plane ],
1448 expanded >> 1, SHAREWARE_TAG );
1449 #else
1450 CA_RLEWexpand( ( word * )buffer, ( word * )mapplanes[ plane ],
1451 expanded >> 1, RTLMap.RLEWtag );
1452 #endif
1453
1454 SafeFree( buffer );
1455 }
1456 close(filehandle);
1457
1458 //
1459 // get map name
1460 //
1461 strcpy( LevelName, RTLMap.Name );
1462 }
1463
1464
1465
1466 /*
1467 ======================
1468 =
1469 = GetNextMap
1470 =
1471 ======================
1472 */
GetNextMap(int tilex,int tiley)1473 int GetNextMap ( int tilex, int tiley )
1474 {
1475 word next;
1476 word icon;
1477 boolean done;
1478
1479 next = MAPSPOT( tilex, tiley, 2 );
1480 icon = MAPSPOT( tilex, tiley, 1 );
1481 done=false;
1482 if ( ( ( icon != EXITTILE ) && ( icon != SECRETEXITTILE ) ) ||
1483 ( ( ( next&0xff00 ) != 0xe200 ) && ( ( next&0xff00 ) != 0xe400 ) ) )
1484 {
1485 int i,j;
1486
1487 for ( j = 0; j < mapheight; j++ )
1488 {
1489 for ( i = 0; i < mapwidth; i++ )
1490 {
1491 icon = MAPSPOT( i, j, 1 );
1492 next = MAPSPOT( i, j, 2 );
1493 if ( ( ( icon == EXITTILE ) || ( icon == SECRETEXITTILE ) ) &&
1494 ( ( ( next&0xff00 ) == 0xe200 ) ||
1495 ( ( next&0xff00 ) == 0xe400 ) ) )
1496 {
1497 done=true;
1498 break;
1499 }
1500 }
1501
1502 if ( done == true )
1503 {
1504 break;
1505 }
1506 }
1507
1508 if ( !done )
1509 {
1510 Error( "GetNextMap : No exit tile on map %d.", gamestate.mapon );
1511 }
1512 }
1513 if ( ( ( next & 0xff00 ) != 0xe200 ) &&
1514 ( ( next & 0xff00 ) != 0xe400 ) )
1515 {
1516 // Should this be DEVELOPMENT only?
1517 Error( "GetNextMap : Illegal destination map %xh at exit "
1518 "tile on map %d.", next, gamestate.mapon );
1519 }
1520
1521 if ( next == 0xe2ff )
1522 {
1523 return -1;
1524 }
1525
1526 return ( next & 0xff );
1527 }
1528
1529 /*
1530 ======================
1531 =
1532 = GetMapFileInfo
1533 =
1534 ======================
1535 */
GetMapFileInfo(mapfileinfo_t * mapinfo,char * filename)1536 void GetMapFileInfo
1537 (
1538 mapfileinfo_t *mapinfo,
1539 char *filename
1540 )
1541
1542 {
1543 RTLMAP RTLMap[ 100 ];
1544 int filehandle;
1545 int i;
1546 int nummaps;
1547
1548 CheckRTLVersion( filename );
1549
1550 filehandle = SafeOpenRead( filename );
1551
1552 //
1553 // Load map header
1554 //
1555 lseek( filehandle, RTL_HEADER_OFFSET, SEEK_SET );
1556 SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) );
1557 close( filehandle );
1558
1559 nummaps = 0;
1560 for( i = 0; i < 100; i++ )
1561 {
1562 if ( !RTLMap[ i ].used )
1563 {
1564 continue;
1565 }
1566
1567 mapinfo->maps[ nummaps ].number = i;
1568
1569 strcpy( mapinfo->maps[ nummaps ].mapname, RTLMap[ i ].Name );
1570
1571 nummaps++;
1572 }
1573
1574 mapinfo->nummaps = nummaps;
1575 }
1576
1577 /*
1578 ======================
1579 =
1580 = GetMapFileName
1581 =
1582 ======================
1583 */
GetMapFileName(char * filename)1584 void GetMapFileName ( char * filename )
1585 {
1586 if ( ( BATTLEMODE ) && (BattleLevels.avail == true) )
1587 {
1588 strcpy(filename,BattleLevels.file);
1589 }
1590 else if (GameLevels.avail == true)
1591 {
1592 strcpy(filename,GameLevels.file);
1593 }
1594 else if ( BATTLEMODE )
1595 {
1596 strcpy(filename,BATTMAPS);
1597 }
1598 else
1599 {
1600 strcpy(filename,ROTTMAPS);
1601 }
1602 }
1603
1604 /*
1605 ======================
1606 =
1607 = SetBattleMapFileName
1608 =
1609 ======================
1610 */
SetBattleMapFileName(char * filename)1611 void SetBattleMapFileName ( char * filename )
1612 {
1613 BattleLevels.avail = true;
1614 memset (&(BattleLevels.file[0]), 0, sizeof (BattleLevels.file));
1615 strcpy (&(BattleLevels.file[0]), filename);
1616 }
1617
1618 /*
1619 ======================
1620 =
1621 = GetMapCRC
1622 =
1623 ======================
1624 */
GetMapCRC(int num)1625 word GetMapCRC
1626 (
1627 int num
1628 )
1629
1630 {
1631 int filehandle;
1632 char filename[ 80 ];
1633 RTLMAP RTLMap;
1634
1635 GetMapFileName( &filename[ 0 ] );
1636 CheckRTLVersion( filename );
1637 filehandle = SafeOpenRead( filename );
1638
1639 //
1640 // Load map header
1641 //
1642 lseek( filehandle, RTL_HEADER_OFFSET + num * sizeof( RTLMap ), SEEK_SET );
1643 SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) );
1644
1645 close( filehandle );
1646
1647 return( RTLMap.CRC );
1648 }
1649
1650
1651 /*
1652 ======================
1653 =
1654 = GetAlternateMapInfo
1655 =
1656 ======================
1657 */
1658
GetAlternateMapInfo(mapfileinfo_t * mapinfo,AlternateInformation * info)1659 void GetAlternateMapInfo (mapfileinfo_t * mapinfo, AlternateInformation *info)
1660 {
1661 if (UL_ChangeDirectory (info->path) == false)
1662 Error ("ERROR : Can't change to alternate directory %s!\n");
1663
1664 GetMapFileInfo (mapinfo, info->file);
1665
1666 UL_ChangeDirectory (&CWD[0]);
1667 }
1668
1669 /*
1670 ======================
1671 =
1672 = GetMapInfo
1673 =
1674 ======================
1675 */
GetMapInfo(mapfileinfo_t * mapinfo)1676 void GetMapInfo
1677 (
1678 mapfileinfo_t *mapinfo
1679 )
1680
1681 {
1682 if ( ( BATTLEMODE ) && ( BattleLevels.avail == true ) )
1683 {
1684 GetAlternateMapInfo( mapinfo, &BattleLevels );
1685 }
1686 else if ( GameLevels.avail == true )
1687 {
1688 GetAlternateMapInfo( mapinfo, &GameLevels );
1689 }
1690 else if ( BATTLEMODE )
1691 {
1692 GetMapFileInfo( mapinfo, BATTMAPS );
1693 }
1694 else
1695 {
1696 GetMapFileInfo( mapinfo, ROTTMAPS );
1697 }
1698 }
1699
1700 /*
1701 ======================
1702 =
1703 = LoadTedMap
1704 =
1705 ======================
1706 */
LoadTedMap(const char * extension,int mapnum)1707 void LoadTedMap
1708 (
1709 const char *extension,
1710 int mapnum
1711 )
1712
1713 {
1714 long pos;
1715 long compressed;
1716 long expanded;
1717 int plane;
1718 int i;
1719 int maphandle;
1720 byte *buffer;
1721 maptype mapheader;
1722 char name[ 200 ];
1723 mapfiletype *tinf;
1724
1725 //
1726 // load maphead.ext (offsets and tileinfo for map file)
1727 //
1728 strcpy( name, "maphead." );
1729 strcat( name, extension );
1730 LoadFile( name, ( void * )&tinf );
1731
1732 // fix structure alignment
1733 tinf = ( void * )( ( word * )tinf - 1 );
1734
1735 for( i = 0 ; i < 100 ; i++ )
1736 {
1737 tinf->headeroffsets[ i ] = IntelLong( tinf->headeroffsets[ i ] );
1738 }
1739
1740 //
1741 // open the data file
1742 //
1743 strcpy( name, "maptemp." );
1744 strcat( name, extension );
1745 maphandle = SafeOpenRead( name );
1746
1747 //
1748 // load map header
1749 //
1750 pos = tinf->headeroffsets[ mapnum ];
1751
1752 // $FFFFFFFF start is a sparse map
1753 if ( pos < 0 )
1754 {
1755 Error( "LoadTedMap : Tried to load a non existent map!" );
1756 }
1757
1758 lseek( maphandle, pos, SEEK_SET );
1759 SafeRead( maphandle, &mapheader, sizeof( maptype ) );
1760
1761 for( i = 0 ; i < 3; i++ )
1762 {
1763 mapheader.planestart[ i ] = IntelLong( mapheader.planestart[ i ] );
1764 mapheader.planelength[ i ] = IntelShort( mapheader.planelength[ i ] );
1765 }
1766
1767 mapheader.width = IntelShort( mapheader.width );
1768 mapheader.height = IntelShort( mapheader.height );
1769
1770 mapwidth = mapheader.width;
1771 mapheight = mapheader.height;
1772
1773 // Set special map flags
1774 MapSpecials = 0;
1775
1776 //
1777 // load the planes in
1778 //
1779 expanded = mapheader.width * mapheader.height * 2;
1780
1781 for( plane = 0; plane <= 2; plane++ )
1782 {
1783 pos = mapheader.planestart[ plane ];
1784 lseek( maphandle, pos, SEEK_SET );
1785
1786 compressed = mapheader.planelength[ plane ];
1787 buffer = SafeMalloc( compressed );
1788 SafeRead( maphandle, buffer, compressed );
1789
1790 mapplanes[ plane ] = Z_Malloc( expanded, PU_LEVEL, &mapplanes[ plane ] );
1791
1792 //
1793 // unRLEW, skipping expanded length
1794 //
1795 CA_RLEWexpand( ( word * )( buffer + 2 ), ( word * )mapplanes[ plane ],
1796 expanded >> 1, 0xabcd );
1797
1798 SafeFree( buffer );
1799 }
1800
1801 // fix structure alignment
1802 tinf = ( void * )( ( word * )tinf + 1 );
1803
1804 SafeFree( tinf );
1805
1806 if ( close( maphandle ) )
1807 {
1808 Error( "Error closing Ted file Error #%ld", errno );
1809 }
1810 }
1811
1812
1813 /*
1814 ======================
1815 =
1816 = LoadAlternateMap
1817 =
1818 ======================
1819 */
1820
LoadAlternateMap(AlternateInformation * info,int mapnum)1821 void LoadAlternateMap (AlternateInformation *info, int mapnum)
1822 {
1823 if (UL_ChangeDirectory (info->path) == false)
1824 Error ("ERROR : Can't change to alternate directory %s!\n",info->path);
1825
1826 ReadROTTMap (info->file, mapnum);
1827
1828 UL_ChangeDirectory (&CWD[0]);
1829 }
1830
1831 /*
1832 ======================
1833 =
1834 = LoadROTTMap
1835 =
1836 ======================
1837 */
LoadROTTMap(int mapnum)1838 void LoadROTTMap
1839 (
1840 int mapnum
1841 )
1842
1843 {
1844 if ( tedlevel == true )
1845 {
1846 LoadTedMap( "rot", mapnum );
1847 }
1848 else if ( ( BATTLEMODE ) && ( BattleLevels.avail == true ) )
1849 {
1850 LoadAlternateMap( &BattleLevels, mapnum );
1851 }
1852 else if ( GameLevels.avail == true )
1853 {
1854 LoadAlternateMap( &GameLevels, mapnum );
1855 }
1856 else if ( BATTLEMODE )
1857 {
1858 ReadROTTMap( BATTMAPS, mapnum );
1859 }
1860 else
1861 {
1862 ReadROTTMap( ROTTMAPS, mapnum );
1863 }
1864 }
1865
1866
CountAreaTiles(void)1867 void CountAreaTiles(void)
1868 {int i,j,areanumber;
1869 word*map,tile;
1870
1871 memset(numareatiles,0,sizeof(numareatiles));
1872 map = mapplanes[0];
1873
1874 for(i=0;i<MAPSIZE;i++)
1875 for(j=0;j<MAPSIZE;j++)
1876 {tile = *map++;
1877
1878 areanumber = tile - AREATILE;
1879 if ((areanumber >= 0) && (areanumber <= NUMAREAS))
1880 numareatiles[areanumber] ++;
1881 }
1882
1883 }
1884
1885
1886
1887 #define InitWall(lump,index,newx,newy) \
1888 { \
1889 PreCacheLump(lump,PU_CACHEWALLS); \
1890 if (W_LumpLength(lump) == 0) \
1891 Error("%s being used in shareware at %ld %ld", \
1892 W_GetNameForNum(lump),newx,newy); \
1893 actorat[newx][newy]= &walls[index]; \
1894 tempwall = (wall_t*)actorat[newx][newy]; \
1895 tempwall->which = WALL; \
1896 tempwall->tile = index; \
1897 } \
1898
1899
1900 /*
1901 ==================
1902 =
1903 = SetupWalls
1904 =
1905 ==================
1906 */
SetupWalls(void)1907 void SetupWalls( void )
1908 {
1909 int i,j,lump,index;
1910 word *map,tile;
1911 wall_t * tempwall;
1912
1913
1914 for (i=0;i<MAXWALLTILES;i++)
1915 memset(&walls[i],0,sizeof(wall_t));
1916
1917 map = mapplanes[0];
1918 for (j=0;j<mapheight;j++)
1919 {
1920 for(i=0;i<mapwidth;i++)
1921 {
1922 if ((i>=0) && (i<=3) && (j==0))
1923 {
1924 map++;
1925 continue;
1926 }
1927 if ((loadedgame == false) && (MAPSPOT(i,j,2) == 0xeeee))
1928 {_2Dpoint *tdptr;
1929
1930 tdptr = &(MISCVARS->EPOP[MISCVARS->nextpop]);
1931 tdptr->x = i;
1932 tdptr->y = j;
1933 MISCVARS->nextpop ++;
1934 MISCVARS->popsleft ++;
1935 }
1936 tile= *map++;
1937
1938 if ((tile > 89) ||
1939 ((tile > 32) && (tile < 36)) ||
1940 (tile == 44) ||
1941 (tile == 45) ||
1942 (tile == 0)
1943 )
1944 {
1945 tilemap[i][j] = 0;
1946 continue;
1947 }
1948
1949 if (tile <= 32)
1950 {
1951 index = tile;
1952 #if 0
1953 if (tile==12)
1954 {
1955 if (MAPSPOT(i,j,2)==0)
1956 MAPSPOT(i,j,2)=21;
1957 }
1958 #endif
1959 }
1960 else
1961 index = tile-3;
1962
1963 if ((tile > 75) && (tile <= 79))
1964 {
1965 lump = tilemap[i][j] = GetLumpForTile(tile);
1966 PreCacheLump(lump,PU_CACHEWALLS);
1967 PreCacheLump(elevatorstart+5,PU_CACHEWALLS);
1968 PreCacheLump(elevatorstart+6,PU_CACHEWALLS);
1969 PreCacheLump(elevatorstart+7,PU_CACHEWALLS);
1970 tilemap[i][j]|=0x2000;
1971 if (MAPSPOT(i,j,2)==0)
1972 MAPSPOT(i,j,2)=21;
1973 }
1974 else if ((tile >= 47) && (tile <= 48))
1975 {
1976 lump = tilemap[i][j] = GetLumpForTile(tile);
1977 InitWall(lump,index,i,j);
1978 tilemap[i][j]|=0x2000;
1979 if (MAPSPOT(i,j,2)==0)
1980 MAPSPOT(i,j,2)=21;
1981 }
1982 else
1983 {
1984 lump = tilemap[i][j] = GetLumpForTile(tile);
1985 InitWall(lump,index,i,j);
1986 if (MAPSPOT(i,j,2))
1987 tilemap[i][j]|=0x2000;
1988 }
1989 }
1990 }
1991 }
1992
1993
1994 /*
1995 ===============
1996 =
1997 = GetNearestAreaNumber
1998 =
1999 ===============
2000 */
GetNearestAreaNumber(int tilex,int tiley)2001 word GetNearestAreaNumber ( int tilex, int tiley )
2002 {
2003 int up,dn,lt,rt;
2004 int tile;
2005
2006 tile=MAPSPOT(tilex,tiley,0)-AREATILE;
2007
2008 if ((tile<=NUMAREAS) && (tile>0))
2009 return (tile+AREATILE);
2010
2011 up=MAPSPOT(tilex,tiley-1,0)-AREATILE;
2012 dn=MAPSPOT(tilex,tiley+1,0)-AREATILE;
2013 lt=MAPSPOT(tilex-1,tiley,0)-AREATILE;
2014 rt=MAPSPOT(tilex+1,tiley,0)-AREATILE;
2015
2016 up = ((up>0) && (up<=NUMAREAS));
2017 dn = ((dn>0) && (dn<=NUMAREAS));
2018 lt = ((lt>0) && (lt<=NUMAREAS));
2019 rt = ((rt>0) && (rt<=NUMAREAS));
2020
2021 if (rt)
2022 return (MAPSPOT(tilex+1,tiley,0) + AREATILE);
2023 else if (lt)
2024 return (MAPSPOT(tilex-1,tiley,0) + AREATILE);
2025 else if (up)
2026 return (MAPSPOT(tilex,tiley-1,0) + AREATILE);
2027 else if (dn)
2028 return (MAPSPOT(tilex,tiley+1,0) + AREATILE);
2029 // else
2030 // Error("GetNearestAreaNumber: Couldn't fix up area at x=%ld y=%ld\n",tilex,tiley);
2031 return (NUMAREAS+AREATILE-1);
2032 }
2033
2034 /*
2035 ===============
2036 =
2037 = SetupWindows
2038 =
2039 ===============
2040 */
SetupWindows(void)2041 void SetupWindows ( void )
2042 {
2043 int i,j;
2044 boolean skythere;
2045
2046 skythere = SkyExists();
2047
2048 for (j=0;j<mapheight;j++)
2049 {
2050 for(i=0;i<mapwidth;i++)
2051 {
2052 if ((i>=0) && (i<=3) && (j==0))
2053 continue;
2054 if (IsWindow(i,j))
2055 {
2056 actorat[i][j]=0;
2057 if (skythere==true)
2058 {
2059 tilemap[i][j]|=0x2000;
2060 }
2061 else
2062 {
2063 MAPSPOT(i,j,2)=0;
2064 }
2065 MAPSPOT(i,j,0)=(word)(GetNearestAreaNumber(i,j));
2066 }
2067 }
2068 }
2069
2070 }
2071
2072
2073 /*
2074 ==================
2075 =
2076 = GetWallIndex
2077 =
2078 ==================
2079 */
2080
GetWallIndex(int texture)2081 int GetWallIndex( int texture )
2082 {
2083 int wallstart;
2084 int exitstart;
2085
2086 wallstart=W_GetNumForName("WALLSTRT");
2087 exitstart=W_GetNumForName("EXITSTRT");
2088 elevatorstart = W_GetNumForName("ELEVSTRT");
2089
2090 if (texture&0x1000)
2091 {
2092 texture&=~0x1000;
2093 if (texture==0)
2094 return 41;
2095 else if (texture==1)
2096 return 90;
2097 else if (texture==2)
2098 return 91;
2099 else if (texture==3)
2100 return 42;
2101 else if (texture==4)
2102 return 92;
2103 else if (texture==5)
2104 return 93;
2105 else if (texture==6)
2106 return 94;
2107 else if (texture==7)
2108 return 95;
2109 else if (texture==8)
2110 return 96;
2111 else if (texture==9)
2112 return 97;
2113 else if (texture==10)
2114 return 98;
2115 else if (texture==11)
2116 return 99;
2117 else if (texture==12)
2118 return 100;
2119 else if (texture==13)
2120 return 101;
2121 else if (texture==14)
2122 return 102;
2123 else if (texture==15)
2124 return 103;
2125 else if (texture==16)
2126 return 104;
2127 }
2128 else if (texture > elevatorstart)
2129 return (texture - elevatorstart + 68);
2130 // else if (texture > specialstart)
2131 // return (texture - specialstart + 41);
2132 else if (texture > exitstart)
2133 return (texture - exitstart + 43);
2134 else
2135 {
2136 if (texture>wallstart+63)
2137 return (texture - (wallstart + 63) + 76 );
2138 else if (texture>wallstart+40)
2139 return (texture - (wallstart + 40) + 45 );
2140 else
2141 return (texture - wallstart);
2142 }
2143 return 0x8000;
2144 }
2145
2146 /*
2147 ==================
2148 =
2149 = SetupAnimatedWalls
2150 =
2151 ==================
2152 */
SetupAnimatedWalls(void)2153 void SetupAnimatedWalls( void )
2154 {
2155 int i,j;
2156 word *map,tile;
2157 wall_t * tempwall;
2158
2159 InitAnimatedWallList();
2160 map = mapplanes[0];
2161 for (j=0;j<mapheight;j++)
2162 {
2163 for(i=0;i<mapwidth;i++)
2164 {
2165 if ((i>=0) && (i<=3) && (j==0))
2166 {
2167 map++;
2168 continue;
2169 }
2170 tile= *map++;
2171 if (tile == 44)
2172 {
2173 actorat[i][j]= &walls[tile-3];
2174 tempwall = (wall_t*)actorat[i][j];
2175 tempwall->which = WALL;
2176 tempwall->tile = tile-3;
2177 tempwall->flags = FL_W_DAMAGE;
2178 SetupAnimatedWall(0);
2179 tilemap[i][j]=0;
2180 tilemap[i][j]|=0x1000;
2181 }
2182 else if (tile == 45)
2183 {
2184 actorat[i][j]= &walls[tile-3];
2185 tempwall = (wall_t*)actorat[i][j];
2186 tempwall->which = WALL;
2187 tempwall->tile = tile-3;
2188 SetupAnimatedWall(3);
2189 tilemap[i][j]=3;
2190 tilemap[i][j]|=0x1000;
2191 }
2192 else if ((tile >= 106) && (tile <= 107))
2193 {
2194 actorat[i][j]= &walls[tile-16];
2195 tempwall = (wall_t*)actorat[i][j];
2196 tempwall->which = WALL;
2197 tempwall->tile = tile-16;
2198 SetupAnimatedWall(tile-105);
2199 tilemap[i][j]=tile-105;
2200 tilemap[i][j]|=0x1000;
2201 }
2202 else if ((tile >= 224) && (tile <= 233))
2203 {
2204 actorat[i][j]= &walls[tile-224+92];
2205 tempwall = (wall_t*)actorat[i][j];
2206 tempwall->which = WALL;
2207 tempwall->tile = tile-224+94;
2208 if (tile==233)
2209 tempwall->flags = FL_W_DAMAGE;
2210 SetupAnimatedWall(tile-224+4);
2211 tilemap[i][j]=tile-224+4;
2212 tilemap[i][j]|=0x1000;
2213 }
2214 else if ((tile >= 242) && (tile <= 244))
2215 {
2216 actorat[i][j]= &walls[tile-242+102];
2217 tempwall = (wall_t*)actorat[i][j];
2218 tempwall->which = WALL;
2219 tempwall->tile = tile-242+102;
2220 SetupAnimatedWall(tile-242+14);
2221 tilemap[i][j]=tile-242+14;
2222 tilemap[i][j]|=0x1000;
2223 }
2224 }
2225 }
2226 }
2227
2228
2229 /*
2230 ==================
2231 =
2232 = SetupSwitches
2233 =
2234 ==================
2235 */
2236
SetupSwitches(void)2237 void SetupSwitches( void )
2238 {
2239 int i,j;
2240 word *map,tile;
2241
2242 map = mapplanes[0];
2243 for (j=0;j<mapheight;j++)
2244 {
2245 for(i=0;i<mapwidth;i++)
2246 {
2247 if ((i>=0) && (i<=3) && (j==0))
2248 {
2249 map++;
2250 continue;
2251 }
2252 tile= *map++;
2253 if ((tile >= 76) && (tile <= 79))
2254 {
2255 if (tile == 79)
2256 lastswitch->flags |= FL_ON;
2257 SpawnSwitchThingy(i,j);
2258 }
2259 else if ((tile == 157) || (tile == 175)) // hi masked switches
2260 {
2261 lastswitch->flags |= FL_W_INVERTED;
2262 lastswitch->flags |= FL_REVERSIBLE;
2263 if (tile==175)
2264 lastswitch->flags |= FL_ON;
2265 SpawnSwitchThingy(i,j);
2266 }
2267 }
2268 }
2269 }
2270
2271
2272
RespawnPlayerobj(objtype * ob)2273 void RespawnPlayerobj(objtype *ob)
2274 {int rand,numchecked=0;
2275 int oldsetupgame,nx,ny,ndir;
2276 playertype *pstate;
2277
2278 M_LINKSTATE(ob,pstate);
2279
2280 if (gamestate.battlemode != battle_CaptureTheTriad)
2281 {
2282 rand = (GameRandomNumber("playerobj respawn",0) % NUMSPAWNLOCATIONS);
2283
2284 while(numchecked < NUMSPAWNLOCATIONS)
2285 {
2286 if (!actorat[SPAWNLOC[rand].x][SPAWNLOC[rand].y])
2287 {RevivePlayerobj(SPAWNLOC[rand].x,SPAWNLOC[rand].y,SPAWNLOC[rand].dir,ob);
2288 return;
2289 }
2290 numchecked ++;
2291 rand = (rand + 1) % NUMSPAWNLOCATIONS;
2292 }
2293 #if (DEVELOPMENT == 1)
2294 SoftError("\nno spawn locations available, using FindEmptyTile");
2295 #endif
2296 nx = SPAWNLOC[rand].x;
2297 ny = SPAWNLOC[rand].y;
2298 ndir = SPAWNLOC[rand].dir;
2299 }
2300 else
2301 {nx = TEAM[pstate->team].tilex;
2302 ny = TEAM[pstate->team].tiley;
2303 ndir = TEAM[pstate->team].dir;
2304 }
2305
2306 oldsetupgame = insetupgame;
2307 insetupgame = true;
2308 FindEmptyTile(&nx,&ny);
2309 insetupgame = oldsetupgame;
2310 RevivePlayerobj(nx,ny,ndir,ob);
2311
2312
2313 }
2314
2315 #define SetupSpecificFlagTeamAt(whichteam, spawnlocindex) \
2316 {int newx,newy; \
2317 \
2318 newx = SPAWNLOC[spawnlocindex].x; \
2319 newy = SPAWNLOC[spawnlocindex].y; \
2320 TEAM[whichteam].tilex = newx; \
2321 TEAM[whichteam].tiley = newy; \
2322 TEAM[whichteam].dir = SPAWNLOC[spawnlocindex].x; \
2323 SpawnStatic(newx,newy,stat_collector,9); \
2324 SpawnNewObj(newx,newy,&s_basemarker1,inertobj); \
2325 LASTACTOR->z = LASTSTAT->z; \
2326 LASTSTAT->flags |= FL_COLORED; \
2327 LASTSTAT->hitpoints = whichteam; \
2328 locspawned[spawnlocindex]=1; \
2329 for(j=0;j<numplayers;j++) \
2330 {if (PLAYERSTATE[j].uniformcolor != \
2331 TEAM[whichteam].uniformcolor) \
2332 continue; \
2333 \
2334 ntilex = newx; \
2335 ntiley = newy; \
2336 FindEmptyTile(&ntilex,&ntiley); \
2337 SpawnPlayerobj(ntilex,ntiley,dir,j); \
2338 } \
2339 } \
2340
2341
2342 /*
2343 =============
2344 =
2345 = AssignTeams called from SetGameDescription in rt_net.c
2346 =
2347 =============
2348 */
2349
AssignTeams(void)2350 void AssignTeams(void)
2351 {int i,color;
2352 int teamforcolor[MAXPLAYERCOLORS];
2353
2354 numteams = 0;
2355 if (!gamestate.teamplay)
2356 return;
2357
2358 memset(teamforcolor,-1,sizeof(teamforcolor));
2359 memset(TEAM,0,sizeof(TEAM));
2360
2361 for(i=0;i<numplayers;i++)
2362 {color = PLAYERSTATE[i].uniformcolor;
2363 if (teamforcolor[color] == -1)
2364 {TEAM[numteams].uniformcolor = color;
2365
2366 TEAM[numteams].nummembers ++;
2367 teamforcolor[color] = numteams;
2368 numteams++;
2369 if ((gamestate.battlemode == battle_CaptureTheTriad) &&
2370 (numteams > 2))
2371 Error("players selected more colors(%d) than Capture the Triad allows",numteams);
2372 }
2373 else
2374 TEAM[teamforcolor[color]].nummembers ++;
2375
2376 PLAYERSTATE[i].team = teamforcolor[color];
2377
2378 }
2379
2380 }
2381
2382
2383
2384 /*
2385 =============
2386 =
2387 = SetupTeams
2388 =
2389 =============
2390 */
2391
2392
SetupTeams(void)2393 void SetupTeams(void)
2394 {
2395
2396 int i,j,rand,sx,sy,ntilex,ntiley,dir,
2397 maxdist,currdist,spawnindex,cnt;
2398 int locspawned[MAXSPAWNLOCATIONS] = {0};
2399
2400 if (gamestate.battlemode == battle_CaptureTheTriad)
2401 {rand = (GameRandomNumber("net player spawn",0) % NUMSPAWNLOCATIONS);
2402
2403 for(i=0;i<NUMSPAWNLOCATIONS;i++)
2404 {sx = SPAWNLOC[rand].x;
2405 sy = SPAWNLOC[rand].y;
2406 dir = SPAWNLOC[rand].dir;
2407
2408 if (CheckTile(sx,sy) && (!IsPlatform(sx,sy)) &&
2409 (Number_of_Empty_Tiles_In_Area_Around(sx,sy) > TEAM[0].nummembers)
2410 )
2411 {SetupSpecificFlagTeamAt(0,rand);
2412 break;
2413 }
2414
2415 rand = (rand + 1)%NUMSPAWNLOCATIONS;
2416 }
2417
2418 if (i == NUMSPAWNLOCATIONS)
2419 Error("No spawn location available for team 0, capture the flag");
2420
2421 maxdist = 0x80000000;
2422 for(i=0;i<NUMSPAWNLOCATIONS;i++)
2423 {if (locspawned[i])
2424 continue;
2425
2426 sx = SPAWNLOC[i].x;
2427 sy = SPAWNLOC[i].y;
2428 dir = SPAWNLOC[i].dir;
2429
2430 if ((Number_of_Empty_Tiles_In_Area_Around(sx,sy) < TEAM[1].nummembers)
2431 || (!CheckTile(sx,sy) || IsPlatform(sx,sy))
2432 )
2433 continue;
2434
2435 currdist = FindDistance(sx-TEAM[0].tilex,sy-TEAM[0].tiley);
2436 if (currdist > maxdist)
2437 {maxdist = currdist;
2438 spawnindex = i;
2439 }
2440 }
2441
2442 SetupSpecificFlagTeamAt(1,spawnindex);
2443 }
2444 else
2445 {
2446 int badcount = 0,teamindex;
2447
2448 if (numteams > NUMSPAWNLOCATIONS)
2449 Error("More teams than spawn locations !");
2450 //cnt =0;
2451 //for(rand = 0;rand < NUMSPAWNLOCATIONS;rand++)
2452 for(cnt=0;cnt<numteams;)
2453 {
2454 rand = (GameRandomNumber("team spawn",0) % NUMSPAWNLOCATIONS);
2455
2456 if (locspawned[rand])
2457 continue;
2458
2459
2460 sx = SPAWNLOC[rand].x;
2461 sy = SPAWNLOC[rand].y;
2462 dir = SPAWNLOC[rand].dir;
2463
2464 if (Number_of_Empty_Tiles_In_Area_Around(sx,sy) < TEAM[cnt].nummembers)
2465 {
2466 badcount ++;
2467 if (badcount == (NUMSPAWNLOCATIONS - cnt))
2468 Error("\n%s team cannot spawn in this level",colorname[TEAM[cnt].uniformcolor]);
2469 continue;
2470 }
2471
2472 badcount = 0;
2473 //Debug("\n\nSpawn Location %d",rand);
2474 //Debug("\n-----------------");
2475 TEAM[cnt].tilex = sx;
2476 TEAM[cnt].tiley = sy;
2477 TEAM[cnt].dir = dir;
2478 locspawned[rand]=1;
2479 cnt++;
2480
2481 }
2482
2483 for(j=0;j<numplayers;j++)
2484 {
2485 teamindex = PLAYERSTATE[j].team;
2486
2487 sx = TEAM[teamindex].tilex;
2488 sy = TEAM[teamindex].tiley;
2489 dir = TEAM[teamindex].dir;
2490
2491 FindEmptyTile(&sx,&sy);
2492
2493 //Debug("\n x: %3d, y: %3d",sx,sy);
2494 SpawnPlayerobj(sx,sy,dir,j);
2495 }
2496
2497
2498 }
2499
2500
2501
2502
2503 //numplayers = 1;
2504 //Error("Okay");
2505 #if ((DEVELOPMENT == 1))
2506 #if (TEAMTEST == 1)
2507
2508 Debug("Team Spawn Location\n");
2509 Debug("-------------------\n");
2510 for(i=0;i<numteams;i++)
2511 Debug("%d %3d,%3d\n",i,TEAM[i].tilex,TEAM[i].tiley);
2512
2513
2514 Debug("Player Team Location\n");
2515 Debug("------ ---- --------\n");
2516 for(i=0;i<numplayers;i++)
2517 Debug(" %d %d %3d,%3d\n",i,PLAYERSTATE[i].team,PLAYER[i]->tilex,PLAYER[i]->tiley);
2518
2519 // Error("done");
2520 #endif
2521 #endif
2522
2523 }
2524
2525
2526 /*
2527 ==================
2528 =
2529 = SetupPlayers
2530 =
2531 ==================
2532 */
2533
SetupPlayers(void)2534 void SetupPlayers( void )
2535 {
2536 int i,j;
2537 word *map,tile;
2538
2539 //START in icon plane = 10
2540
2541 map = mapplanes[1];
2542 for(j=0;j<mapheight;j++)
2543 for(i=0;i<mapwidth;i++)
2544 {
2545 tile = *map++;
2546 switch (tile)
2547 {
2548 case 19:
2549 case 20:
2550 case 21:
2551 case 22:
2552 FIRST.x = i;
2553 FIRST.y = j;
2554 FIRST.dir = tile-19;
2555 SPAWNLOC[NUMSPAWNLOCATIONS].x = i;
2556 SPAWNLOC[NUMSPAWNLOCATIONS].y = j;
2557 SPAWNLOC[NUMSPAWNLOCATIONS].dir = tile-19;
2558 if (NUMSPAWNLOCATIONS<MAXSPAWNLOCATIONS)
2559 NUMSPAWNLOCATIONS ++;
2560 break;
2561
2562 case 274:
2563 case 275:
2564 case 276:
2565 case 277:
2566 SPAWNLOC[NUMSPAWNLOCATIONS].x = i;
2567 SPAWNLOC[NUMSPAWNLOCATIONS].y = j;
2568 SPAWNLOC[NUMSPAWNLOCATIONS].dir = tile-274;
2569 if (NUMSPAWNLOCATIONS<MAXSPAWNLOCATIONS)
2570 NUMSPAWNLOCATIONS ++;
2571 break;
2572 }
2573
2574 }
2575
2576 if ( NUMSPAWNLOCATIONS <= 0 )
2577 {
2578 Error( "No spawn locations found on map." );
2579 }
2580
2581 /*modemgame=true;
2582 gamestate.teamplay = true;
2583 PLAYERSTATE[0].uniformcolor = 2;
2584 PLAYERSTATE[1].uniformcolor = 2;
2585 numplayers = 2;
2586 AssignTeams();*/
2587
2588 if (!BATTLEMODE)
2589 {
2590 if (tedlevel)
2591 {
2592 if ((tedx==0) || (tedy == 0))
2593 SpawnPlayerobj (FIRST.x, FIRST.y, FIRST.dir,0);
2594 else
2595 SpawnPlayerobj(tedx,tedy,FIRST.dir,0);
2596 }
2597 else
2598 SpawnPlayerobj(FIRST.x,FIRST.y,FIRST.dir,0);
2599 }
2600
2601 else if (gamestate.teamplay == true)
2602 SetupTeams();
2603
2604 else
2605 {
2606 int rand,cnt,locspawned[MAXSPAWNLOCATIONS]={0};
2607 int locsleft;
2608
2609 locsleft=NUMSPAWNLOCATIONS;
2610 for(cnt=0;cnt<numplayers;)
2611 {rand = (GameRandomNumber("net player spawn",0) % NUMSPAWNLOCATIONS);
2612 if (locsleft==0)
2613 {
2614 int x,y;
2615
2616 x=SPAWNLOC[rand].x;
2617 y=SPAWNLOC[rand].y;
2618 FindEmptyTile(&x,&y);
2619 SpawnPlayerobj(x,y,SPAWNLOC[rand].dir,cnt);
2620 cnt++;
2621 }
2622 else if (!locspawned[rand])
2623 {SpawnPlayerobj(SPAWNLOC[rand].x,SPAWNLOC[rand].y,SPAWNLOC[rand].dir,cnt);
2624 locspawned[rand]=1;
2625 locsleft--;
2626 cnt++;
2627 }
2628 }
2629 }
2630
2631 if (gamestate.battlemode == battle_Tag)
2632 {int i;
2633 playertype *pstate;
2634
2635 BATTLE_It = GameRandomNumber("tag choose",0) % numplayers;
2636
2637 PLAYER[BATTLE_It]->flags |= FL_DESIGNATED;
2638 for(i=0;i<numplayers;i++)
2639 {M_LINKSTATE(PLAYER[i],pstate);
2640
2641 if (i == BATTLE_It)
2642 {pstate->missileweapon = pstate->oldweapon = pstate->new_weapon =
2643 pstate->oldmissileweapon = pstate->weapon = wp_godhand;
2644 pstate->bulletweapon = -1;
2645 }
2646 else
2647 {pstate->missileweapon = pstate->oldweapon = pstate->new_weapon =
2648 pstate->oldmissileweapon = pstate->bulletweapon = pstate->weapon = -1;
2649 }
2650 }
2651 }
2652
2653 PreCachePlayers();
2654 }
2655
2656
2657
2658 /*
2659 ==================
2660 =
2661 = SetupMaskedWalls
2662 =
2663 ==================
2664 */
2665
SetupMaskedWalls(void)2666 void SetupMaskedWalls( void )
2667 {
2668 int i,j;
2669 word *map,tile;
2670
2671 map = mapplanes[0];
2672 for (j=0;j<mapheight;j++)
2673 {
2674 for(i=0;i<mapwidth;i++)
2675 {
2676 tile = *map++;
2677 if ((tile >= 158) && (tile <= 160)) // Multi glassed walls
2678 {
2679 SpawnMaskedWall(i,j,mw_multi1+(tile-158),MW_MULTI|MW_BLOCKING|MW_BLOCKINGCHANGES|MW_SHOOTABLE);
2680 }
2681 else if ((tile >= 176) && (tile <= 178)) // Multi shot out glassed walls
2682 {
2683 SpawnMaskedWall(i,j,mw_multi1+(tile-176),MW_BOTTOMPASSABLE);
2684 }
2685 else if ((tile >= 162) && (tile <= 171))
2686 {
2687 switch (tile)
2688 {
2689 case 162:
2690 SpawnMaskedWall(i,j,mw_normal1,MW_SHOOTABLE|MW_BLOCKING);
2691 break;
2692 case 163:
2693 SpawnMaskedWall(i,j,mw_normal1,MW_BLOCKING);
2694 break;
2695 case 164:
2696 SpawnMaskedWall(i,j,mw_normal2,MW_SHOOTABLE|MW_BLOCKING);
2697 break;
2698 case 165:
2699 SpawnMaskedWall(i,j,mw_normal2,MW_BLOCKING);
2700 break;
2701 case 166:
2702 SpawnMaskedWall(i,j,mw_normal3,MW_SHOOTABLE|MW_BLOCKING);
2703 break;
2704 case 167:
2705 SpawnMaskedWall(i,j,mw_normal3,MW_BLOCKING);
2706 break;
2707 case 168:
2708 SpawnMaskedWall(i,j,mw_singlepane,MW_SHOOTABLE|MW_BLOCKINGCHANGES|MW_BLOCKING);
2709 break;
2710 case 169:
2711 SpawnMaskedWall(i,j,mw_singlepane,MW_BOTTOMPASSABLE);
2712 break;
2713 case 170:
2714 SpawnMaskedWall(i,j,mw_dogwall,MW_NONDOGBLOCKING|MW_WEAPONBLOCKING);
2715 break;
2716 case 171:
2717 SpawnMaskedWall(i,j,mw_peephole,MW_WEAPONBLOCKING|MW_BLOCKING);
2718 break;
2719 }
2720 }
2721 else if (tile == 172)
2722 SpawnMaskedWall(i,j,mw_exitarch,MW_BOTTOMPASSABLE);
2723 else if (tile == 173)
2724 SpawnMaskedWall(i,j,mw_secretexitarch,MW_BOTTOMPASSABLE);
2725 else if (tile == 174) // entry gate
2726 SpawnMaskedWall(i,j,mw_entrygate,MW_BLOCKING);
2727 else if (tile == 157) // hi switch off
2728 SpawnMaskedWall(i,j,mw_hiswitchoff,MW_BLOCKING);
2729 else if (tile == 175) // hi switch on
2730 SpawnMaskedWall(i,j,mw_hiswitchon,MW_BLOCKING|MW_SWITCHON);
2731 else if (tile == 179) // railing;
2732 SpawnMaskedWall(i,j,mw_railing,MW_ABOVEPASSABLE|MW_MIDDLEPASSABLE);
2733 // else if (tile == 161) // pillar
2734 // SpawnMaskedWall(i,j,mw_pillar,MW_BLOCKING);
2735 }
2736 }
2737 for (j=0;j<mapheight;j++)
2738 for(i=0;i<mapwidth;i++)
2739 {
2740 if (IsPlatform(i,j)) // tall platform in icon plane
2741 {
2742 if ((MAPSPOT(i,j,0)-AREATILE>=0) || (MAPSPOT(i,j,0)==21))
2743 // check to see we are not on a wall
2744 {
2745 int which;
2746
2747 which=MAPSPOT(i,j,2)-4;
2748 switch (which)
2749 {
2750 case 0:
2751 SpawnMaskedWall(i,j,mw_platform1,MW_BOTTOMPASSABLE|MW_MIDDLEPASSABLE);
2752 break;
2753 case 1:
2754 SpawnMaskedWall(i,j,mw_platform2,MW_ABOVEPASSABLE|MW_MIDDLEPASSABLE);
2755 break;
2756 case 2:
2757 SpawnMaskedWall(i,j,mw_platform3,MW_MIDDLEPASSABLE);
2758 break;
2759 case 3:
2760 SpawnMaskedWall(i,j,mw_platform4,MW_BOTTOMPASSABLE);
2761 break;
2762 case 4:
2763 SpawnMaskedWall(i,j,mw_platform5,MW_BOTTOMPASSABLE|MW_ABOVEPASSABLE);
2764 break;
2765 case 5:
2766 SpawnMaskedWall(i,j,mw_platform6,MW_ABOVEPASSABLE);
2767 break;
2768 case -3:
2769 SpawnMaskedWall(i,j,mw_platform7,MW_ABOVEPASSABLE);
2770 break;
2771 default:
2772 Error ("Illegal Maskedwall platform value at x=%ld y=%ld\n",i,j);
2773 break;
2774 }
2775 #if 0
2776 if (IsPlatform(i+1,j))
2777 {
2778 if ( (IsPlatform(i,j+1)) || (IsPlatform(i,j-1)) )
2779 SpawnStatic(i,j,83,MAPSPOT(i,j,2));
2780 }
2781 else if (IsPlatform(i-1,j))
2782 {
2783 if ( (IsPlatform(i,j+1)) || (IsPlatform(i,j-1)) )
2784 SpawnStatic(i,j,83,MAPSPOT(i,j,2));
2785 }
2786 #endif
2787 }
2788 else
2789 Error("You have what appears to be a platform ontop\n a wall at x=%ld y=%ld\n",i,j);
2790 }
2791 }
2792 }
2793
2794 /*
2795 int GetAreaNumber ( int tilex, int tiley, int dir );
2796 void RemoveDangerWalls
2797 (
2798 void
2799 )
2800
2801 {
2802 int i;
2803 int j;
2804 word *map;
2805 word tile;
2806
2807 map = mapplanes[ 1 ];
2808
2809 for( j = 0; j < mapheight; j++ )
2810 {
2811 for( i = 0; i < mapwidth; i++ )
2812 {
2813 tile = *map++;
2814 switch( tile )
2815 {
2816 case 256:
2817 case 257:
2818 case 258:
2819 case 259:
2820 if ( MAPSPOT( i, j, 2 ) == 0 )
2821 {
2822 MAPSPOT( i, j, 0 ) = ( word )( GetAreaNumber( i, j,
2823 ( tile - 256 ) << 1 ) + AREATILE );
2824 MAPSPOT( i, j, 1 ) = 0;
2825 }
2826 break;
2827
2828 case 300:
2829 case 318:
2830 case 336:
2831 case 354:
2832 if ( MAPSPOT( i, j, 2 ) == 0 )
2833 {
2834 MAPSPOT( i, j, 0 ) = ( word )( GetAreaNumber( i, j,
2835 ( ( tile - 300 ) / 9 ) + AREATILE ) );
2836 MAPSPOT( i, j, 1 ) = 0;
2837 }
2838 break;
2839 }
2840 }
2841 }
2842 }
2843 */
2844
2845
2846 /*
2847 ==================
2848 =
2849 = SetupPushWalls
2850 =
2851 ==================
2852 */
2853
SetupPushWalls(void)2854 void SetupPushWalls( void )
2855 {
2856 int i,j;
2857 word *map,tile;
2858 int temp;
2859
2860 map = mapplanes[1];
2861 for(j=0;j<mapheight;j++)
2862 {
2863 for(i=0;i<mapwidth;i++)
2864 {
2865 tile = *map++;
2866 switch(tile)
2867 {
2868 case 72:
2869 case 73:
2870 case 74:
2871 case 75:
2872 case 76:
2873 case 77:
2874 case 78:
2875 case 79:
2876 if (tilemap[i][j] && ActorIsWall(i,j))
2877 {
2878 temp=tilemap[i][j]&0x1fff;
2879 tilemap[i][j] = pwallnum;
2880 if (MAPSPOT(i,j,2))
2881 SpawnPushWall(i,j,1,temp,tile-72,0);
2882 else
2883 SpawnPushWall(i,j,0,temp,tile-72,0);
2884 }
2885 break;
2886
2887 case 80: //OldPushWall
2888 if (tilemap[i][j])
2889 {
2890 temp=tilemap[i][j]&0x1fff;
2891 tilemap[i][j] = pwallnum;
2892 if (MAPSPOT(i,j,2))
2893 Error("You cannot link a pushwall which has no direction associated\n with it at x=%ld y=%ld\n",i,j);
2894 else
2895 SpawnPushWall(i,j,0,temp,nodir,0);
2896 }
2897 break;
2898
2899
2900 case 256:
2901 case 257:
2902 case 258:
2903 case 259:
2904 if (tilemap[i][j])
2905 {
2906 temp=tilemap[i][j]&0x1fff;
2907 tilemap[i][j] = pwallnum;
2908 if (MAPSPOT(i,j,2))
2909 SpawnPushWall(i,j,0,temp,(tile-256)<<1,2);
2910 else
2911 SpawnPushWall(i,j,0,temp,(tile-256)<<1,4);
2912 }
2913 else
2914 Error("You have to place a turbomovewall icon on a wall at x=%d y=%d",i,j);
2915 break;
2916
2917 case 300:
2918 case 318:
2919 case 336:
2920 case 354:
2921 if (tilemap[i][j])
2922 {
2923 temp=tilemap[i][j]&0x1fff;
2924 tilemap[i][j] = pwallnum;
2925 if (MAPSPOT(i,j,2))
2926 SpawnPushWall(i,j,0,temp,(tile-300)/9,1);
2927 else
2928 SpawnPushWall(i,j,0,temp,(tile-300)/9,3);
2929 }
2930 else
2931 Error("You have to place a movewall icon on a wall at x=%d y=%d",i,j);
2932 break;
2933 }
2934 }
2935 }
2936 }
2937
2938
2939 /*
2940 ==================
2941 =
2942 = GetPushWallNumber
2943 =
2944 ==================
2945 */
2946
GetPushWallNumber(int tx,int ty)2947 int GetPushWallNumber( int tx, int ty )
2948 {
2949 int i;
2950
2951 for (i=0;i<pwallnum;i++)
2952 if ( (pwallobjlist[i]->tilex==tx) && (pwallobjlist[i]->tiley==ty))
2953 return i;
2954 Error ("Could not find a push wall at x=%ld y=%ld\n",tx,ty);
2955 return -1;
2956 }
2957
2958
2959 /*
2960 ==================
2961 =
2962 = SetupPushWallLinks
2963 =
2964 ==================
2965 */
SetupPushWallLinks(void)2966 void SetupPushWallLinks( void )
2967 {
2968 int i,j;
2969 word *map,tile;
2970 word touchx,touchy;
2971
2972 map = mapplanes[1];
2973 for(j=0;j<mapheight;j++)
2974 {
2975 for(i=0;i<mapwidth;i++)
2976 {
2977 tile = *map++;
2978 switch(tile)
2979 {
2980 case 72:
2981 case 73:
2982 case 74:
2983 case 75:
2984 case 76:
2985 case 77:
2986 case 78:
2987 case 79:
2988 if (ActorIsPushWall(i,j))
2989 {
2990 if (MAPSPOT(i,j,2))
2991 {
2992 touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff);
2993 touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff);
2994 if (touchindices[touchx][touchy])
2995 {
2996 if (MAPSPOT(i,j+1,2)!=0)
2997 {
2998 #if (DEVELOPMENT == 1)
2999 SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j);
3000 #endif
3001 }
3002 Link_To_Touchplate(touchx,touchy,ActivatePushWall,NULL,GetPushWallNumber(i,j),0);
3003 }
3004 else
3005 Error("tried to link a pushwall at x=%ld y=%ld to a non-existent touchplate\n",i,j);
3006 }
3007 }
3008 break;
3009
3010 case 80:
3011 if (ActorIsPushWall(i,j))
3012 {
3013 if (MAPSPOT(i,j,2))
3014 {
3015 Error("You shouldn't be linking a nondirectional-push wall at x=%ld y=%ld\n",i,j);
3016 }
3017 }
3018 break;
3019 case 256:
3020 case 257:
3021 case 258:
3022 case 259:
3023 if (ActorIsPushWall(i,j))
3024 {
3025 if (MAPSPOT(i,j,2))
3026 {
3027 touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff);
3028 touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff);
3029 if (touchindices[touchx][touchy])
3030 {
3031 if (MAPSPOT(i,j+1,2)!=0)
3032 {
3033 #if (DEVELOPMENT == 1)
3034 SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j);
3035 #endif
3036 }
3037 Link_To_Touchplate(touchx,touchy,ActivateMoveWall,NULL,GetPushWallNumber(i,j),0);
3038 }
3039 else
3040 Error("tried to link a turbomovewall at x=%ld y=%ld to a non-existent touchplate\n",i,j);
3041 }
3042 }
3043 break;
3044
3045 case 300:
3046 case 318:
3047 case 336:
3048 case 354:
3049 if (ActorIsPushWall(i,j))
3050 {
3051 if (MAPSPOT(i,j,2))
3052 {
3053 touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff);
3054 touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff);
3055 if (touchindices[touchx][touchy])
3056 {
3057 if (MAPSPOT(i,j+1,2)!=0)
3058 {
3059 #if (DEVELOPMENT == 1)
3060 SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j);
3061 #endif
3062 }
3063 Link_To_Touchplate(touchx,touchy,ActivateMoveWall,NULL,GetPushWallNumber(i,j),0);
3064 }
3065 else
3066 Error("tried to link a movewall at x=%ld y=%ld to a non-existent touchplate\n",i,j);
3067 }
3068 }
3069 break;
3070 }
3071 }
3072 }
3073 }
3074
3075 /*
3076 =================
3077 =
3078 = SetupElevators
3079 =
3080 =================
3081 */
3082
SetupElevators(void)3083 void SetupElevators (void)
3084 {
3085 int j, i,x,y,starti;
3086 word *map;
3087 word tile;
3088 elevator_t *elev;
3089 doorobj_t* dptr;
3090
3091 map = mapplanes[1];
3092 map += 4 ;
3093
3094 for (j = 0; j < mapheight; j++)
3095 {
3096 if (j == 0)
3097 starti = 4;
3098 else
3099 starti = 0;
3100
3101 for (i = starti; i < mapwidth; i++)
3102 {tile = *map++;
3103
3104 if ((tile > 89) && (tile < 98))
3105 {elev = &ELEVATOR[tile-90];
3106 if (!elev->sx)
3107 {elev->sx = i;
3108 elev->sy = j;
3109 elev->doortoopen = -1;
3110 elev->doorclosing = -1;
3111 elev->nextaction = -1;
3112 _numelevators ++;
3113 }
3114 else
3115 {elev->dx = i;
3116 elev->dy = j;
3117 }
3118 }
3119 }
3120 }
3121
3122 if (_numelevators && (!ELEVATOR[0].sx))
3123 Error("Elevators must start at 1, dumb ass.");
3124
3125 for(i=0;i<_numelevators;i++)
3126 {elev = &ELEVATOR[i];
3127 x = elev->sx;
3128 y = elev->sy;
3129 for(j=0;j<doornum;j++)
3130 {dptr = doorobjlist[j];
3131 if (((dptr->tilex == (x+1)) && (dptr->tiley == y)) ||
3132 ((dptr->tilex == (x-1)) && (dptr->tiley == y)) ||
3133 ((dptr->tilex == x) && (dptr->tiley == (y+1))) ||
3134 ((dptr->tilex == x) && (dptr->tiley == (y-1))))
3135 {elev->door1 = j;
3136 dptr->eindex = i;
3137 if ((dptr->tilex == (x+1)) && (dptr->tiley == y))
3138 {elev->esx = x-1;
3139 elev->esy = y;
3140 }
3141 else if ((dptr->tilex == (x-1)) && (dptr->tiley == y))
3142 {elev->esx = x+1;
3143 elev->esy = y;
3144 }
3145 else if ((dptr->tilex == x) && (dptr->tiley == (y+1)))
3146 {elev->esx = x;
3147 elev->esy = y-1;
3148 }
3149 else if ((dptr->tilex == x) && (dptr->tiley == (y-1)))
3150 {elev->esx = x;
3151 elev->esy = y+1;
3152 }
3153 break;
3154 }
3155 }
3156
3157 x = elev->dx;
3158 y = elev->dy;
3159 for(j=0;j<doornum;j++)
3160 {dptr = doorobjlist[j];
3161 if (((dptr->tilex == (x+1)) && (dptr->tiley == y)) ||
3162 ((dptr->tilex == (x-1)) && (dptr->tiley == y)) ||
3163 ((dptr->tilex == x) && (dptr->tiley == (y+1))) ||
3164 ((dptr->tilex == x) && (dptr->tiley == (y-1))))
3165 {elev->door2 = j;
3166 dptr->eindex = i;
3167 dptr->flags |= DF_ELEVLOCKED;
3168 if ((dptr->tilex == (x+1)) && (dptr->tiley == y))
3169 {elev->edx = x-1;
3170 elev->edy = y;
3171 }
3172 else if ((dptr->tilex == (x-1)) && (dptr->tiley == y))
3173 {elev->edx = x+1;
3174 elev->edy = y;
3175 }
3176 else if ((dptr->tilex == x) && (dptr->tiley == (y+1)))
3177 {elev->edx = x;
3178 elev->edy = y-1;
3179 }
3180 else if ((dptr->tilex == x) && (dptr->tiley == (y-1)))
3181 {elev->edx = x;
3182 elev->edy = y+1;
3183 }
3184 break;
3185 }
3186
3187 }
3188 }
3189 #if ((DEVELOPMENT == 1))
3190 #if ((ELEVATORTEST == 1))
3191 for(i=0;i<_numelevators;i++)
3192 Debug("\nelevator %d door1 %2d, door2 %2d",i,ELEVATOR[i].door1,ELEVATOR[i].door2);
3193 #endif
3194 #endif
3195 }
3196
3197
3198 /*
3199 =================
3200 =
3201 = SetupDoors
3202 =
3203 =================
3204 */
3205
SetupDoors(void)3206 void SetupDoors (void)
3207 {
3208 int j, i;
3209 word *map;
3210 word tile;
3211 byte locked;
3212
3213 map = mapplanes[0];
3214
3215 for (j = 0; j < mapheight; j++)
3216 for (i = 0; i < mapwidth; i++)
3217 {
3218 tile = *map++;
3219
3220 if ((tile >= 33) && (tile <= 35))
3221 {
3222 tilemap[i][j] = doornum;
3223
3224 locked=0;
3225 if (MAPSPOT (i, j, 2))
3226 locked = 5;
3227
3228 SpawnDoor (i, j, locked, (tile-33)+15);
3229 }
3230
3231 else if ((tile > 89) && (tile < 94))
3232 {
3233 tilemap[i][j] = doornum;
3234
3235 locked = 0;
3236 if (MAPSPOT (i, j, 2))
3237 locked = 5;
3238
3239 SpawnDoor (i, j, locked, tile-90);
3240 }
3241
3242 else if ((tile > 93) && (tile < 98))
3243 {
3244 Error("locked door %d being used at %d,%d",tile,i,j);
3245 }
3246
3247
3248 else if ((tile > 97) && (tile < 105))
3249 {
3250 tilemap[i][j] = doornum;
3251
3252 locked = 0;
3253 if (MAPSPOT (i, j, 2))
3254 locked = 5;
3255
3256 SpawnDoor (i, j, locked, tile-90);
3257 }
3258 else if ((tile >= 154) && (tile <= 156))
3259 {
3260 tilemap[i][j] = doornum;
3261
3262 locked=0;
3263 if (MAPSPOT (i, j, 2))
3264 locked = 5;
3265
3266 SpawnDoor (i, j, locked, (tile-154)+18);
3267 }
3268 }
3269 }
3270
3271 /*
3272 ==================
3273 =
3274 = GetDoorNumber
3275 =
3276 ==================
3277 */
3278
GetDoorNumber(int tx,int ty)3279 int GetDoorNumber( int tx, int ty )
3280 {
3281 int i;
3282
3283 for (i=0;i<doornum;i++)
3284 if ( (doorobjlist[i]->tilex==tx) && (doorobjlist[i]->tiley==ty))
3285 return i;
3286 Error ("Could not find a door at x=%ld y=%ld\n",tx,ty);
3287 return -1;
3288 }
3289
3290 /*
3291 =================
3292 =
3293 = SetupDoorLinks
3294 =
3295 =================
3296 */
3297
SetupDoorLinks(void)3298 void SetupDoorLinks (void)
3299 {
3300 int j,
3301 i,
3302 k;
3303 word *map;
3304 int clocklinked;
3305 int clockx,clocky;
3306 int doornumber;
3307 word touchx,
3308 tile,
3309 touchy;
3310
3311 map = mapplanes[0];
3312
3313 for (j = 0; j < mapheight; j++)
3314 for (i = 0; i < mapwidth; i++)
3315 {
3316 tile = *map++;
3317
3318 if (MAPSPOT (i, j, 2))
3319 {
3320 if (IsDoor(i,j)==1)
3321 {
3322 clocklinked = 0;
3323
3324 doornumber=GetDoorNumber(i,j);
3325
3326 for (k = 0; k < numclocks; k++)
3327 {
3328 clockx = Clocks[k].points_to_tilex;
3329 clocky = Clocks[k].points_to_tiley;
3330
3331 if ((clockx == i) && (clocky == j))
3332 {
3333 clocklinked = 1;
3334 ClockLink (LinkedOpenDoor, LinkedCloseDoor, doornumber, k);
3335 doorobjlist[doornumber]->lock = 5;
3336 doorobjlist[doornumber]->flags |= DF_TIMED;
3337 }
3338 }
3339
3340 if (!clocklinked)
3341 {
3342 touchx = (word) ((MAPSPOT (i, j, 2) >> 8) & 0xff);
3343 touchy = (word) ((MAPSPOT (i, j, 2) >> 0) & 0xff);
3344
3345 if (touchindices[touchx][touchy])
3346 {
3347 if (MAPSPOT (i, j, 1) == 192)
3348 Link_To_Touchplate (touchx, touchy, LinkedCloseDoor,
3349 LinkedCloseDoor, doornumber, 0);
3350 else
3351 Link_To_Touchplate (touchx, touchy, LinkedOpenDoor,
3352 LinkedOpenDoor, doornumber, 0);
3353 }
3354 else
3355 Error ("tried to link a door at x=%ld y=%ld to a non-existent touchplate",i,j);
3356 }
3357 }
3358 }
3359 }
3360 }
3361
3362
3363 /*
3364 =================
3365 =
3366 = FindTimeTile
3367 =
3368 =================
3369 */
FindTimeTile(int * x,int * y)3370 void FindTimeTile ( int * x, int * y )
3371 {
3372 int xx,yy;
3373
3374 xx=*x;
3375 yy=*y;
3376
3377 if (!(tilemap[xx+1][yy]) && MAPSPOT(xx+1,yy,2))
3378 {
3379 *x=xx+1;
3380 return;
3381 }
3382 if (!(tilemap[xx-1][yy]) && MAPSPOT(xx-1,yy,2))
3383 {
3384 *x=xx-1;
3385 return;
3386 }
3387 if (!(tilemap[xx][yy+1]) && MAPSPOT(xx,yy+1,2))
3388 {
3389 *y=yy+1;
3390 return;
3391 }
3392 if (!(tilemap[xx][yy-1]) && MAPSPOT(xx,yy-1,2))
3393 {
3394 *y=yy-1;
3395 return;
3396 }
3397 Error ("Could not find an end time for a clock linked item\nat x=%ld y=%ld\n",*x,*y);
3398 }
3399
3400
3401
3402 /*
3403 =================
3404 =
3405 = SetupClocks
3406 =
3407 =================
3408 */
3409
SetupClocks(void)3410 void SetupClocks (void)
3411 {
3412 int i,
3413 j,
3414 minutes,
3415 seconds,
3416 starti;
3417 word *map,
3418 tile,
3419 mapx,
3420 mapy;
3421 int endtimex,
3422 endtimey;
3423
3424
3425 map = mapplanes[1];
3426 map += 4 ;
3427
3428 for (j = 0; j < mapheight; j++)
3429 {
3430 if (j == 0)
3431 starti = 4;
3432 else
3433 starti = 0;
3434
3435 for (i = starti; i < mapwidth; i++)
3436 {
3437 tile = *map++;
3438
3439 if (tile == 121)
3440 {
3441 mapx = (word) ((MAPSPOT (i, j, 2) >> 8) & 0xff);
3442 mapy = (word) ((MAPSPOT (i, j, 2) >> 0) & 0xff);
3443
3444 minutes = (int) ((MAPSPOT (mapx, mapy, 2) >> 8) & 0xff);
3445 seconds = (int) ((MAPSPOT (mapx, mapy, 2) >> 0) & 0xff);
3446
3447 if (seconds > 0x59)
3448 Error ("seconds of clock time must be below 0x5a (60 secs) ");
3449
3450 seconds = 10 * (seconds/16) + (seconds % 16);
3451 minutes = 60 * (10*(minutes/16) + (minutes % 16));
3452
3453 // total seconds
3454 Clocks[numclocks].time1 = VBLCOUNTER*(seconds + minutes);
3455
3456 endtimex=mapx;
3457 endtimey=mapy;
3458
3459 FindTimeTile (&endtimex, &endtimey);
3460
3461 minutes = (int) ((MAPSPOT (endtimex, endtimey, 2) >> 8) & 0xff);
3462 seconds = (int) ((MAPSPOT (endtimex, endtimey, 2) >> 0) & 0xff);
3463
3464 if (seconds > 0x59)
3465 Error("seconds of clock time must be below 0x5a (60 secs)");
3466
3467 seconds = 10 * (seconds/16) + (seconds % 16);
3468 minutes = 60 * (10*(minutes/16) + (minutes % 16));
3469
3470 // total seconds
3471 Clocks[numclocks].time2 = VBLCOUNTER * (seconds + minutes);
3472 Clocks[numclocks].points_to_tilex = mapx;
3473 Clocks[numclocks].points_to_tiley = mapy;
3474 Clocks[numclocks].linkindex = lasttouch;
3475
3476 numclocks ++;
3477
3478 // clocks treated as virtual touchplates
3479 lasttouch ++;
3480 }
3481 }
3482 }
3483 }
3484
3485
3486
3487 /*
3488 =================
3489 =
3490 = LinkElevatorDiskGroups
3491 =
3492 =================
3493 */
3494
LinkElevatorDiskGroups(void)3495 void LinkElevatorDiskGroups(void)
3496 {
3497 objtype *diskfinder1,*temp,*master;
3498 int maxplatformheight[30]={-1};
3499 int num_distinct_max_heights=0;
3500 int i;
3501 boolean newdiskheight;
3502
3503
3504 #define M_ISELEVDISK(actor) \
3505 ((actor->obclass == diskobj) && (actor->state == &s_elevdisk))
3506
3507
3508
3509 for(diskfinder1 = FIRSTACTOR;diskfinder1;diskfinder1 = diskfinder1->next)
3510 {
3511 if (!M_ISELEVDISK(diskfinder1))
3512 continue;
3513
3514 newdiskheight = true;
3515 for(i=0;i<num_distinct_max_heights;i++)
3516 {
3517 if (maxplatformheight[i] == diskfinder1->temp2)
3518 {
3519 newdiskheight = false;
3520 break;
3521 }
3522 }
3523
3524 if (newdiskheight == true)
3525 maxplatformheight[num_distinct_max_heights++] = diskfinder1->temp2;
3526
3527 }
3528
3529
3530 for(i=0;i<num_distinct_max_heights;i++)
3531 {
3532
3533 SpawnDisk(64,64,0,true);
3534 master = new;
3535 master->temp2 = maxplatformheight[i];
3536
3537 for(temp = FIRSTACTOR;temp;temp = temp->next)
3538 {
3539 if (temp == master)
3540 continue;
3541
3542 if (!M_ISELEVDISK(temp))
3543 continue;
3544
3545 if (temp->temp2 != maxplatformheight[i])
3546 continue;
3547
3548 temp->target = master;
3549 SetTilePosition(master,temp->tilex,temp->tiley);
3550 master->areanumber=AREANUMBER(master->tilex,master->tiley);
3551
3552 }
3553 master->flags |= FL_ABP;
3554 MakeActive(master);
3555 }
3556
3557
3558 }
3559
3560
3561 /*
3562 =================
3563 =
3564 = LinkActor
3565 =
3566 =================
3567 */
3568
3569
LinkActor(objtype * ob,int tilex,int tiley,void (* action)(int),void (* swapaction)(int))3570 void LinkActor (objtype *ob,int tilex,int tiley,
3571 void (*action)(int),void (*swapaction)(int)
3572 )
3573 {
3574 word touchx,touchy;
3575 int clockx,clocky;
3576 int clocklinked,k;
3577 wall_t * tswitch;
3578
3579
3580 clocklinked = 0;
3581 for(k=0;k<numclocks;k++)
3582 {
3583 clockx = Clocks[k].points_to_tilex;
3584 clocky = Clocks[k].points_to_tiley;
3585 if ((clockx == tilex) && (clocky == tiley))
3586 {
3587 clocklinked = 1;
3588 ClockLink(EnableObject,DisableObject,(int)ob,k);
3589 }
3590 }
3591
3592 if (!clocklinked)
3593 {
3594 touchx = (word) ((MAPSPOT(tilex,tiley,2) >> 8) & 0xff);
3595 touchy = (word) ((MAPSPOT(tilex,tiley,2) >> 0) & 0xff);
3596 if ((MISCVARS->TOMLOC.x == touchx) && (MISCVARS->TOMLOC.y == touchy))
3597 {
3598 objtype *tom = (objtype*)actorat[touchx][touchy];
3599 tom->whatever = ob;
3600 }
3601
3602 else if (touchindices[touchx][touchy])
3603 {
3604 tswitch = (wall_t*) actorat[touchx][touchy];
3605
3606 if (tswitch && (ob->obclass == wallfireobj))
3607 {
3608 tswitch->flags |= FL_REVERSIBLE;
3609 if (tswitch->flags & FL_ON)
3610 ob->flags |= FL_ACTIVE;
3611 }
3612
3613
3614 if (tswitch && (tswitch->flags & FL_ON))
3615 Link_To_Touchplate(touchx,touchy,swapaction,action,(int)ob,0);
3616 else
3617 Link_To_Touchplate(touchx,touchy,action,swapaction,(int)ob,0);
3618 if (ob->obclass == gasgrateobj)
3619 {
3620 ob->temp1 = touchx;
3621 ob->temp2 = touchy;
3622 }
3623 }
3624 else
3625 Error("tried to link an object at x=%ld y=%ld to a non-existent touchplate supposedly at x=%ld y=%ld",tilex,tiley,touchx,touchy);
3626 }
3627
3628 if (tilemap[tilex][tiley])
3629 (MAPSPOT(tilex,tiley,2))=21;
3630 }
3631
3632
3633
3634
3635 /*
3636 ======================
3637 =
3638 = SetupInanimateActors
3639 =
3640 ======================
3641 */
3642
3643
SetupInanimateActors(void)3644 void SetupInanimateActors (void)
3645 {
3646 int i,j,linked;
3647 word *map,tile;
3648 void (*action)(int),(*swapaction)(int);
3649
3650
3651 map = mapplanes[1];
3652
3653
3654 // non-linked, harmless inanimate actors
3655 for(j=0;j<mapheight;j++)
3656 {
3657 for(i=0;i<mapwidth;i++)
3658 {
3659 tile = *map++;
3660
3661 switch(tile)
3662 {
3663
3664 case 193:
3665 SpawnSpring(i,j);
3666 break;
3667
3668 #if 0
3669 case 460:
3670 // if ( gamestate.Product != ROTT_SHAREWARE )
3671 {
3672 SpawnNewObj(i,j,&s_wind,inertobj);
3673 }
3674 break;
3675 #endif
3676
3677 case 462:
3678 case 463:
3679 case 464:
3680 case 465:
3681 case 466:
3682
3683 SpawnDisk(i,j,tile-462,false);
3684 break;
3685
3686 case 285:
3687 case 286:
3688 case 287:
3689 SpawnPushColumn(i,j,tile-285,nodir,0);
3690 break;
3691 }
3692 }
3693 }
3694
3695
3696 // linked, harmless actors
3697 map = mapplanes[1];
3698 for(j=0;j<mapheight;j++)
3699 {
3700 for(i=0;i<mapwidth;i++)
3701 {
3702 tile = *map++;
3703 action = EnableObject;
3704 swapaction = DisableObject;
3705 linked = (MAPSPOT(i,j,2) && (!IsPlatform(i,j)));
3706
3707
3708 switch(tile)
3709 {
3710
3711 case 140:
3712 case 141:
3713 case 142:
3714 case 143:
3715
3716 if ((!BATTLEMODE) || (gamestate.BattleOptions.SpawnDangers))
3717 {
3718 PreCacheActor(wallfireobj,0);
3719 SpawnWallfire(i,j,tile-140);
3720 if (!linked)
3721 {
3722 new->flags |= FL_ACTIVE;
3723 if (tilemap[i][j])
3724 MAPSPOT(i,j,2) = 21;
3725 }
3726 else
3727 LinkActor(new,i,j,action,swapaction);
3728 }
3729 else if (tilemap[i][j])
3730 MAPSPOT(i,j,2) = 21;
3731
3732 break;
3733
3734
3735
3736
3737
3738 case 303:
3739 case 304:
3740 case 305:
3741 SpawnPushColumn(i,j,tile-303,east,linked);
3742 swapaction = NULL;
3743 if (linked)
3744 LinkActor(new,i,j,action,swapaction);
3745
3746 break;
3747
3748 case 321:
3749 case 322:
3750 case 323:
3751 SpawnPushColumn(i,j,tile-321,north,linked);
3752 swapaction = NULL;
3753 if (linked)
3754 LinkActor(new,i,j,action,swapaction);
3755
3756 break;
3757
3758 case 339:
3759 case 340:
3760 case 341:
3761 SpawnPushColumn(i,j,tile-339,west,linked);
3762 swapaction = NULL;
3763 if (linked)
3764 LinkActor(new,i,j,action,swapaction);
3765
3766 break;
3767
3768 case 357:
3769 case 358:
3770 case 359:
3771 SpawnPushColumn(i,j,tile-357,south,linked);
3772 swapaction = NULL;
3773 if (linked)
3774 LinkActor(new,i,j,action,swapaction);
3775
3776 break;
3777
3778
3779 }
3780
3781 }
3782 }
3783
3784 //harmful actors
3785
3786 if ((!BATTLEMODE) || (gamestate.BattleOptions.SpawnDangers))
3787 {
3788 map = mapplanes[1];
3789 for(j=0;j<mapheight;j++)
3790 {
3791 for(i=0;i<mapwidth;i++)
3792 {
3793 tile = *map++;
3794 action = EnableObject;
3795 swapaction = DisableObject;
3796 linked = (MAPSPOT(i,j,2) && (!IsPlatform(i,j)));
3797
3798 switch(tile)
3799 {
3800 case 89:
3801 SpawnFourWayGun(i,j);
3802 break;
3803
3804
3805 case 156:
3806 case 157:
3807 SpawnBlade(i,j,nodir,0,tile-156);
3808 if (linked)
3809 LinkActor(new,i,j,action,swapaction);
3810
3811 break;
3812
3813 case 174:
3814 case 175:
3815 SpawnBlade(i,j,nodir,1,tile-174);
3816 if (linked)
3817 LinkActor(new,i,j,action,swapaction);
3818
3819 break;
3820
3821
3822
3823 case 412:
3824 SpawnSpear(i,j,0);
3825 break;
3826
3827 case 430:
3828 SpawnSpear(i,j,1);
3829 break;
3830
3831 case 413:
3832 SpawnCrushingColumn(i,j,1); //down
3833 break;
3834
3835 case 431:
3836 SpawnCrushingColumn(i,j,0); // up
3837 break;
3838
3839
3840 case 192:
3841 if (!tilemap[i][j])
3842 {
3843 SpawnNewObj(i,j,&s_gas1,gasgrateobj);
3844 PreCacheActor(gasgrateobj,0);
3845 new->flags |= FL_ABP;
3846 MakeActive(new);
3847 swapaction = NULL;
3848 if (linked)
3849 LinkActor(new,i,j,action,swapaction);
3850
3851 }
3852 break;
3853
3854
3855 case 301:
3856 case 302:
3857 SpawnBlade(i,j,east,tile-301,0);
3858 if (!linked)
3859 new->flags |= FL_ACTIVE;
3860 else
3861 LinkActor(new,i,j,action,swapaction);
3862
3863 break;
3864
3865 case 319:
3866 case 320:
3867 SpawnBlade(i,j,north,tile-319,0);
3868 if (!linked)
3869 new->flags |= FL_ACTIVE;
3870 else
3871 LinkActor(new,i,j,action,swapaction);
3872
3873 break;
3874
3875 case 337:
3876 case 338:
3877 SpawnBlade(i,j,west,tile-337,0);
3878 if (!linked)
3879 new->flags |= FL_ACTIVE;
3880 else
3881 LinkActor(new,i,j,action,swapaction);
3882
3883 break;
3884
3885 case 355:
3886 case 356:
3887 SpawnBlade(i,j,south,tile-355,0);
3888 if (!linked)
3889 new->flags |= FL_ACTIVE;
3890 else
3891 LinkActor(new,i,j,action,swapaction);
3892
3893 break;
3894
3895 case 372:
3896 SpawnFirejet(i,j,nodir,0);
3897 break;
3898
3899 case 373:
3900 case 374:
3901 case 375:
3902 case 376:
3903 SpawnFirejet(i,j,tile-373,0);
3904 break;
3905
3906 case 390:
3907 SpawnFirejet(i,j,nodir,1);
3908 break;
3909
3910 case 391:
3911 case 392:
3912 case 393:
3913 case 394:
3914 SpawnFirejet(i,j,tile-391,1);
3915 break;
3916
3917 case 278:
3918 case 279:
3919 case 280:
3920 case 281:
3921 SpawnBoulder(i,j,tile-278);
3922 if (!linked)
3923 new->flags |= FL_ACTIVE;
3924 else
3925 LinkActor(new,i,j,action,swapaction);
3926
3927 break;
3928
3929 }
3930
3931
3932 }
3933 }
3934 }
3935
3936 LinkElevatorDiskGroups();
3937
3938 }
3939
3940
3941 /*
3942 ===================
3943 =
3944 = FixTiles
3945 =
3946 ===================
3947 */
3948
FixTiles(void)3949 void FixTiles(void)
3950 {
3951 word *map,tile;
3952 int i,j;
3953
3954 map = mapplanes[1];
3955 for(j=0;j<mapheight;j++)
3956 {
3957 for(i=0;i<mapwidth;i++)
3958 {
3959 tile = *map++;
3960 switch(tile)
3961 {
3962 case 140:
3963 case 141:
3964 case 142:
3965 case 143:
3966 case 192:
3967 case 278:
3968 case 279:
3969 case 280:
3970 case 281:
3971 if (tilemap[i][j])
3972 (MAPSPOT(i,j,2))=21;
3973 break;
3974 }
3975 }
3976 }
3977
3978 }
3979
3980
Illuminate(void)3981 void Illuminate(void)
3982 {statobj_t*temp;
3983
3984 if (lightsource==0)
3985 return;
3986 for(temp=FIRSTSTAT;temp;temp=temp->statnext)
3987 if (temp->flags & FL_LIGHTON)
3988 TurnOnLight(temp->tilex,temp->tiley);
3989 }
3990
3991
3992 /*
3993 =================
3994 =
3995 = SetupLights
3996 =
3997 =================
3998 */
SetupLights(void)3999 void SetupLights(void)
4000 {
4001 int i,j,touchx,touchy;
4002 wall_t *tswitch;
4003 word *map,tile;
4004 int starti;
4005
4006 // Initialize Lights in Area
4007
4008 memset(LightsInArea,0,sizeof(LightsInArea));
4009
4010 map = mapplanes[1];
4011 map+=5;
4012
4013 for (j=0;j<mapheight;j++)
4014 {
4015 if (j==0)
4016 starti=5;
4017 else
4018 starti=0;
4019 for(i=starti;i<mapwidth;i++)
4020 {
4021 tile= *map++;
4022
4023
4024
4025 switch (tile)
4026 {
4027
4028 // Add light sourcing to these objects
4029
4030 case 23:
4031 case 24:
4032 case 25:
4033 case 26:
4034 case 27:
4035 case 42:
4036 case 63:
4037 case 64:
4038 sprites[i][j]->flags |= FL_LIGHTON;
4039 break;
4040
4041 case 28:
4042 case 43:
4043 if (MAPSPOT(i,j,2))
4044 {
4045 touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff);
4046 touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff);
4047 tswitch = (wall_t*) actorat[touchx][touchy];
4048
4049 if (tswitch && (tswitch->which == WALL))
4050 {tswitch->flags |= FL_REVERSIBLE;
4051 if (!(tswitch->flags & FL_ON))
4052 {sprites[i][j]->shapenum --;
4053 if (touchindices[touchx][touchy])
4054 {Link_To_Touchplate(touchx,touchy,ActivateLight,DeactivateLight,(int)(sprites[i][j]),0);
4055 sprites[i][j]->linked_to = touchindices[touchx][touchy]-1;
4056 }
4057 else
4058 Error("tried to link a light at x=%ld y=%ld to a non-existent touchplate",i,j);
4059 }
4060 else
4061 {if (touchindices[touchx][touchy])
4062 {Link_To_Touchplate(touchx,touchy,DeactivateLight,ActivateLight,(int)(sprites[i][j]),0);
4063 sprites[i][j]->linked_to = touchindices[touchx][touchy]-1;
4064 }
4065 else
4066 Error("tried to link a light at x=%ld y=%ld to a non-existent touchplate",i,j);
4067 sprites[i][j]->flags |= FL_LIGHTON;
4068 }
4069 }
4070 else
4071 {if (touchindices[touchx][touchy])
4072 {Link_To_Touchplate(touchx,touchy,DeactivateLight,ActivateLight,(int)(sprites[i][j]),0);
4073 sprites[i][j]->linked_to = touchindices[touchx][touchy]-1;
4074 }
4075 else
4076 Error("tried to link a light at x=%ld y=%ld to a non-existent touchplate",i,j);
4077 sprites[i][j]->flags |= FL_LIGHTON;
4078 }
4079
4080 }
4081 else
4082 sprites[i][j]->flags |= FL_LIGHTON;
4083
4084 break;
4085 }
4086 }
4087 }
4088 }
4089
4090 /*
4091 ==================
4092 =
4093 = PrintMapStats
4094 =
4095 ==================
4096 */
PrintMapStats(void)4097 void PrintMapStats (void)
4098 {
4099 int size;
4100 int total;
4101
4102 if (MAPSTATS==false)
4103 return;
4104
4105 OpenMapDebug();
4106
4107 total=0;
4108 MapDebug("MAP STATS Map Number %ld\n",gamestate.mapon);
4109 MapDebug("=======================\n");
4110 size=pwallnum*sizeof(pwallobj_t);
4111 total+=size;
4112 MapDebug("Number of PushWalls : %4ld size = %6ld\n",pwallnum,size);
4113 size=maskednum*sizeof(maskedwallobj_t);
4114 total+=size;
4115 MapDebug("Number of MaskedWalls : %4ld size = %6ld\n",maskednum,size);
4116 size=doornum*sizeof(doorobj_t);
4117 total+=size;
4118 MapDebug("Number of Doors : %4ld size = %6ld\n",doornum,size);
4119 size=lasttouch*sizeof(touchplatetype);
4120 total+=size;
4121 MapDebug("Number of TouchPlates : %4ld size = %6ld\n",lasttouch,size);
4122 size=_numelevators*sizeof(elevator_t);
4123 total+=size;
4124 MapDebug("Number of Elevators : %4ld size = %6ld\n",_numelevators,size);
4125 size=statcount*sizeof(statobj_t);
4126 total+=size;
4127 MapDebug("Number of Sprites : %4ld size = %6ld\n",statcount,size);
4128 size=objcount*sizeof(objtype);
4129 total+=size;
4130 MapDebug("Number of Actors : %4ld size = %6ld\n",objcount,size);
4131 MapDebug("Number of Clocks : %4ld\n",numclocks);
4132 MapDebug("\nTotal size of level : %6ld\n",total);
4133 }
4134
4135
IsWeapon(int tile)4136 boolean IsWeapon(int tile)
4137 {
4138 if ((tile >= 46) && (tile <= 56))
4139 return true;
4140
4141 return false;
4142
4143 }
4144
4145
WeaponName(int tile)4146 char *WeaponName(int tile)
4147 {
4148 switch(tile)
4149 {
4150 case 46:
4151 return "Bat ";
4152 break;
4153
4154 case 47:
4155 return "Knife ";
4156 break;
4157
4158 case 48:
4159 return "Double Pistol ";
4160 break;
4161
4162 case 49:
4163 return "MP40 ";
4164 break;
4165
4166 case 50:
4167 return "Bazooka ";
4168 break;
4169
4170 case 51:
4171 return "Firebomb ";
4172 break;
4173
4174 case 52:
4175 return "Heatseeker ";
4176 break;
4177
4178 case 53:
4179 return "Drunk Missile ";
4180 break;
4181
4182 case 54:
4183 return "Flamewall ";
4184 break;
4185
4186 case 55:
4187 return "Split Missile ";
4188 break;
4189
4190 case 56:
4191 return "KES ";
4192 break;
4193 }
4194 return " ";
4195 }
4196
4197
4198
GetLumpForTile(int tile)4199 int GetLumpForTile(int tile)
4200 {
4201 int wallstart;
4202 int exitstart;
4203
4204 wallstart=W_GetNumForName("WALLSTRT");
4205 exitstart=W_GetNumForName("EXITSTRT");
4206 elevatorstart = W_GetNumForName("ELEVSTRT");
4207
4208 if ((tile >= 1) && (tile <= 32))
4209 {
4210 return (tile + wallstart);
4211 }
4212 else if ((tile >= 36) && (tile <= 45))
4213 {
4214 return (tile + wallstart - 3);
4215 }
4216 else if (tile == 46)
4217 {
4218 return (wallstart + 74);
4219 }
4220 else if ((tile >= 47) && (tile <= 48))
4221 {
4222 return (tile + exitstart - 46);
4223 }
4224 else if ((tile >= 49) && (tile <= 71))
4225 {
4226 return (tile + wallstart - 8);
4227 }
4228 else if ((tile >= 72) && (tile <= 79))
4229 {
4230 return (tile - 72 + elevatorstart + 1);
4231 }
4232 else if ((tile >= 80) && (tile <= 89))
4233 {
4234 return (tile + wallstart - 16);
4235 }
4236 return -1;
4237 }
4238
4239
4240
4241
4242 #if (DEVELOPMENT == 1)
4243
4244
4245 /*
4246 ==================
4247 =
4248 = Insane Dump
4249 =
4250 ==================
4251 */
4252
InsaneDump(void)4253 void InsaneDump(void)
4254 {
4255 int i,j,level;
4256 word *map,tile;
4257 int tally[1000];
4258 int inlevel[1000][10];
4259
4260 if (TILESTATS==false)
4261 return;
4262
4263 OpenMapDebug();
4264
4265
4266 // WALLS
4267 memset(tally,0,sizeof(tally));
4268 memset(inlevel,0,sizeof(inlevel));
4269 MapDebug("=======================\n");
4270 MapDebug("= WALLS\n");
4271 MapDebug("=======================\n");
4272 mapheight = mapwidth = 128;
4273 BATTLEMODE = 1;
4274 for(level=0;level<8;level ++)
4275 {
4276 GetEpisode(level);
4277 LoadROTTMap(level);
4278 map = mapplanes[0];
4279 for (j=0;j<mapheight;j++)
4280 {
4281 for(i=0;i<mapwidth;i++)
4282 {tile = *map++;
4283 if (IsWall(i,j)==true)
4284 {tally[tile]++;
4285 inlevel[tile][level]=1;
4286 }
4287
4288 }
4289 }
4290 }
4291
4292 MapDebug("Wall # Frequency Levels\n");
4293 MapDebug("----------------------------\n");
4294 for (i=0;i<1000;i++)
4295 if (i < 90)
4296 {MapDebug("%4d %4d %s",i,tally[i],
4297 W_GetNameForNum(GetLumpForTile(i)));
4298 MapDebug(" ");
4299 for(level=0;level < 10;level ++)
4300 if (inlevel[i][level])
4301 MapDebug("%d,",level);
4302 MapDebug("\n");
4303 }
4304
4305
4306
4307
4308
4309 // Doors
4310 memset(tally,0,sizeof(tally));
4311 memset(inlevel,0,sizeof(inlevel));
4312 MapDebug("=======================\n");
4313 MapDebug("= DOORS\n");
4314 MapDebug("=======================\n");
4315 for(level=0;level<10;level ++)
4316 {
4317 GetEpisode(level);
4318 LoadROTTMap(level);
4319 map = mapplanes[0];
4320 for (j=0;j<mapheight;j++)
4321 {
4322 for(i=0;i<mapwidth;i++)
4323 {tile = *map++;
4324 if (IsDoor(i,j)==true)
4325 {tally[tile]++;
4326 inlevel[tile][level]=1;
4327 }
4328
4329 }
4330 }
4331 }
4332
4333 MapDebug("Door # Frequency Levels\n");
4334 MapDebug("----------------------------\n");
4335 for (i=0;i<1000;i++)
4336 if (tally[i]!=0)
4337 {MapDebug("%4d %4d ",i,tally[i]);
4338 for(level=0;level < 10;level ++)
4339 if (inlevel[i][level])
4340 MapDebug("%d,",level);
4341 MapDebug("\n");
4342
4343 }
4344
4345 // MaskedWalls
4346 memset(tally,0,sizeof(tally));
4347 memset(inlevel,0,sizeof(inlevel));
4348 MapDebug("=======================\n");
4349 MapDebug("= MASKED WALLS\n");
4350 MapDebug("=======================\n");
4351 for(level=0;level<10;level ++)
4352 {
4353 GetEpisode(level);
4354 LoadROTTMap(level);
4355 map = mapplanes[0];
4356 for (j=0;j<mapheight;j++)
4357 {
4358 for(i=0;i<mapwidth;i++)
4359 {tile = *map++;
4360 if ((IsMaskedWall(i,j)) && (!IsPlatform(i,j)))
4361 {tally[tile]++;
4362 inlevel[tile][level]=1;
4363 }
4364
4365 }
4366 }
4367 }
4368
4369 MapDebug("MWall # Frequency Levels\n");
4370 MapDebug("----------------------------\n");
4371 for (i=0;i<1000;i++)
4372 if (tally[i]!=0)
4373 {MapDebug("%4d %4d ",i,tally[i]);
4374 for(level=0;level < 10;level ++)
4375 if (inlevel[i][level])
4376 MapDebug("%d,",level);
4377 MapDebug("\n");
4378
4379 }
4380
4381 }
4382
4383 #endif
4384
4385 /*
4386 ==================
4387 =
4388 = PrintTileStats
4389 =
4390 ==================
4391 */
PrintTileStats(void)4392 void PrintTileStats (void)
4393 {
4394 int i,j;
4395 word *map;
4396 int easytotal;
4397 int hardtotal;
4398 int tally[1000];
4399
4400 if (TILESTATS==false)
4401 return;
4402
4403 OpenMapDebug();
4404
4405 MapDebug("TILE STATS Map Number %ld\n",gamestate.mapon);
4406 MapDebug("=======================\n\n");
4407
4408
4409 // Weapons
4410 memset(tally,0,sizeof(tally));
4411 MapDebug("=======================\n");
4412 MapDebug("= WEAPONS\n");
4413 MapDebug("=======================\n");
4414 map = mapplanes[1];
4415 for (j=0;j<mapheight;j++)
4416 {
4417 for(i=0;i<mapwidth;i++)
4418 {
4419 if (IsWeapon(*map))
4420 MapDebug("\n %s at %3d,%3d",WeaponName(*map),i,j);
4421 map++;
4422 }
4423 }
4424 MapDebug("\n\n");
4425 // WALLS
4426 memset(tally,0,sizeof(tally));
4427 MapDebug("=======================\n");
4428 MapDebug("= WALLS\n");
4429 MapDebug("=======================\n");
4430 map = mapplanes[0];
4431 for (j=0;j<mapheight;j++)
4432 {
4433 for(i=0;i<mapwidth;i++)
4434 {
4435 if (IsWall(i,j)==true)
4436 tally[(*map)]++;
4437 map++;
4438 }
4439 }
4440 MapDebug("Wall # Frequency\n");
4441 MapDebug("-----------------------\n");
4442 for (i=0;i<1000;i++)
4443 if (tally[i]!=0)
4444 MapDebug(" %4ld %4ld\n",i,tally[i]);
4445
4446 // Doors
4447 memset(tally,0,sizeof(tally));
4448 MapDebug("=======================\n");
4449 MapDebug("= DOORS\n");
4450 MapDebug("=======================\n");
4451 map = mapplanes[0];
4452 for (j=0;j<mapheight;j++)
4453 {
4454 for(i=0;i<mapwidth;i++)
4455 {
4456 if (IsDoor(i,j)==true)
4457 tally[(*map)]++;
4458 map++;
4459 }
4460 }
4461 MapDebug("Door # Frequency\n");
4462 MapDebug("-----------------------\n");
4463 for (i=0;i<1000;i++)
4464 if (tally[i]!=0)
4465 MapDebug(" %4ld %4ld\n",i,tally[i]);
4466
4467 // MaskedWalls
4468 memset(tally,0,sizeof(tally));
4469 MapDebug("=======================\n");
4470 MapDebug("= MASKEDWALLS\n");
4471 MapDebug("=======================\n");
4472 map = mapplanes[0];
4473 for (j=0;j<mapheight;j++)
4474 {
4475 for(i=0;i<mapwidth;i++)
4476 {
4477 if (IsMaskedWall(i,j)==true)
4478 if (IsPlatform(i,j)==false)
4479 tally[(*map)]++;
4480 map++;
4481 }
4482 }
4483 MapDebug("Mwall # Frequency\n");
4484 MapDebug("-----------------------\n");
4485 for (i=0;i<1000;i++)
4486 if (tally[i]!=0)
4487 MapDebug(" %4ld %4ld\n",i,tally[i]);
4488 // Platforms
4489 memset(tally,0,sizeof(tally));
4490 MapDebug("=======================\n");
4491 MapDebug("= PLATFORMS\n");
4492 MapDebug("=======================\n");
4493 map = mapplanes[2];
4494 for (j=0;j<mapheight;j++)
4495 {
4496 for(i=0;i<mapwidth;i++)
4497 {
4498 if (IsPlatform(i,j)==true)
4499 tally[(*map)]++;
4500 map++;
4501 }
4502 }
4503 MapDebug("Pform # Frequency\n");
4504 MapDebug("-----------------------\n");
4505 for (i=0;i<1000;i++)
4506 if (tally[i]!=0)
4507 MapDebug(" %4ld %4ld\n",i,tally[i]);
4508
4509 // Actors
4510 memset(tally,0,sizeof(tally));
4511 MapDebug("=======================\n");
4512 MapDebug("= ACTORS\n");
4513 MapDebug("=======================\n");
4514 map = mapplanes[1];
4515 for (j=0;j<mapheight;j++)
4516 {
4517 for(i=0;i<mapwidth;i++)
4518 {
4519 if ((*map)>0)
4520 tally[(*map)]++;
4521 map++;
4522 }
4523 }
4524
4525 // Low Guards
4526 easytotal=0;
4527 hardtotal=0;
4528 for (i=108;i<=119;i++)
4529 easytotal+=tally[i];
4530 for (i=126;i<=137;i++)
4531 hardtotal+=tally[i];
4532 MapDebug("\nLowGuards\n");
4533 MapDebug("-----------------------\n");
4534 MapDebug("EasyTotal=%4ld\n",easytotal);
4535 MapDebug("HardTotal=%4ld\n",hardtotal);
4536 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4537
4538 // Sneaky Low Guards
4539 easytotal=0;
4540 hardtotal=0;
4541 for (i=120;i<=120;i++)
4542 easytotal+=tally[i];
4543 for (i=138;i<=138;i++)
4544 hardtotal+=tally[i];
4545 MapDebug("\nSneakyLowGuards\n");
4546 MapDebug("-----------------------\n");
4547 MapDebug("EasyTotal=%4ld\n",easytotal);
4548 MapDebug("HardTotal=%4ld\n",hardtotal);
4549 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4550
4551 // High Guards
4552 easytotal=0;
4553 hardtotal=0;
4554 for (i=144;i<=155;i++)
4555 easytotal+=tally[i];
4556 for (i=162;i<=173;i++)
4557 hardtotal+=tally[i];
4558 MapDebug("\nHighGuards\n");
4559 MapDebug("-----------------------\n");
4560 MapDebug("EasyTotal=%4ld\n",easytotal);
4561 MapDebug("HardTotal=%4ld\n",hardtotal);
4562 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4563
4564 // OverPatrol Guards
4565 easytotal=0;
4566 hardtotal=0;
4567 for (i=216;i<=227;i++)
4568 easytotal+=tally[i];
4569 for (i=234;i<=245;i++)
4570 hardtotal+=tally[i];
4571 MapDebug("\nOverPatrolGuards\n");
4572 MapDebug("-----------------------\n");
4573 MapDebug("EasyTotal=%4ld\n",easytotal);
4574 MapDebug("HardTotal=%4ld\n",hardtotal);
4575 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4576
4577 // Strike Guards
4578 easytotal=0;
4579 hardtotal=0;
4580 for (i=180;i<=191;i++)
4581 easytotal+=tally[i];
4582 for (i=198;i<=204;i++)
4583 hardtotal+=tally[i];
4584 MapDebug("\nStrikeGuards\n");
4585 MapDebug("-----------------------\n");
4586 MapDebug("EasyTotal=%4ld\n",easytotal);
4587 MapDebug("HardTotal=%4ld\n",hardtotal);
4588 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4589
4590 // TriadEnforcer Guards
4591 easytotal=0;
4592 hardtotal=0;
4593 for (i=288;i<=299;i++)
4594 easytotal+=tally[i];
4595 for (i=306;i<=317;i++)
4596 hardtotal+=tally[i];
4597 MapDebug("\nTriadEnforcer Guards\n");
4598 MapDebug("-----------------------\n");
4599 MapDebug("EasyTotal=%4ld\n",easytotal);
4600 MapDebug("HardTotal=%4ld\n",hardtotal);
4601 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4602
4603 // Lightning Guards
4604 easytotal=0;
4605 hardtotal=0;
4606 for (i=324;i<=335;i++)
4607 easytotal+=tally[i];
4608 for (i=342;i<=353;i++)
4609 hardtotal+=tally[i];
4610 MapDebug("\nLightningGuards\n");
4611 MapDebug("-----------------------\n");
4612 MapDebug("EasyTotal=%4ld\n",easytotal);
4613 MapDebug("HardTotal=%4ld\n",hardtotal);
4614 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4615
4616 // Random Actors
4617 easytotal=0;
4618 hardtotal=0;
4619 for (i=122;i<=125;i++)
4620 easytotal+=tally[i];
4621 MapDebug("\nRandom Actors\n");
4622 MapDebug("-----------------------\n");
4623 MapDebug(" Total=%4ld\n",easytotal);
4624
4625 // Monks
4626 easytotal=0;
4627 hardtotal=0;
4628 for (i=360;i<=371;i++)
4629 easytotal+=tally[i];
4630 for (i=378;i<=389;i++)
4631 hardtotal+=tally[i];
4632 MapDebug("\nMonks\n");
4633 MapDebug("-----------------------\n");
4634 MapDebug("EasyTotal=%4ld\n",easytotal);
4635 MapDebug("HardTotal=%4ld\n",hardtotal);
4636 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4637
4638 // Fire Monks
4639 easytotal=0;
4640 hardtotal=0;
4641 for (i=396;i<=407;i++)
4642 easytotal+=tally[i];
4643 for (i=414;i<=425;i++)
4644 hardtotal+=tally[i];
4645 MapDebug("\nFire Monks\n");
4646 MapDebug("-----------------------\n");
4647 MapDebug("EasyTotal=%4ld\n",easytotal);
4648 MapDebug("HardTotal=%4ld\n",hardtotal);
4649 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4650
4651 // Robo Guards
4652 easytotal=0;
4653 hardtotal=0;
4654 for (i=158;i<=161;i++)
4655 easytotal+=tally[i];
4656 for (i=176;i<=179;i++)
4657 hardtotal+=tally[i];
4658 MapDebug("\nRoboGuards\n");
4659 MapDebug("-----------------------\n");
4660 MapDebug("EasyTotal=%4ld\n",easytotal);
4661 MapDebug("HardTotal=%4ld\n",hardtotal);
4662 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4663
4664 // Ballistikrafts
4665 easytotal=0;
4666 hardtotal=0;
4667 for (i=408;i<=411;i++)
4668 easytotal+=tally[i];
4669 for (i=426;i<=429;i++)
4670 hardtotal+=tally[i];
4671 MapDebug("\nBallistikrafts\n");
4672 MapDebug("-----------------------\n");
4673 MapDebug("EasyTotal=%4ld\n",easytotal);
4674 MapDebug("HardTotal=%4ld\n",hardtotal);
4675 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4676
4677 // Boulders
4678 easytotal=0;
4679 hardtotal=0;
4680 for (i=278;i<=281;i++)
4681 easytotal+=tally[i];
4682 for (i=395;i<=395;i++)
4683 hardtotal+=tally[i];
4684 MapDebug("\nBoulders\n");
4685 MapDebug("-----------------------\n");
4686 MapDebug("Boulders=%4ld\n",easytotal);
4687 MapDebug("BoulderHoles=%4ld\n",hardtotal);
4688
4689 // PushColumns
4690 easytotal=0;
4691 hardtotal=0;
4692 for (i=285;i<=287;i++)
4693 easytotal+=tally[i];
4694 for (i=303;i<=305;i++)
4695 easytotal+=tally[i];
4696 for (i=321;i<=323;i++)
4697 easytotal+=tally[i];
4698 for (i=339;i<=341;i++)
4699 easytotal+=tally[i];
4700 for (i=357;i<=359;i++)
4701 easytotal+=tally[i];
4702 MapDebug("\nPushColumns\n");
4703 MapDebug("-----------------------\n");
4704 MapDebug(" Total=%4ld\n",easytotal);
4705
4706 // Gun Emplacements
4707 easytotal=0;
4708 hardtotal=0;
4709 for (i=194;i<=197;i++)
4710 easytotal+=tally[i];
4711 for (i=212;i<=215;i++)
4712 hardtotal+=tally[i];
4713 MapDebug("\nGun Emplacements\n");
4714 MapDebug("-----------------------\n");
4715 MapDebug("EasyTotal=%4ld\n",easytotal);
4716 MapDebug("HardTotal=%4ld\n",hardtotal);
4717 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4718
4719 // 4-way guns
4720 easytotal=0;
4721 hardtotal=0;
4722 for (i=89;i<=89;i++)
4723 easytotal+=tally[i];
4724 for (i=211;i<=211;i++)
4725 hardtotal+=tally[i];
4726 MapDebug("\n4-way guns\n");
4727 MapDebug("-----------------------\n");
4728 MapDebug("EasyTotal=%4ld\n",easytotal);
4729 MapDebug("HardTotal=%4ld\n",hardtotal);
4730 MapDebug(" Total=%4ld\n",easytotal+hardtotal);
4731
4732 // Stabbers from above
4733 MapDebug("\nStabbers from above\n");
4734 MapDebug("-----------------------\n");
4735 MapDebug(" Total=%4ld\n",tally[412]);
4736
4737 // Stabbers from below
4738 MapDebug("\nStabbers from below\n");
4739 MapDebug("-----------------------\n");
4740 MapDebug(" Total=%4ld\n",tally[430]);
4741
4742 // Crushing pillar from above
4743 MapDebug("\nCrushing pillar from above\n");
4744 MapDebug("-----------------------\n");
4745 MapDebug(" Total=%4ld\n",tally[413]);
4746
4747 // Crushing pillar from below
4748 MapDebug("\nCrushing pillar from below\n");
4749 MapDebug("-----------------------\n");
4750 MapDebug(" Total=%4ld\n",tally[431]);
4751
4752 // Above Spinner
4753 MapDebug("\nAbove Spinner\n");
4754 MapDebug("-----------------------\n");
4755 MapDebug(" Total=%4ld\n",tally[156]);
4756
4757 // Ground Spinner
4758 MapDebug("\nGround Spinner\n");
4759 MapDebug("-----------------------\n");
4760 MapDebug(" Total=%4ld\n",tally[174]);
4761
4762 // Spinner from above
4763 MapDebug("\nSpinner from above\n");
4764 MapDebug("-----------------------\n");
4765 MapDebug(" Total=%4ld\n",tally[157]);
4766
4767 // Spinner from below
4768 MapDebug("\nSpinner from below\n");
4769 MapDebug("-----------------------\n");
4770 MapDebug(" Total=%4ld\n",tally[175]);
4771
4772 // Bosses
4773 easytotal=0;
4774 for (i=99;i<=103;i++)
4775 easytotal+=tally[i];
4776 MapDebug("\nBosses\n");
4777 MapDebug("-----------------------\n");
4778 MapDebug(" Total=%4ld\n",easytotal);
4779
4780 // Spring Boards
4781 MapDebug("\nSpring Boards\n");
4782 MapDebug("-----------------------\n");
4783 MapDebug(" Total=%4ld\n",tally[193]);
4784
4785 // Above FlameJets
4786 easytotal=0;
4787 hardtotal=0;
4788 for (i=372;i<=376;i++)
4789 easytotal+=tally[i];
4790 for (i=390;i<=394;i++)
4791 hardtotal+=tally[i];
4792 MapDebug("\nFlameJets\n");
4793 MapDebug("-----------------------\n");
4794 MapDebug(" Above=%4ld\n",easytotal);
4795 MapDebug(" Ground=%4ld\n",hardtotal);
4796
4797 // Fire Chutes
4798 easytotal=0;
4799 for (i=140;i<=143;i++)
4800 easytotal+=tally[i];
4801 MapDebug("\nFireChutes\n");
4802 MapDebug("-----------------------\n");
4803 MapDebug(" Total=%4ld\n",easytotal);
4804
4805 // Sprites
4806 MapDebug("=======================\n");
4807 MapDebug("= SPRITES\n");
4808 MapDebug("=======================\n");
4809 MapDebug("Sprite # Frequency\n");
4810 MapDebug("-----------------------\n");
4811 for (i=1;i<=72;i++)
4812 if (tally[i]!=0)
4813 MapDebug(" %4ld %4ld\n",i,tally[i]);
4814 for (i=210;i<=210;i++)
4815 if (tally[i]!=0)
4816 MapDebug(" %4ld %4ld\n",i,tally[i]);
4817 for (i=228;i<=233;i++)
4818 if (tally[i]!=0)
4819 MapDebug(" %4ld %4ld\n",i,tally[i]);
4820 for (i=246;i<=255;i++)
4821 if (tally[i]!=0)
4822 MapDebug(" %4ld %4ld\n",i,tally[i]);
4823 for (i=260;i<=273;i++)
4824 if (tally[i]!=0)
4825 MapDebug(" %4ld %4ld\n",i,tally[i]);
4826 for (i=282;i<=284;i++)
4827 if (tally[i]!=0)
4828 MapDebug(" %4ld %4ld\n",i,tally[i]);
4829 }
4830
4831 //***************************************************************************
4832 //
4833 // GetSongForLevel - returns song to play for current level
4834 //
4835 //***************************************************************************
GetSongForLevel(void)4836 int GetSongForLevel ( void )
4837 {
4838 int i;
4839 int num;
4840
4841 for (i=0;i<mapwidth;i++)
4842 {
4843 num = MAPSPOT(i,0,2);
4844 if ( (num>>8) == 0xba )
4845 return (num&0xff);
4846 }
4847 // Error("GetSongForLevel: could not find song in level %ld\n",gamestate.mapon);
4848 // return -1;
4849 return 0;
4850 }
4851
4852 /*
4853 ==================
4854 =
4855 = DoSharewareConversionBackgroundPlane
4856 =
4857 ==================
4858 */
DoSharewareConversionBackgroundPlane(void)4859 void DoSharewareConversionBackgroundPlane (void)
4860 {
4861 int i,j;
4862 word * map;
4863
4864
4865 for (j=0;j<mapheight;j++)
4866 {
4867 for(i=0;i<mapwidth;i++)
4868 {
4869 map=&(mapplanes[0][MAPSIZE*(j)+(i)]);
4870 switch (*map)
4871 {
4872
4873 // Tom Face
4874 case 45:
4875 *map=44;
4876 break;
4877 // Doors
4878 case 90:
4879 case 92:
4880 case 93:
4881 case 98:
4882 case 99:
4883 case 100:
4884 *map=91;
4885 break;
4886 case 103:
4887 case 104:
4888 *map=101;
4889 break;
4890 case 154:
4891 *map=33;
4892 break;
4893 case 155:
4894 *map=34;
4895 break;
4896 case 156:
4897 *map=35;
4898 break;
4899
4900 //locked doors
4901 case 94:
4902 *map = 101;
4903 *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=29;
4904 break;
4905 case 95:
4906 *map = 101;
4907 *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=30;
4908 break;
4909 case 96:
4910 *map = 101;
4911 *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=31;
4912 break;
4913 case 97:
4914 *map = 101;
4915 *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=32;
4916 break;
4917 // Tall pillar
4918 case 161:
4919 *map=0;
4920 break;
4921 // Masked Walls
4922 case 162:
4923 case 166:
4924 *map=164;
4925 break;
4926 case 163:
4927 case 167:
4928 case 170:
4929 case 171:
4930 *map=165;
4931 break;
4932
4933 // Floors and Ceilings
4934 case 180:
4935 case 183:
4936 case 184:
4937 *map=181;
4938 break;
4939 case 198:
4940 case 201:
4941 case 202:
4942 *map=199;
4943 break;
4944 case 188:
4945 *map=187;
4946 break;
4947 case 206:
4948 *map=205;
4949 break;
4950 case 190:
4951 *map=191;
4952 break;
4953 case 208:
4954 *map=209;
4955 break;
4956 case 192:
4957 case 193:
4958 case 194:
4959 case 195:
4960 *map=189;
4961 break;
4962 case 210:
4963 case 211:
4964 case 212:
4965 case 213:
4966 *map=207;
4967 break;
4968 // Skys
4969 case 237:
4970 case 238:
4971 case 239:
4972 *map=234;
4973 break;
4974 // Animating walls
4975 case 107:
4976 *map=106;
4977 break;
4978 case 228:
4979 case 229:
4980 case 230:
4981 case 242:
4982 *map=21;
4983 break;
4984 case 233:
4985 *map=44;
4986 break;
4987 case 232:
4988 *map=231;
4989 break;
4990 }
4991 }
4992 }
4993 }
4994
4995
4996 /*
4997 ========================================
4998 =
4999 = DoLowMemoryConversionBackgroundPlane
5000 =
5001 ========================================
5002 */
DoLowMemoryConversionBackgroundPlane(void)5003 void DoLowMemoryConversionBackgroundPlane (void)
5004 {
5005 int i,j;
5006 word * map;
5007
5008
5009 for (j=0;j<mapheight;j++)
5010 {
5011 for(i=0;i<mapwidth;i++)
5012 {
5013 map=&(mapplanes[0][MAPSIZE*(j)+(i)]);
5014 switch (*map)
5015 {
5016 //Walls
5017
5018 case 2:
5019 case 3:
5020 case 4:
5021 *map = 1;
5022 break;
5023
5024 case 6:
5025 case 7:
5026 case 8:
5027 *map = 5;
5028 break;
5029
5030 case 14:
5031 case 15:
5032 case 16:
5033 *map = 13;
5034 break;
5035
5036 case 18:
5037 case 19:
5038 case 20:
5039 *map = 17;
5040 break;
5041
5042 case 26:
5043 case 27:
5044 case 28:
5045 *map = 25;
5046 break;
5047
5048 case 30:
5049 case 31:
5050 case 32:
5051 *map = 29;
5052 break;
5053
5054 #if 0
5055 case 37:
5056 case 38:
5057 case 39:
5058 *map = 36;
5059 break;
5060
5061 case 41:
5062 case 42:
5063 case 43:
5064 *map = 40;
5065 break;
5066 #endif
5067
5068 case 50:
5069 case 51:
5070 case 52:
5071 *map = 49;
5072 break;
5073
5074 #if 0
5075 case 55:
5076 case 56:
5077 case 57:
5078 *map = 54;
5079 break;
5080
5081 case 59:
5082 case 60:
5083 case 61:
5084 *map = 58;
5085 break;
5086 #endif
5087
5088 case 66:
5089 case 67:
5090 case 68:
5091 *map = 65;
5092 break;
5093
5094 case 70:
5095 case 71:
5096 *map = 69;
5097 break;
5098
5099 case 81:
5100 case 82:
5101 case 84:
5102 *map = 83;
5103 break;
5104
5105 // Masked Walls
5106 case 158:
5107 case 159:
5108 case 160:
5109 case 168:
5110 case 169:
5111 case 176:
5112 case 178:
5113 *map=177;
5114 break;
5115 case 162:
5116 case 163:
5117 case 164:
5118 case 166:
5119 case 167:
5120 *map=165;
5121 break;
5122
5123 //Doors
5124 case 90:
5125 case 91:
5126 case 92:
5127 case 93:
5128 case 98:
5129 case 99:
5130 case 100:
5131 case 101:
5132 case 103:
5133 case 104:
5134 case 33:
5135 case 34:
5136 case 35:
5137 case 154:
5138 case 155:
5139 case 156:
5140 *map = 101;
5141 break;
5142
5143 //Animating Walls
5144 case 22:
5145 case 23:
5146 case 24:
5147 case 228:
5148 case 229:
5149 case 230:
5150 case 231:
5151 case 232:
5152 case 242:
5153 case 243:
5154 case 244:
5155 *map = 21;
5156 break;
5157 case 233:
5158 *map = 44;
5159 break;
5160
5161 #if 0
5162 //Skys
5163 case 234:
5164 case 235:
5165 case 236:
5166 case 237:
5167 case 238:
5168 case 239:
5169 *map=(*(&(mapplanes[0][MAPSIZE*(0)+(0)]))) + 18;
5170 break;
5171 #endif
5172 }
5173 }
5174 }
5175 }
5176
5177
5178 /*
5179 ========================================
5180 =
5181 = DoLowMemoryConversionIconPlane
5182 =
5183 ========================================
5184 */
DoLowMemoryConversionIconPlane(void)5185 void DoLowMemoryConversionIconPlane (void)
5186 {
5187 #if 0
5188 int i,j;
5189 word * map;
5190
5191
5192 for (j=0;j<mapheight;j++)
5193 {
5194 for(i=0;i<mapwidth;i++)
5195 {
5196 map=&(mapplanes[2][MAPSIZE*(j)+(i)]);
5197 switch (*map)
5198 {
5199 case 13:
5200 *(&(mapplanes[0][MAPSIZE*(j)+(i)]))=21;
5201 *map=0;
5202 break;
5203 }
5204 }
5205 }
5206 #endif
5207 }
5208
5209
5210
5211 /*
5212 ========================================
5213 =
5214 = DoLowMemoryConversionForegroundPlane
5215 =
5216 ========================================
5217 */
5218
DoLowMemoryConversionForegroundPlane(void)5219 void DoLowMemoryConversionForegroundPlane (void)
5220 {
5221 int i,j;
5222 word * map;
5223
5224
5225 for (j=0;j<mapheight;j++)
5226 {
5227 for(i=0;i<mapwidth;i++)
5228 {
5229 map=&MAPSPOT(i,j,1);
5230 switch (*map)
5231 {
5232 // light sourcing
5233 case 139:
5234 *map=0;
5235 break;
5236
5237 //sprites
5238 case 42:
5239 case 43:
5240 case 63:
5241 case 64:
5242 *map = 43;
5243 break;
5244
5245 case 246:
5246 case 247:
5247 case 248:
5248 case 264:
5249 case 265:
5250 case 267:
5251 case 283:
5252 *map = 266;
5253 break;
5254
5255 //lightning
5256 case 377:
5257 *map = 0;
5258 break;
5259
5260 // actor guards
5261
5262 // normal low guards
5263 case 108:
5264 case 109:
5265 case 110:
5266 case 111:
5267 case 112:
5268 case 113:
5269 case 114:
5270 case 115:
5271 case 116:
5272 case 117:
5273 case 118:
5274 case 119:
5275
5276 case 126:
5277 case 127:
5278 case 128:
5279 case 129:
5280 case 130:
5281 case 131:
5282 case 132:
5283 case 133:
5284 case 134:
5285 case 135:
5286 case 136:
5287 case 137:
5288 (*map)+=216;
5289 break;
5290
5291 // sneaky low guards
5292 case 120:
5293 case 138:
5294 *map = 0;
5295 break;
5296
5297 // normal over patrol
5298 case 216:
5299 case 217:
5300 case 218:
5301 case 219:
5302 case 220:
5303 case 221:
5304 case 222:
5305 case 223:
5306 case 224:
5307 case 225:
5308 case 226:
5309 case 227:
5310
5311
5312 case 234:
5313 case 235:
5314 case 236:
5315 case 237:
5316 case 238:
5317 case 239:
5318 case 240:
5319 case 241:
5320 case 242:
5321 case 243:
5322 case 244:
5323 case 245:
5324 (*map)-=36;
5325 break;
5326
5327 //environment dangers
5328
5329 #if (SHAREWARE==0)
5330 case 412: //spears to firejets
5331 *map = 372;
5332 break;
5333
5334 case 430:
5335 *map = 390;
5336 break;
5337
5338 case 413: //cylinders down to firejets
5339 *map = 372;
5340 break;
5341 #endif
5342
5343 case 156:
5344 case 157:
5345 *map = 372; //spinblade stabbers to firejets
5346 break;
5347
5348 case 174:
5349 case 175:
5350 *map = 390;
5351 break;
5352
5353 case 301: // directional spin blades
5354 *map = 373;
5355 break;
5356
5357 case 319: // directional spin blades
5358 *map = 374;
5359 break;
5360
5361 case 337: // directional spin blades
5362 *map = 375;
5363 break;
5364
5365 case 355: // directional spin blades
5366 *map = 376;
5367 break;
5368
5369 case 302: // directional spin blades
5370 *map = 391;
5371 break;
5372
5373 case 320: // directional spin blades
5374 *map = 392;
5375 break;
5376
5377 case 338: // directional spin blades
5378 *map = 393;
5379 break;
5380
5381 case 356: // directional spin blades
5382 *map = 394;
5383 break;
5384
5385 case 194: // directional emplacements to four-way
5386 case 195: // easy
5387 case 196:
5388 case 197:
5389 *map = 89;
5390 break;
5391
5392 case 212: // hard
5393 case 213:
5394 case 214:
5395 case 215:
5396 *map = 211;
5397 break;
5398
5399 }
5400 }
5401 }
5402 }
5403
5404
5405 /*
5406 ==================
5407 =
5408 = DoSharewareConversionForegroundPlane
5409 =
5410 ==================
5411 */
DoSharewareConversionForegroundPlane(void)5412 void DoSharewareConversionForegroundPlane (void)
5413 {
5414 int i,j;
5415 word * map;
5416
5417
5418 for (j=0;j<mapheight;j++)
5419 {
5420 for(i=0;i<mapwidth;i++)
5421 {
5422 map=&(mapplanes[1][MAPSIZE*(j)+(i)]);
5423 switch (*map)
5424 {
5425 case 32: // Crystal Key
5426 case 47: // Knife
5427 case 65: // DIP BALL D
5428 case 66: // DIP BALL I
5429 case 67: // DIP BALL P
5430 case 99: // Boss
5431 case 100: // Boss
5432 case 101: // Boss
5433 case 102: // Boss
5434 case 103: // Boss
5435 case 210: // Scott's head
5436 case 278: // Boulder
5437 case 279: // Boulder
5438 case 280: // Boulder
5439 case 281: // Boulder
5440 case 395: // Boulder
5441 *map=0;
5442 break;
5443 case 41: // 3-UP to 1-UP
5444 *map=40;
5445 break;
5446 case 46: // Bat
5447 *map=50;
5448 break;
5449 case 55: // Split Missile
5450 *map=52;
5451 break;
5452 case 56: // KES
5453 *map=53;
5454 break;
5455 case 253: // Dog Mode
5456 *map=254;
5457 break;
5458 case 262: // Tom Larva
5459 *map=263;
5460 break;
5461 }
5462 }
5463 }
5464 }
5465
5466 /*
5467 ========================================
5468 =
5469 = DoRegisterConversionBackgroundPlane
5470 =
5471 ========================================
5472 */
DoRegisterConversionBackgroundPlane(void)5473 void DoRegisterConversionBackgroundPlane (void)
5474 {
5475 int i,j;
5476 word * map;
5477
5478
5479 for (j=0;j<mapheight;j++)
5480 {
5481 for(i=0;i<mapwidth;i++)
5482 {
5483 map=&(mapplanes[0][MAPSIZE*(j)+(i)]);
5484 switch (*map)
5485 {
5486 //locked doors
5487
5488 case 94:
5489 *map = 101;
5490 *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=29;
5491 break;
5492 case 95:
5493 *map = 101;
5494 *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=30;
5495 break;
5496 case 96:
5497 *map = 101;
5498 *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=31;
5499 break;
5500 case 97:
5501 *map = 101;
5502 *(&(mapplanes[1][MAPSIZE*(j)+(i)]))=32;
5503 break;
5504
5505 case 232:
5506 *map = 231; //map chains to machinery
5507 break;
5508
5509 case 228:
5510 *map = 230; //map gray water to blue water
5511 break;
5512
5513 }
5514 }
5515 }
5516 }
5517
5518
5519
5520 /*
5521 ========================================
5522 =
5523 = DoRegisterConversionForegroundPlane
5524 =
5525 ========================================
5526 */
DoRegisterConversionForegroundPlane(void)5527 void DoRegisterConversionForegroundPlane (void)
5528 {
5529 // int i,j;
5530 // word * map;
5531
5532
5533 #if 0
5534 for (j=0;j<mapheight;j++)
5535 {
5536 for(i=0;i<mapwidth;i++)
5537 {
5538 map=&MAPSPOT(i,j,1);
5539 switch (*map)
5540 {
5541 //sprites
5542 case 42:
5543 case 43:
5544 case 63:
5545 case 64:
5546 *map = 43;
5547 break;
5548
5549 }
5550 }
5551 }
5552 #endif
5553 }
5554
5555 /*
5556 ==================
5557 =
5558 = DoSharewareConversion
5559 =
5560 ==================
5561 */
DoSharewareConversion(void)5562 void DoSharewareConversion (void)
5563 {
5564 DoSharewareConversionBackgroundPlane ();
5565 DoSharewareConversionForegroundPlane ();
5566 }
5567
5568
5569 /*
5570 ==================
5571 =
5572 = DoRegisterConversion
5573 =
5574 ==================
5575 */
DoRegisterConversion(void)5576 void DoRegisterConversion (void)
5577 {
5578 DoRegisterConversionBackgroundPlane ();
5579 DoRegisterConversionForegroundPlane ();
5580 }
5581
5582 /*
5583 =======================
5584 =
5585 = DoPanicMapping
5586 =
5587 =======================
5588 */
DoPanicMapping(void)5589 boolean DoPanicMapping (void)
5590 {
5591 if ((lowmemory==true) && (modemgame==false) && (demorecord==false) && (demoplayback==false))
5592 return true;
5593 else
5594 return false;
5595 }
5596
5597 /*
5598 =======================
5599 =
5600 = DoLowMemoryConversion
5601 =
5602 =======================
5603 */
DoLowMemoryConversion(void)5604 void DoLowMemoryConversion (void)
5605 {
5606 DoLowMemoryConversionBackgroundPlane ();
5607 if ((modemgame==false) && (demorecord==false) && (demoplayback==false))
5608 DoLowMemoryConversionForegroundPlane ();
5609 DoLowMemoryConversionIconPlane ();
5610 }
5611
5612
5613
5614 /*
5615 ==================
5616 =
5617 = SetupGameLevel
5618 =
5619 ==================
5620 */
SetupGameLevel(void)5621 void SetupGameLevel (void)
5622 {
5623 int crud;
5624 int i;
5625
5626 #if 0
5627 mapwidth = mapheight = 128;
5628
5629 InsaneDump();
5630 /*
5631 for(i=0;i<11;i++)
5632 {GetEpisode(i);
5633 LoadROTTMap(i);
5634 MapDebug("\n//================================//");
5635 MapDebug("\n// SHAREWARE LEVEL %d //",i);
5636 MapDebug("\n//================================//\n\n");
5637
5638 PrintTileStats();
5639 }
5640 */
5641 Error("okay");
5642 #endif
5643
5644 insetupgame=true;
5645
5646 InitializeRNG ();
5647
5648 if ((demoplayback==true) || (demorecord==true))
5649 SetRNGindex ( 0 );
5650
5651 if (gamestate.randomseed!=-1)
5652 SetRNGindex ( gamestate.randomseed );
5653
5654 if (tedlevel)
5655 {
5656 GetEpisode (tedlevelnum);
5657 LoadROTTMap(tedlevelnum);
5658 gamestate.mapon=tedlevelnum;
5659 }
5660 else
5661 {
5662 GetEpisode (gamestate.mapon);
5663 LoadROTTMap(gamestate.mapon);
5664 }
5665 if (DoPanicMapping())
5666 {
5667 DoLowMemoryConversion();
5668 }
5669 if ( gamestate.Product == ROTT_SHAREWARE )
5670 {
5671 DoSharewareConversion ();
5672 }
5673 else
5674 {
5675 DoRegisterConversion ();
5676 }
5677 if ( (NewGame) || (lastlevelloaded!=gamestate.mapon) )
5678 {
5679 SetupPreCache();
5680 lastlevelloaded=gamestate.mapon;
5681 MU_StartSong(song_level);
5682 }
5683 shapestart = W_GetNumForName("SHAPSTRT");
5684 shapestop = W_GetNumForName("SHAPSTOP");
5685 gunsstart=W_GetNumForName("GUNSTART");
5686
5687 playstate = ex_stillplaying;
5688 SNAKELEVEL = 0;
5689 whichpath = 0;
5690
5691 InitializePlayerstates();
5692
5693 ResetCheatCodes();
5694
5695 gamestate.killtotal = gamestate.killcount = 0;
5696 gamestate.secrettotal = gamestate.secretcount = 0;
5697 gamestate.treasuretotal = gamestate.treasurecount = 0;
5698 gamestate.supertotal = gamestate.supercount = 0;
5699 gamestate.healthtotal = gamestate.healthcount = 0;
5700 gamestate.missiletotal = gamestate.missilecount = 0;
5701 gamestate.democratictotal = gamestate.democraticcount = 0;
5702 gamestate.planttotal = gamestate.plantcount = 0;
5703 gamestate.DODEMOCRATICBONUS1 = true;
5704 gamestate.DOGROUNDZEROBONUS = false;
5705
5706 if (gamestate.mapon == 30)
5707 SNAKELEVEL = 1;
5708 else if (gamestate.mapon == 32)
5709 SNAKELEVEL = 2;
5710 else if (gamestate.mapon == 33)
5711 SNAKELEVEL = 3;
5712
5713 InitAreas();
5714 InitDoorList();
5715 InitElevators();
5716 if (loadedgame==false)
5717 {
5718 InitStaticList ();
5719 InitActorList();
5720 }
5721 memset (tilemap,0,sizeof(tilemap));
5722 memset (actorat,0,sizeof(actorat));
5723 memset (sprites,0,sizeof(sprites));
5724 memset (mapseen,0,sizeof(mapseen));
5725 memset (LightsInArea,0,sizeof(LightsInArea));
5726
5727 PrintTileStats();
5728
5729 SetupLightLevels();
5730
5731 crud=(word)MAPSPOT(0,0,1);
5732 if ((crud>=90) && (crud<=97))
5733 {
5734 levelheight=crud-89;
5735 maxheight = (levelheight << 6)-32;
5736 nominalheight = maxheight-32;
5737 }
5738 else if ((crud>=450) && (crud<=457))
5739 {
5740 levelheight=crud-450+9;
5741 maxheight = (levelheight << 6)-32;
5742 nominalheight = maxheight-32;
5743 }
5744 else
5745 Error("You must specify a valid height sprite icon at (2,0) on map %ld\n",gamestate.mapon);
5746
5747 /*
5748 if ( ( BATTLEMODE ) && ( !gamestate.BattleOptions.SpawnDangers ) )
5749 {
5750 RemoveDangerWalls();
5751 }
5752 */
5753 // pheight=maxheight-32;
5754 CountAreaTiles();
5755 SetupWalls();
5756
5757 SetupClocks();
5758 SetupAnimatedWalls();
5759
5760 if (loadedgame==false)
5761 {
5762 SetupSwitches();
5763 SetupStatics ();
5764 SetupMaskedWalls();
5765 SetupDoors();
5766 SetupPushWalls();
5767 SetupPlayers();
5768 if (!BATTLEMODE)
5769 {
5770 SetupActors();
5771 SetupRandomActors();
5772 }
5773 SetupElevators();
5774 SetupDoorLinks();
5775 SetupPushWallLinks();
5776 FixDoorAreaNumbers();
5777 FixMaskedWallAreaNumbers();
5778 SetupWindows();
5779 SetupLights();
5780 SetupInanimateActors();
5781 }
5782 else {
5783 FixTiles();
5784 }
5785
5786 if (gamestate.SpawnEluder || gamestate.SpawnDeluder)
5787 {
5788 //MED
5789 for (i=0;i<25;i++)
5790 RespawnEluder();
5791 }
5792
5793
5794 if ( ( BATTLEMODE ) && ( MapSpecials & MAP_SPECIAL_TOGGLE_PUSHWALLS ) )
5795 {
5796 ActivateAllPushWalls();
5797 }
5798 Illuminate();
5799
5800 if (SNAKELEVEL == 1)
5801 SetupSnakePath();
5802
5803 LoftSprites();
5804
5805 SetPlaneViewSize();
5806 if (loadedgame==false)
5807 {
5808 ConnectAreas();
5809 #if (DEVELOPMENT == 1)
5810 #if (PRECACHETEST == 1)
5811 SoftError("Start PreCaching\n");
5812 #endif
5813 #endif
5814 #if (DEVELOPMENT == 1)
5815 PrintMapStats();
5816 #endif
5817 PreCache();
5818 #if (DEVELOPMENT == 1)
5819 #if (PRECACHETEST == 1)
5820 SoftError("Done PreCaching\n");
5821 #endif
5822 #endif
5823 SetupPlayScreen();
5824 SetupScreen(false);
5825 }
5826
5827 if (BATTLEMODE) {
5828 SetModemLightLevel ( gamestate.BattleOptions.LightLevel );
5829 }
5830
5831 if (player != NULL) {
5832 for (i=0;i<100;i++) {
5833 UpdateLightLevel(player->areanumber);
5834 }
5835 }
5836
5837 insetupgame=false;
5838
5839 tedlevel = false; // turn it off once we have done any ted stuff
5840 }
5841
5842
InitializePlayerstates(void)5843 void InitializePlayerstates(void)
5844 {int i;
5845 playertype * pstate;
5846
5847 if (NewGame || (gamestate.mapon == 0) || tedlevel)
5848 {for(i=0;i<numplayers;i++)
5849 InitializeWeapons(&PLAYERSTATE[i]);
5850 }
5851
5852 for(i=0;i<numplayers;i++)
5853 {
5854 pstate=&PLAYERSTATE[i];
5855 if (
5856 (pstate->missileweapon == wp_godhand)
5857 #if (SHAREWARE == 0)
5858 ||
5859 (pstate->missileweapon == wp_dog)
5860 #endif
5861 )
5862 {
5863 pstate->weapon=pstate->new_weapon=pstate->oldweapon;
5864 pstate->missileweapon = pstate->oldmissileweapon;
5865
5866 }
5867
5868 ResetPlayerstate(pstate);
5869 }
5870
5871 NewGame = false;
5872
5873 }
5874
5875
SetupSnakePath(void)5876 void SetupSnakePath(void)
5877 {
5878 #if (SHAREWARE == 0)
5879 int i,j;
5880 word *map,tile;
5881
5882 map = mapplanes[1];
5883
5884 for(j=0;j<mapheight;j++)
5885 for(i=0;i<mapwidth;i++)
5886 {tile = *map++;
5887 if ((tile >= 72) && (tile <= 79) && (!tilemap[i][j]))
5888 {SNAKEPATH[whichpath].x = i;
5889 SNAKEPATH[whichpath].y = j;
5890 whichpath ++;
5891 }
5892
5893 }
5894 #endif
5895 }
5896
5897
SetupRandomActors(void)5898 void SetupRandomActors(void)
5899 {int i,j;
5900 word *map,tile;
5901 int starti,totalrandom=0,count=0,ambush,locindex,orig;
5902 byte actorpresent[10]={0},index=0,randomtype,used[100]={0};
5903 _2Dpoint randloc[100];
5904
5905
5906 map = mapplanes[1];
5907 map+=5;
5908 for(i=0;i<10;i++)
5909 {if (RANDOMACTORTYPE[i])
5910 actorpresent[index++]=i;
5911 }
5912
5913
5914 if (!index)
5915 return;
5916
5917 for (j=0;j<mapheight;j++)
5918 {if (j==0)
5919 starti=5;
5920 else
5921 starti=0;
5922 for(i=starti;i<mapwidth;i++)
5923 {tile= *map++;
5924
5925 if ((tile >= 122) && (tile <= 125))
5926 {randloc[totalrandom].x = i;
5927 randloc[totalrandom].y = j;
5928 totalrandom++;
5929 if (totalrandom >= 100)
5930 Error("Max random actors (100) exceeded");
5931 }
5932
5933 }
5934 }
5935
5936 orig = totalrandom;
5937 switch(gamestate.difficulty)
5938 {
5939 case gd_baby:
5940 totalrandom = 7*totalrandom/10;
5941 break;
5942
5943 case gd_easy:
5944 totalrandom = 8*totalrandom/10;
5945 break;
5946
5947 case gd_medium:
5948 totalrandom = 9*totalrandom/10;
5949 break;
5950
5951 }
5952
5953
5954 while(count<totalrandom)
5955 { locindex = (GameRandomNumber("rand loc index",0) % orig);
5956
5957 if (!used[locindex])
5958 {randomtype = actorpresent[GameRandomNumber("SetupRandomActors",0) % index];
5959 ambush = (GameRandomNumber("rand actor",0) < 128);
5960 i = randloc[locindex].x;
5961 j = randloc[locindex].y;
5962 SpawnStand(randomtype,i,j,tile-122,ambush);
5963 used[locindex] = 1;
5964 PreCacheActor(randomtype,0);
5965 count++;
5966 }
5967 }
5968
5969 }
5970
SetupActors(void)5971 void SetupActors(void)
5972 {
5973 int i,j;
5974 word *map,tile;
5975 int starti;
5976
5977
5978 //GetRainActors();
5979
5980 map = mapplanes[1];
5981 map+=5;
5982
5983 for (j=0;j<mapheight;j++)
5984 {
5985 if (j==0)
5986 starti=5;
5987 else
5988 starti=0;
5989 for(i=starti;i<mapwidth;i++)
5990 {
5991 tile= *map++;
5992
5993 switch(tile)
5994 {
5995
5996 case 126:
5997 case 127:
5998 case 128:
5999 case 129:
6000 if (gamestate.difficulty < gd_hard)
6001 break;
6002 tile -= 18;
6003
6004 case 108:
6005 case 109:
6006 case 110:
6007 case 111:
6008 SpawnStand(lowguardobj,i,j,tile-108,0);
6009 break;
6010
6011
6012
6013
6014 case 130:
6015 case 131:
6016 case 132:
6017 case 133:
6018 if (gamestate.difficulty < gd_hard)
6019 break;
6020 tile -= 18;
6021
6022 case 112:
6023 case 113:
6024 case 114:
6025 case 115:
6026 SpawnPatrol(lowguardobj,i,j,tile-112);
6027 break;
6028
6029 case 134:
6030 case 135:
6031 case 136:
6032 case 137:
6033 if (gamestate.difficulty < gd_hard)
6034 break;
6035 tile -= 18;
6036
6037 case 116:
6038 case 117:
6039 case 118:
6040 case 119:
6041 SpawnStand(lowguardobj,i,j,tile-116,1);
6042 break;
6043
6044 case 138:
6045 if (gamestate.difficulty < gd_hard)
6046 break;
6047 tile -= 18;
6048
6049 case 120:
6050 SpawnSneaky(i,j);
6051 break;
6052
6053 case 162:
6054 case 163:
6055 case 164:
6056 case 165:
6057 if (gamestate.difficulty < gd_hard)
6058 break;
6059 tile -= 18;
6060
6061 case 144:
6062 case 145:
6063 case 146:
6064 case 147:
6065 SpawnStand(highguardobj,i,j,tile-144,0);
6066 break;
6067
6068 case 170:
6069 case 171:
6070 case 172:
6071 case 173:
6072 if (gamestate.difficulty < gd_hard)
6073 break;
6074 tile -= 18;
6075
6076 case 152:
6077 case 153:
6078 case 154:
6079 case 155:
6080 SpawnStand(highguardobj,i,j,tile-152,1);
6081 break;
6082
6083
6084
6085 case 166:
6086 case 167:
6087 case 168:
6088 case 169:
6089 if (gamestate.difficulty < gd_hard)
6090 break;
6091 tile -= 18;
6092
6093 case 148:
6094 case 149:
6095 case 150:
6096 case 151:
6097 SpawnPatrol(highguardobj,i,j,tile-148);
6098 break;
6099
6100 case 176:
6101 case 177:
6102 case 178:
6103 case 179:
6104 if (gamestate.difficulty < gd_hard)
6105 break;
6106 tile -= 18;
6107
6108 case 158:
6109 case 159:
6110 case 160:
6111 case 161:
6112 SpawnPatrol(roboguardobj,i,j,tile-158);
6113 break;
6114
6115 case 212:
6116 case 213:
6117 case 214:
6118 case 215:
6119 if (gamestate.difficulty < gd_hard)
6120 break;
6121 tile -= 18;
6122
6123 case 194:
6124 case 195:
6125 case 196:
6126 case 197:
6127 SpawnGunThingy(patrolgunobj,i,j,tile-194);
6128 break;
6129
6130 case 198:
6131 case 199:
6132 case 200:
6133 case 201:
6134 if (gamestate.difficulty < gd_hard)
6135 break;
6136 tile -= 18;
6137
6138 case 180:
6139 case 181:
6140 case 182:
6141 case 183:
6142 SpawnStand(strikeguardobj,i,j,tile-180,0);
6143 break;
6144
6145 case 206:
6146 case 207:
6147 case 208:
6148 case 209:
6149 if (gamestate.difficulty < gd_hard)
6150 break;
6151 tile -= 18;
6152
6153 case 188:
6154 case 189:
6155 case 190:
6156 case 191:
6157 SpawnStand(strikeguardobj,i,j,tile-188,1);
6158 break;
6159
6160 case 202:
6161 case 203:
6162 case 204:
6163 case 205:
6164 if (gamestate.difficulty < gd_hard)
6165 break;
6166 tile -= 18;
6167
6168 case 184:
6169 case 185:
6170 case 186:
6171 case 187:
6172 SpawnPatrol(strikeguardobj,i,j,tile-184);
6173 break;
6174
6175 case 234:
6176 case 235:
6177 case 236:
6178 case 237:
6179 if (gamestate.difficulty < gd_hard)
6180 break;
6181 tile -= 18;
6182
6183 case 216:
6184 case 217:
6185 case 218:
6186 case 219:
6187 SpawnStand(overpatrolobj,i,j,tile-216,0);
6188 break;
6189
6190 case 242:
6191 case 243:
6192 case 244:
6193 case 245:
6194 if (gamestate.difficulty < gd_hard)
6195 break;
6196 tile -= 18;
6197
6198 case 224:
6199 case 225:
6200 case 226:
6201 case 227:
6202 SpawnStand(overpatrolobj,i,j,tile-224,1);
6203 break;
6204
6205 case 238:
6206 case 239:
6207 case 240:
6208 case 241:
6209 if (gamestate.difficulty < gd_hard)
6210 break;
6211 tile -= 18;
6212
6213 case 220:
6214 case 221:
6215 case 222:
6216 case 223:
6217 SpawnPatrol(overpatrolobj,i,j,tile-220);
6218 break;
6219 case 306:
6220 case 307:
6221 case 308:
6222 case 309:
6223 if (gamestate.difficulty < gd_hard)
6224 break;
6225 tile -= 18;
6226
6227 case 288:
6228 case 289:
6229 case 290:
6230 case 291:
6231 SpawnStand(triadenforcerobj,i,j,tile-288,0);
6232 break;
6233
6234 case 314:
6235 case 315:
6236 case 316:
6237 case 317:
6238 if (gamestate.difficulty < gd_hard)
6239 break;
6240 tile -= 18;
6241
6242 case 296:
6243 case 297:
6244 case 298:
6245 case 299:
6246 SpawnStand(triadenforcerobj,i,j,tile-296,1);
6247 break;
6248
6249 case 310:
6250 case 311:
6251 case 312:
6252 case 313:
6253 if (gamestate.difficulty < gd_hard)
6254 break;
6255 tile -= 18;
6256
6257 case 292:
6258 case 293:
6259 case 294:
6260 case 295:
6261 SpawnPatrol(triadenforcerobj,i,j,tile-292);
6262 break;
6263
6264 case 342:
6265 case 343:
6266 case 344:
6267 case 345:
6268 if (gamestate.difficulty < gd_hard)
6269 break;
6270 tile -= 18;
6271
6272 case 324:
6273 case 325:
6274 case 326:
6275 case 327:
6276 SpawnStand(blitzguardobj,i,j,tile-324,0);
6277 break;
6278
6279 case 350:
6280 case 351:
6281 case 352:
6282 case 353:
6283 if (gamestate.difficulty < gd_hard)
6284 break;
6285 tile -= 18;
6286
6287 case 332:
6288 case 333:
6289 case 334:
6290 case 335:
6291 SpawnStand(blitzguardobj,i,j,tile-332,1);
6292 break;
6293
6294 case 346:
6295 case 347:
6296 case 348:
6297 case 349:
6298 if (gamestate.difficulty < gd_hard)
6299 break;
6300 tile -= 18;
6301 case 328:
6302 case 329:
6303 case 330:
6304 case 331:
6305 SpawnPatrol(blitzguardobj,i,j,tile-328);
6306 break;
6307
6308 case 378:
6309 case 379:
6310 case 380:
6311 case 381:
6312 if (gamestate.difficulty < gd_hard)
6313 break;
6314 tile -= 18;
6315
6316 case 360:
6317 case 361:
6318 case 362:
6319 case 363:
6320 SpawnStand(deathmonkobj,i,j,tile-360,0);
6321 break;
6322
6323 case 386:
6324 case 387:
6325 case 388:
6326 case 389:
6327 if (gamestate.difficulty < gd_hard)
6328 break;
6329 tile -= 18;
6330
6331 case 368:
6332 case 369:
6333 case 370:
6334 case 371:
6335 SpawnStand(deathmonkobj,i,j,tile-368,1);
6336 break;
6337
6338 case 382:
6339 case 383:
6340 case 384:
6341 case 385:
6342 if (gamestate.difficulty < gd_hard)
6343 break;
6344 tile -= 18;
6345
6346 case 364:
6347 case 365:
6348 case 366:
6349 case 367:
6350 SpawnPatrol(deathmonkobj,i,j,tile-364);
6351 break;
6352
6353 case 414:
6354 case 415:
6355 case 416:
6356 case 417:
6357 if (gamestate.difficulty < gd_hard)
6358 break;
6359 tile -= 18;
6360
6361 case 396:
6362 case 397:
6363 case 398:
6364 case 399:
6365 SpawnStand(dfiremonkobj,i,j,tile-396,0);
6366 break;
6367
6368
6369
6370 case 422:
6371 case 423:
6372 case 424:
6373 case 425:
6374 if (gamestate.difficulty < gd_hard)
6375 break;
6376 tile -= 18;
6377
6378
6379 case 404:
6380 case 405:
6381 case 406:
6382 case 407:
6383 SpawnStand(dfiremonkobj,i,j,tile-404,1);
6384 break;
6385
6386 case 418:
6387 case 419:
6388 case 420:
6389 case 421:
6390 if (gamestate.difficulty < gd_hard)
6391 break;
6392 tile -= 18;
6393
6394 case 400:
6395 case 401:
6396 case 402:
6397 case 403:
6398 SpawnPatrol(dfiremonkobj,i,j,tile-400);
6399 break;
6400
6401 case 99:
6402 SpawnStand(b_darianobj,i,j,tile-99,0);
6403 break;
6404 case 100:
6405 SpawnStand(b_heinrichobj,i,j,tile-100,0);
6406 break;
6407 case 101:
6408 SpawnStand(b_darkmonkobj,i,j,tile-101,0);
6409 MISCVARS->TOMLOC.x = i;
6410 MISCVARS->TOMLOC.y = j;
6411 break;
6412 case 102:
6413 SpawnMultiSpriteActor(b_robobossobj,i,j,tile-102);
6414 break;
6415
6416 case 103:
6417 SpawnSnake(i,j);
6418 break;
6419
6420 case 426:
6421 case 427:
6422 case 428:
6423 case 429:
6424 if (gamestate.difficulty < gd_hard)
6425 break;
6426 tile -= 18;
6427
6428 case 408:
6429 case 409:
6430 case 410:
6431 case 411:
6432 SpawnPatrol(wallopobj,i,j,tile-408);
6433 break;
6434
6435
6436 }
6437 }
6438 }
6439 }
6440
SetupStatics(void)6441 void SetupStatics(void)
6442 {
6443 int i,j,spawnz;
6444 word *map,tile;
6445 int starti;
6446
6447 map = mapplanes[1];
6448 map+=5;
6449
6450 BATTLE_NumCollectorItems = 0;
6451 for (j=0;j<mapheight;j++)
6452 {
6453 if (j==0)
6454 starti=5;
6455 else
6456 starti=0;
6457 for(i=starti;i<mapwidth;i++)
6458 {
6459 tile= *map++;
6460 spawnz = (MAPSPOT(i,j,2))?(MAPSPOT(i,j,2)):(-1);
6461
6462 if ( gamestate.BattleOptions.RandomWeapons )
6463 {
6464 int num;
6465
6466 switch( tile )
6467 {
6468 case 46:
6469 case 48:
6470 case 49:
6471 case 50:
6472 case 51:
6473 case 52:
6474 case 53:
6475 case 54:
6476 case 55:
6477 case 56:
6478 if ( gamestate.Product == ROTT_SHAREWARE )
6479 {
6480 num = ( GameRandomNumber( "Random Weapon", 0 ) % 7 );
6481 tile = SharewareWeaponTiles[ num ];
6482 }
6483 else
6484 {
6485 num = ( GameRandomNumber( "Random Weapon", 1 ) % 10 );
6486 tile = NormalWeaponTiles[ num ];
6487 }
6488 break;
6489 }
6490 }
6491
6492 switch (tile)
6493 {
6494
6495 // Add light sourcing to these objects
6496
6497 case 23:
6498 case 24:
6499 case 25:
6500 case 26:
6501 case 27:
6502 case 28:
6503 case 42:
6504 case 43:
6505 case 63:
6506 case 64:
6507 SpawnStatic(i,j,tile-23,spawnz);
6508 break;
6509
6510 case 44:
6511 SpawnStatic(i,j,tile-23,spawnz);
6512 if (loadedgame == false)
6513 {
6514 gamestate.healthtotal ++;
6515 gamestate.democratictotal ++;
6516 }
6517 break;
6518
6519
6520 case 36:
6521 case 37:
6522 case 38:
6523 case 39:
6524 SpawnStatic(i,j,tile-23,spawnz);
6525 if (loadedgame == false)
6526 gamestate.healthtotal ++;
6527 break;
6528
6529 case 29:
6530 case 30:
6531 case 31:
6532 case 32:
6533 if (IsDoor (i, j) == 0)
6534 {
6535 if ( BATTLEMODE )
6536 {
6537 // Spawn empty table
6538 SpawnStatic( i, j, 247 - 246 + 57, spawnz );
6539 }
6540 else
6541 {
6542 // Spawn key table
6543 SpawnStatic( i, j, tile - 23, spawnz );
6544 }
6545 }
6546 break;
6547
6548 case 33:
6549 case 34:
6550 case 35:
6551 case 40:
6552 case 41:
6553 case 45:
6554 SpawnStatic(i,j,tile-23,spawnz);
6555 break;
6556
6557 case 46:
6558 #if (SHAREWARE == 1)
6559 Error("\n tried to spawn excalibat at %d,%d in shareware !",i,j);
6560 #endif
6561
6562
6563 SD_PreCacheSoundGroup(SD_EXCALIBOUNCESND,SD_EXCALIBLASTSND);
6564
6565
6566 PreCacheGroup(W_GetNumForName("EXBAT1"),
6567 W_GetNumForName("EXBAT7"));
6568
6569
6570
6571 SpawnStatic(i,j,tile-23,spawnz);
6572 if (loadedgame == false)
6573 gamestate.missiletotal ++;
6574 break;
6575 case 47:
6576 PreCacheGroup(W_GetNumForName("KNIFE1"),
6577 W_GetNumForName("KNIFE10"));
6578 PreCacheGroup(W_GetNumForName("ESTATUE1"),
6579 W_GetNumForName("ESTATUE8"));
6580
6581 SpawnStatic(i,j,tile-23,spawnz);
6582 break;
6583
6584 case 48:
6585 SD_PreCacheSound(SD_ATKTWOPISTOLSND);
6586
6587 if ((locplayerstate->player == 1) || (locplayerstate->player == 3))
6588 PreCacheGroup(W_GetNumForName("RFPIST1"),
6589 W_GetNumForName("LFPIST3"));
6590
6591 else if (locplayerstate->player == 2)
6592 PreCacheGroup(W_GetNumForName("RBMPIST1"),
6593 W_GetNumForName("LBMPIST3"));
6594
6595 else
6596 PreCacheGroup(W_GetNumForName("RMPIST1"),
6597 W_GetNumForName("LMPIST3"));
6598
6599 SpawnStatic(i,j,tile-23,spawnz);
6600
6601 break;
6602 case 49:
6603
6604 SD_PreCacheSound(SD_ATKMP40SND);
6605 PreCacheGroup(W_GetNumForName("MP401"),
6606 W_GetNumForName("MP403"));
6607 SpawnStatic(i,j,tile-23,spawnz);
6608 break;
6609
6610 case 50:
6611 SD_PreCacheSound(SD_MISSILEHITSND);
6612 SD_PreCacheSound(SD_MISSILEFLYSND);
6613 SD_PreCacheSound(SD_BAZOOKAFIRESND);
6614 PreCacheGroup(W_GetNumForName("BAZOOKA1"),
6615 W_GetNumForName("BAZOOKA4"));
6616 SpawnStatic(i,j,tile-23,spawnz);
6617 if (loadedgame == false)
6618 gamestate.missiletotal ++;
6619 break;
6620 case 51:
6621
6622
6623 SD_PreCacheSound(SD_MISSILEHITSND);
6624 SD_PreCacheSound(SD_MISSILEFLYSND);
6625 SD_PreCacheSound(SD_FIREBOMBFIRESND);
6626 PreCacheGroup(W_GetNumForName("FBOMB1"),
6627 W_GetNumForName("FBOMB4"));
6628 SpawnStatic(i,j,tile-23,spawnz);
6629 if (loadedgame == false)
6630 gamestate.missiletotal ++;
6631 break;
6632 case 52:
6633 SD_PreCacheSound(SD_MISSILEHITSND);
6634 SD_PreCacheSound(SD_MISSILEFLYSND);
6635 SD_PreCacheSound(SD_HEATSEEKFIRESND);
6636 PreCacheGroup(W_GetNumForName("HSEEK1"),
6637 W_GetNumForName("HSEEK4"));
6638 SpawnStatic(i,j,tile-23,spawnz);
6639 if (loadedgame == false)
6640 gamestate.missiletotal ++;
6641 break;
6642 case 53:
6643 SD_PreCacheSound(SD_MISSILEHITSND);
6644 SD_PreCacheSound(SD_MISSILEFLYSND);
6645 SD_PreCacheSound(SD_DRUNKFIRESND);
6646 PreCacheGroup(W_GetNumForName("DRUNK1"),
6647 W_GetNumForName("DRUNK4"));
6648 SpawnStatic(i,j,tile-23,spawnz);
6649 if (loadedgame == false)
6650 gamestate.missiletotal ++;
6651 break;
6652 case 54:
6653 SD_PreCacheSound(SD_MISSILEHITSND);
6654 SD_PreCacheSound(SD_MISSILEFLYSND);
6655 SD_PreCacheSound(SD_FLAMEWALLFIRESND);
6656 SD_PreCacheSound(SD_FLAMEWALLSND);
6657 PreCacheGroup(W_GetNumForName("FIREW1"),
6658 W_GetNumForName("FIREW3"));
6659 PreCacheGroup(W_GetNumForName("FWALL1"),
6660 W_GetNumForName("FWALL15"));
6661 PreCacheGroup(W_GetNumForName("SKEL1"),
6662 W_GetNumForName("SKEL48"));
6663 SpawnStatic(i,j,tile-23,spawnz);
6664 if (loadedgame == false)
6665 gamestate.missiletotal ++;
6666 break;
6667 case 55:
6668 #if (SHAREWARE == 1)
6669 Error("\n tried to spawn split missile at %d,%d in shareware !",i,j);
6670 #endif
6671 SD_PreCacheSound(SD_MISSILEHITSND);
6672 SD_PreCacheSound(SD_MISSILEFLYSND);
6673 SD_PreCacheSound(SD_SPLITFIRESND);
6674 SD_PreCacheSound(SD_SPLITSND);
6675 PreCacheGroup(W_GetNumForName("SPLIT1"),
6676 W_GetNumForName("SPLIT4"));
6677 SpawnStatic(i,j,tile-23,spawnz);
6678 if (loadedgame == false)
6679 gamestate.missiletotal ++;
6680 break;
6681 case 56:
6682 #if (SHAREWARE == 1)
6683 Error("\n tried to spawn kes at %d,%d in shareware !",i,j);
6684 #endif
6685
6686
6687
6688 SD_PreCacheSound(SD_GRAVSND);
6689 SD_PreCacheSound(SD_GRAVHITSND);
6690 SD_PreCacheSound(SD_GRAVFIRESND);
6691 SD_PreCacheSound(SD_GRAVBUILDSND);
6692
6693 PreCacheGroup(W_GetNumForName("KES1"),
6694 W_GetNumForName("KES6"));
6695 PreCacheGroup(W_GetNumForName("KSPHERE1"),
6696 W_GetNumForName("KSPHERE4"));
6697 SpawnStatic(i,j,tile-23,spawnz);
6698 if (loadedgame == false)
6699 gamestate.missiletotal ++;
6700 break;
6701
6702 case 57:
6703 case 58:
6704 case 59:
6705 case 60:
6706 case 61:
6707 case 62:
6708 case 65:
6709 case 66:
6710 case 67:
6711 SpawnStatic(i,j,tile-23,spawnz);
6712 break;
6713
6714 case 68:
6715 case 69:
6716 case 70:
6717 case 71:
6718 SpawnStatic(i,j,tile-23,spawnz);
6719 break;
6720
6721 case 98:
6722 SpawnStatic(i,j,tile-98+49,spawnz);
6723 break;
6724
6725 case 210:
6726 SpawnStatic(i,j,stat_scotthead,spawnz);
6727 break;
6728
6729 case 228:
6730 case 229:
6731 case 230:
6732 case 231:
6733 case 232:
6734 case 233:
6735 SpawnStatic(i,j,tile-228+51,spawnz);
6736 break;
6737 case 246:
6738 case 247:
6739 case 248:
6740 case 249:
6741 case 250:
6742 case 251:
6743 SpawnStatic(i,j,tile-246+57,spawnz);
6744 break;
6745 case 264:
6746 case 265:
6747 SpawnStatic(i,j,tile-264+63,spawnz);
6748 gamestate.planttotal ++;
6749 break;
6750
6751 case 266:
6752 SpawnStatic(i,j,stat_urn,spawnz);
6753 break;
6754
6755 case 268:
6756 SpawnStatic(i,j,tile-265+63,spawnz);
6757 break;
6758
6759 case 269:
6760 SpawnStatic(i,j,tile-265+63,spawnz);
6761 break;
6762
6763 case 267:
6764 SpawnStatic(i,j,stat_emptystatue,spawnz);
6765 break;
6766
6767 case 282:
6768 SpawnStatic(i,j,stat_heatgrate,spawnz);
6769 break;
6770
6771 case 283:
6772 SpawnStatic(i,j,stat_standardpole,spawnz);
6773 break;
6774
6775 case 284:
6776 if ( !BATTLEMODE )
6777 {
6778 SpawnStatic(i,j,stat_pit,spawnz);
6779 }
6780 break;
6781
6782
6783
6784
6785 case 252:
6786 SD_PreCacheSound(SD_GRAVSND);
6787 SD_PreCacheSound(SD_GRAVHITSND);
6788 SD_PreCacheSoundGroup(SD_GODMODEFIRESND,SD_LOSEMODESND);
6789 if ((locplayerstate->player == 1) || (locplayerstate->player ==3))
6790 SD_PreCacheSound(SD_GODWOMANSND);
6791 else
6792 SD_PreCacheSound(SD_GODMANSND);
6793
6794
6795 PreCacheGroup(W_GetNumForName("GODHAND1"),
6796 W_GetNumForName("GODHAND8"));
6797
6798 PreCacheGroup(W_GetNumForName("VAPO1"),
6799 W_GetNumForName("LITSOUL"));
6800
6801 PreCacheGroup(W_GetNumForName("GODFIRE1"),
6802 W_GetNumForName("GODFIRE4"));
6803
6804 SpawnStatic(i,j,stat_godmode,spawnz);
6805 if (loadedgame == false)
6806 gamestate.supertotal ++;
6807 break;
6808
6809 case 253:
6810
6811 #if (SHAREWARE == 1)
6812 Error("DogMode Power up in shareware at x=%ld y=%ld\n",i,j);
6813 #endif
6814
6815 SD_PreCacheSoundGroup(SD_DOGMODEPANTSND,SD_DOGMODELICKSND);
6816 if ((locplayerstate->player == 1) || (locplayerstate->player ==3))
6817 SD_PreCacheSound(SD_DOGWOMANSND);
6818 else
6819 SD_PreCacheSound(SD_DOGMANSND);
6820
6821
6822
6823 PreCacheGroup(W_GetNumForName("DOGNOSE1"),
6824 W_GetNumForName("DOGPAW4"));
6825 SpawnStatic(i,j,stat_dogmode,spawnz);
6826 if (loadedgame == false)
6827 gamestate.supertotal ++;
6828 break;
6829
6830 case 254:
6831 SpawnStatic(i,j,stat_fleetfeet,spawnz);
6832 if (loadedgame == false)
6833 gamestate.supertotal ++;
6834 break;
6835
6836 case 255:
6837 SpawnStatic(i,j,stat_random,spawnz);
6838 if (loadedgame == false)
6839 gamestate.supertotal ++;
6840 break;
6841
6842 case 260:
6843 SpawnStatic(i,j,stat_elastic,spawnz);
6844 if (loadedgame == false)
6845 gamestate.supertotal ++;
6846 break;
6847
6848 case 261:
6849 SpawnStatic(i,j,stat_mushroom,spawnz);
6850 if (loadedgame == false)
6851 {
6852 gamestate.supertotal ++;
6853 gamestate.democratictotal ++;
6854 }
6855 break;
6856
6857
6858 case 262:
6859 SpawnStatic(i,j,stat_tomlarva,spawnz);
6860 break;
6861
6862 case 263:
6863 if (gamestate.SpawnCollectItems)
6864 {
6865 SpawnStatic(i,j,stat_collector,spawnz);
6866 LASTSTAT->flags |= FL_COLORED;
6867 LASTSTAT->hitpoints =
6868 ( GameRandomNumber("colors",0) % MAXPLAYERCOLORS );
6869 BATTLE_NumCollectorItems++;
6870 }
6871 break;
6872
6873 case 270:
6874 SpawnStatic(i,j,stat_bulletproof,spawnz);
6875 if (loadedgame == false)
6876 gamestate.supertotal ++;
6877 break;
6878 case 271:
6879 SpawnStatic(i,j,stat_asbesto,spawnz);
6880 if (loadedgame == false)
6881 gamestate.supertotal ++;
6882 break;
6883 case 272:
6884 SpawnStatic(i,j,stat_gasmask,spawnz);
6885 if (loadedgame == false)
6886 gamestate.supertotal ++;
6887 break;
6888 case 461:
6889 SpawnStatic(i,j,stat_disk,spawnz);
6890 break;
6891 }
6892 }
6893 }
6894 }
6895
6896
6897
RaiseSprites(int x,int y,int count,int dir)6898 void RaiseSprites( int x, int y, int count, int dir )
6899 {
6900 int a,c;
6901 int dx,dy;
6902 int h;
6903 int i;
6904 int xx;
6905 int hc;
6906 int d;
6907
6908 dx=0;
6909 dy=0;
6910 if (dir==1)
6911 dx=1;
6912 else
6913 dy=1;
6914
6915
6916 if (((statobj_t *)sprites[x][y])->z==-65)
6917 {
6918 c=(maxheight+20)<<8;
6919 hc=(count+1)<<7;
6920 a=(c<<8)/(hc*hc);
6921 for (i=0;i<count;i++)
6922 {
6923 xx=-hc+((i+1)<<8);
6924 h=(c-FixedMulShift(a,(xx*xx),8) )>>8;
6925 ((statobj_t *)sprites[x+(dx*i)][y+(dy*i)])->z=maxheight-h;
6926 }
6927 }
6928 else
6929 {
6930 if (ActorIsSpring(x-(dx),y-(dy)))
6931 d=1;
6932 else if (ActorIsSpring(x+(dx*count),y+(dy*count)))
6933 d=0;
6934 else
6935 Error("Cannot find a spring board around a ramp ascension near x=%ld y=%ld\n",x,y);
6936
6937 hc=((maxheight+20)<<16)/(count+1);
6938 h=hc<<1;
6939 for (i=0;i<count;i++)
6940 {
6941 if (d==1)
6942 ((statobj_t *)sprites[x+(dx*i)][y+(dy*i)])->z=maxheight-(h>>16);
6943 else
6944 ((statobj_t *)sprites[x+(dx*(count-i-1))][y+(dy*(count-i-1))])->z=maxheight-(h>>16);
6945 h+=hc;
6946 }
6947 }
6948 }
6949
LoftSprites(void)6950 void LoftSprites( void )
6951 {
6952 int x,y;
6953 int count;
6954
6955 for(y=1;y<mapheight-1;y++)
6956 {
6957 for(x=1;x<mapwidth-1;x++)
6958 {
6959 if (StaticUndefined(x,y))
6960 {
6961 if (StaticUndefined(x+1,y))
6962 {
6963 count=1;
6964 while (StaticUndefined(x+count,y))
6965 count++;
6966 if (count<3)
6967 Error ("Are You kidding me? You are trying to loft <3 sprites in an arc??? \n x=%ld y=%ld\n",x,y);
6968 RaiseSprites(x,y,count,1);
6969 }
6970 else if (StaticUndefined(x,y+1))
6971 {
6972 count=1;
6973 while (StaticUndefined(x,y+count))
6974 count++;
6975 if (count<3)
6976 Error ("Are You kidding me? You are trying to loft <3 sprites??? \n x=%ld y=%ld\n",x,y);
6977 RaiseSprites(x,y,count,0);
6978 }
6979 else
6980 Error ("Sprite Lofter is confused around x=%ld y=%ld\n",x,y);
6981 }
6982 }
6983 }
6984 }
6985
6986