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