/* Copyright (C) 1994-1995 Apogee Software, Ltd. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // make sure word alignment is OFF! #include "rt_def.h" #include "rt_sound.h" #include #include #include #include #ifdef DOS #include #include #include #else #include #endif #include "states.h" #include "watcom.h" #include "rt_ted.h" #include "_rt_ted.h" #include "w_wad.h" #include "z_zone.h" #include "rt_util.h" #include "lumpy.h" #include "rt_vid.h" #include "rt_actor.h" #include "rt_stat.h" #include "rt_menu.h" #include "rt_draw.h" #include "rt_com.h" #include "rt_main.h" #include "rt_door.h" #include "rt_playr.h" #include "rt_view.h" #include "rt_str.h" #include "isr.h" #include "rt_floor.h" #include "rt_game.h" #include "rt_rand.h" #include "rt_cfg.h" #include "develop.h" #include "modexlib.h" #include "engine.h" #include "rt_debug.h" #include "rt_scale.h" #include "rt_net.h" //MED #include "memcheck.h" //======================================== // GLOBAL VARIABLES //======================================== extern boolean UseBaseMarker; teamtype TEAM[MAXPLAYERS]; int numareatiles[NUMAREAS+1]; int shapestart,shapestop; _2dvec SPAWNLOC[MAXSPAWNLOCATIONS],FIRST,SECOND; int NUMSPAWNLOCATIONS,numteams=0; wall_t walls[MAXWALLTILES]; str_clock Clocks[MAXCLOCKS]; int numclocks; int LightsInArea[NUMAREAS+1]; int maxheight; int nominalheight; int elevatorstart; int gunsstart; int fog; int lightsource; int SNAKELEVEL; int whichpath; word *mapplanes[3]; int mapwidth; int mapheight; int lastlevelloaded=-1; boolean insetupgame; boolean ISRTL = false; unsigned MapSpecials = 0; char LevelName[80]; //======================================== // LOCAL VARIABLES //======================================== static cachetype * cachelist; static word cacheindex; static boolean CachingStarted=false; static char * ROTTMAPS = STANDARDGAMELEVELS; static char * BATTMAPS = STANDARDBATTLELEVELS; static char NormalWeaponTiles[ 10 ] = { 46, 48, 49, 50, 51, 52, 53, 54, 55, 56 }; static char SharewareWeaponTiles[ 7 ] = { 48, 49, 50, 51, 52, 53, 54 }; static char CacheStrings[MAXSILLYSTRINGS][80]= { {"Ready yourself\nfor destruction!\0\0"}, {"Here comes the enemy!\0\0"}, {"Hope you wrote\nyour will!\0\0"}, {"Did you bring your\nextra bullets?\0\0"}, {"Try not to bleed\non the rug.\0\0"}, {"Let's see...bandages,\ntape, splints,...\0\0"}, {"Couldn't we just\ntalk this over?\0\0"}, {"Cache as cache can...\0\0"}, {"You are smart.\nMake us strong.\0\0"}, {"Bleh!\0\0"}, {"I am as far\nabove you...\0\0"}, {"Just keep thinkin':\nBut it's loadin' COOL\nstuff...\0\0"}, {"Guess which line\nwill win!\0\0"}, {"Oh, no. Not again.\0\0"}, {"Wait! I'm not ready!\nToo late.\0\0"}, {"Hope this doesn't\ncrash.\0\0"}, {"Have a sandwich.\0\0"}, {"Smoke 'em if\nya got 'em...and\nif ya like cancer.\0\0"}, {"Ummmmm...\0\0"}, {"Bang! Bang! Bang!\nFreeze!\0\0"}, {"You have the right\nto...DIE.\0\0"}, {"Insert funny phrase\nhere.\0\0"}, {"Blood, bullets,\nnicely decorated\nhallways.\0\0"}, {"You are to be killed,\nnot hurt.\0\0"}, {"It's time for you to\ngo down the stairs!\0\0"}, {"This game, like,\nrules and stuff.\0\0"}, {"We get money for this!\nHa ha ha ha!\0\0"}, {"Let's not start any\nreligious wars...\0\0"}, {"I don't wanna start\nno ting...\0\0"}, {"Ah, another sacrifice!\0\0"}, {"If you were dead,\nyou'd be the\nsame thing.\0\0"}, {"This Game isn't\nhuman; it can't\nbe reasoned with!\0\0"} }; void SetupGameLevel (void); void ScanInfoPlane(void); void DrawPreCache( void ); void InitializePlayerstates(void); void SetupSnakePath(void); void SetupRandomActors(void); void SetupActors(void); void SetupStatics(void); void LoftSprites( void ); int GetLumpForTile(int tile); //======================================== /* ====================== = = SortPreCache = Sort the Precache for cachelevel precedence using a HEAPSORT = ====================== */ #define SGN(x) ((x>0) ? (1) : ((x==0) ? (0) : (-1))) /*--------------------------------------------------------------------------*/ int CompareTags(s1p,s2p) cachetype *s1p,*s2p; { // Sort according to lump if (DoPanicMapping()==true) return SGN(s1p->cachelevel-s2p->cachelevel); // Sort according to cachelevel else return SGN(s1p->lump-s2p->lump); } void SwitchCacheEntries(s1p,s2p) cachetype *s1p,*s2p; { cachetype temp; temp=*s1p; *s1p=*s2p; *s2p=temp; } void SortPreCache( void ) { hsort((char *)cachelist,cacheindex,sizeof(cachetype),&CompareTags,&SwitchCacheEntries); } //======================================== /* ====================== = = SetupPreCache = Setup the cache for pre-cacheing = ====================== */ void SetupPreCache( void ) { CachingStarted=true; cacheindex=0; cachelist=(cachetype *)SafeMalloc(MAXPRECACHE*(sizeof(cachetype))); DrawPreCache(); } /* ====================== = = ShutdownPreCache = Setup the cache for pre-cacheing = ====================== */ void ShutdownPreCache( void ) { CachingStarted=false; SafeFree((byte *)cachelist); } /* ====================== = = PreCacheLump = precache the lump and check to see if it is already tagged = ====================== */ void PreCacheLump( int lump, int level, int type ) // added type { int i; if (CachingStarted==false) return; if (!W_LumpLength(lump)) { #if (PRECACHETEST == 1) SoftError("Tried to precache a label, lump = %ld tag=%ld maskednum=%ld\n",lump, level, maskednum); #endif return; } for (i=1;iplayer*REMOTEOFFSET); end =W_GetNumForName("CASWDEAD")+(pstate->player*REMOTEOFFSET); PreCacheGroup(start,end,cache_patch_t); } } } void PreCachePlayerSound(void) { switch (locplayerstate->player) { case 0: SD_PreCacheSound(SD_PLAYERTCSND); break; case 1: SD_PreCacheSound(SD_PLAYERTBSND); break; case 2: SD_PreCacheSound(SD_PLAYERDWSND); break; case 3: SD_PreCacheSound(SD_PLAYERLNSND); break; case 4: SD_PreCacheSound(SD_PLAYERIPFSND); break; } } #define IS_ALTERNATE_ACTOR(ob) \ ((ob->shapeoffset - deathshapeoffset[ob->obclass]) > 0)\ /* ====================== = = PreCacheActor = precache the lump and check to see if it is already tagged = ====================== */ void PreCacheActor( int actor, int which ) { int start; int end; switch (actor) { case lowguardobj: if (IS_ALTERNATE_ACTOR(new)) { start = SD_LOWGUARD2SEESND; end = SD_LOWGUARD2SEE3SND; SD_PreCacheSoundGroup(start,end); start = SD_LOWGUARD2DIESND; end = SD_LOWGUARD2DIESND; SD_PreCacheSoundGroup(start,end); start = SD_LOWGUARDFIRESND; end = SD_SNEAKYSPRINGFSND; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("MARSHOO1"); end =W_GetNumForName("MNGRISE4"); //end =W_GetNumForName("MARUSE28"); } else {start = SD_LOWGUARD1SEESND; end = SD_LOWGUARD1SEE3SND; SD_PreCacheSoundGroup(start,end); start = SD_LOWGUARD1DIESND; end = SD_LOWGUARD1DIESND; SD_PreCacheSoundGroup(start,end); start = SD_LOWGUARDFIRESND; end = SD_SNEAKYSPRINGFSND; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("LWGSHOO1"); end = W_GetNumForName("SNGRISE4"); //end =W_GetNumForName("LOWUSE28"); } break; case highguardobj: start = SD_HIGHGUARD1SEESND; end = SD_HIGHGUARDDIESND; SD_PreCacheSoundGroup(start,end); if (IS_ALTERNATE_ACTOR(new)) { start=W_GetNumForName("HIGSHOO1"); end =W_GetNumForName("HIGWDEAD"); //end =W_GetNumForName("HIHUSE28"); } else { start=W_GetNumForName("HG2SHOO1"); end =W_GetNumForName("HG2WDEAD"); //end =W_GetNumForName("H2HUSE28"); } break; case overpatrolobj: start=W_GetNumForName("OBBOLO1"); end =W_GetNumForName("OBBOLO4"); PreCacheGroup(start,end,cache_patch_t); start=W_GetNumForName("NET1"); end =W_GetNumForName("NET4"); PreCacheGroup(start,end,cache_patch_t); start = SD_OVERP1SEESND; end = SD_OVERPDIESND; SD_PreCacheSoundGroup(start,end); SD_PreCacheSoundGroup(SD_NETWIGGLESND,SD_NETFALLSND); if (IS_ALTERNATE_ACTOR(new)) { start=W_GetNumForName("PATSHOO1"); end =W_GetNumForName("PATDEAD"); //end =W_GetNumForName("OBPUSE28"); } else { start=W_GetNumForName("OBPSHOO1"); end =W_GetNumForName("OBPDEAD"); //end =W_GetNumForName("PATUSE28"); } break; case strikeguardobj: start = SD_STRIKE1SEESND; end = SD_STRIKEDIESND; SD_PreCacheSoundGroup(start,end); if (IS_ALTERNATE_ACTOR(new)) { start=W_GetNumForName("XYGSHOO1"); end =W_GetNumForName("XYLROLL6"); //end =W_GetNumForName("XYUSE28"); } else { start=W_GetNumForName("ANGSHOO1"); end =W_GetNumForName("ANLROLL6"); //end =W_GetNumForName("ANUSE28"); } break; case blitzguardobj: start = SD_BLITZ1SEESND; end = SD_BLITZDIESND; SD_PreCacheSoundGroup(start,end); if (IS_ALTERNATE_ACTOR(new)) { start=W_GetNumForName("WIGSHOO1"); end =W_GetNumForName("WIHUSE28"); } else { start=W_GetNumForName("LIGSHOO1"); end =W_GetNumForName("LIPEAD11"); } break; case triadenforcerobj: start = SD_ENFORCERSEESND; end = SD_ENFORCERDIESND; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("TEGREN1"); end =W_GetNumForName("TGRENF6"); PreCacheGroup(start,end,cache_patch_t); start=W_GetNumForName("TRISHOO1"); end =W_GetNumForName("TRIWDEAD"); //end =W_GetNumForName("TRIUSE28"); break; case deathmonkobj: start = SD_MONKSEESND; end = SD_MONKDIESND; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("MONKDR1"); end =W_GetNumForName("MONDEAD"); //end =W_GetNumForName("MONUSE28"); break; case dfiremonkobj: start = SD_FIREMONKSEESND; end = SD_FIREMONKDIESND; SD_PreCacheSoundGroup(start,end); start = W_GetNumForName("MONFIRE1"); end = W_GetNumForName("MONFIRE4"); PreCacheGroup(start,end,cache_patch_t); if (IS_ALTERNATE_ACTOR(new)) { start=W_GetNumForName("MRKKSH1"); end =W_GetNumForName("MRKDEAD7"); } else { start=W_GetNumForName("ALLKSH1"); end =W_GetNumForName("ALLDEAD7"); } break; case roboguardobj: start = SD_ROBOTSEESND; end = SD_ROBOTDIESND; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("ROBOGRD1"); end =W_GetNumForName("ROBGRD16"); break; case b_darianobj: PreCachePlayerSound(); start = SD_DARIANSEESND; end = SD_DARIANSAY3; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("DARSHOO1"); end =W_GetNumForName("DARUSE28"); break; case b_heinrichobj: PreCachePlayerSound(); start = SD_KRISTSEESND; end = SD_KRISTSAY3; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("MINE1"); end =W_GetNumForName("MINE4"); PreCacheGroup(start,end,cache_patch_t); start=W_GetNumForName("HSIT1"); end =W_GetNumForName("HDOPE8"); break; case b_darkmonkobj: start = SD_DARKMONKSEESND; end = SD_DARKMONKSAY3; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("LIGNING1"); end =W_GetNumForName("FSPARK4"); PreCacheGroup(start,end,cache_patch_t); start=W_GetNumForName("TOMS1"); end =W_GetNumForName("TOHRH8"); break; case b_darksnakeobj: PreCachePlayerSound(); start = SD_SNAKESEESND; end = SD_SNAKESAY3; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("TOMRH1"); end =W_GetNumForName("TOHRH8"); case b_robobossobj: PreCachePlayerSound(); start = SD_NMESEESND; end = SD_NMESEESND; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("RHEAD101"); end =W_GetNumForName("NMESAUC4"); break; case patrolgunobj: start = SD_EMPLACEMENTSEESND; end = SD_BIGEMPLACEFIRESND; SD_PreCacheSoundGroup(start,end); start=W_GetNumForName("GUNEMP1"); end =W_GetNumForName("GUNEMPF8"); PreCacheGroup(start,end,cache_patch_t); start=W_GetNumForName("GRISE11"); end =W_GetNumForName("GDEAD2"); break; case wallopobj: start=W_GetNumForName("BSTAR1"); end =W_GetNumForName("BSTAR4"); PreCacheGroup(start,end,cache_patch_t); start=W_GetNumForName("BCRAFT1"); end =W_GetNumForName("BCRAFT16"); break; case wallfireobj: SD_PreCacheSound(SD_FIRECHUTESND); SD_PreCacheSound(SD_FIREBALLSND); SD_PreCacheSound(SD_FIREBALLHITSND); start = W_GetNumForName("CRFIRE11"); end = W_GetNumForName("CREXP5"); case pillarobj: start=W_GetNumForName("PUSHCOL1"); end =W_GetNumForName("PSHCOL1A"); //end =W_GetNumForName("PUSHCOL3"); break; case firejetobj: SD_PreCacheSound(SD_FIREJETSND); if (which) { start=W_GetNumForName("FJUP0"); end =W_GetNumForName("FJUP22"); } #if (SHAREWARE == 0) else { start=W_GetNumForName("FJDOWN0"); end =W_GetNumForName("FJDOWN22"); } #endif break; case bladeobj: SD_PreCacheSound(SD_BLADESPINSND); #if (SHAREWARE == 0) if (which&2) { if (which&1) { start=W_GetNumForName("SPSTUP1"); end =W_GetNumForName("SPSTUP16"); } else { start=W_GetNumForName("SPSTDN1"); end =W_GetNumForName("SPSTDN16"); } } else { if (which&1) { start=W_GetNumForName("UBLADE1"); end =W_GetNumForName("UBLADE9"); } else { start=W_GetNumForName("DBLADE1"); end =W_GetNumForName("DBLADE9"); } } #else start=W_GetNumForName("UBLADE1"); end =W_GetNumForName("UBLADE9"); #endif break; case crushcolobj: SD_PreCacheSound(SD_CYLINDERMOVESND); if (which) { start=W_GetNumForName("CRDOWN1"); end =W_GetNumForName("CRDOWN8"); } #if (SHAREWARE == 0) else { start=W_GetNumForName("CRUP1"); end =W_GetNumForName("CRUP8"); } #endif break; case boulderobj: start=W_GetNumForName("BOL11"); end =W_GetNumForName("BSINK9"); SD_PreCacheSound(SD_BOULDERHITSND); SD_PreCacheSound(SD_BOULDERROLLSND); SD_PreCacheSound(SD_BOULDERFALLSND); break; case spearobj: SD_PreCacheSound(SD_SPEARSTABSND); if (which) { start=W_GetNumForName("SPEARUP1"); end =W_GetNumForName("SPERUP16"); } #if (SHAREWARE == 0) else { start=W_GetNumForName("SPEARDN1"); end =W_GetNumForName("SPERDN16"); } #endif break; case gasgrateobj: start = SD_GASSTARTSND; end = SD_GASMASKSND; SD_PreCacheSoundGroup(start,end); if ((locplayerstate->player == 1) || (locplayerstate->player == 3)) SD_PreCacheSound(SD_PLAYERCOUGHFSND); else SD_PreCacheSound(SD_PLAYERCOUGHMSND); start=-1; end=-1; break; case springobj: SD_PreCacheSound(SD_SPRINGBOARDSND); start=W_GetNumForName("SPRING1"); end =W_GetNumForName("SPRING9"); break; default: return; break; } if ((start>=0) && (end>=0)) PreCacheGroup(start,end,cache_patch_t); } /* ====================== = = MiscPreCache = precache the lump and check to see if it is already tagged = ====================== */ void MiscPreCache( void ) { int start; int end; //essential sounds SD_PreCacheSoundGroup(SD_HITWALLSND,SD_PLAYERDWHURTSND); SD_PreCacheSoundGroup(SD_RICOCHET1SND,SD_RICOCHET3SND); SD_PreCacheSound(SD_ATKPISTOLSND); SD_PreCacheSoundGroup(SD_PLAYERBURNEDSND,SD_PLAYERLANDSND); SD_PreCacheSoundGroup(SD_EXPLODEFLOORSND,SD_EXPLODESND); if (lightning==true) SD_PreCacheSound(SD_LIGHTNINGSND); SD_PreCacheSound(SD_BODYLANDSND); SD_PreCacheSound(SD_GIBSPLASHSND); SD_PreCacheSound(SD_ACTORLANDSND); SD_PreCacheSound(SD_ACTORSQUISHSND); // cache in bullet hole graphics start=W_GetNumForName("BULLETHO"); end=W_GetNumForName("ALTBHO"); PreCacheGroup(start,end,cache_transpatch_t); // cache in explosions if (DoPanicMapping()==true) { start=W_GetNumForName("EXPLOS1"); end =W_GetNumForName("EXPLOS20"); PreCacheGroup(start,end,cache_patch_t); } else { start=W_GetNumForName("EXPLOS1"); end =W_GetNumForName("GREXP25"); PreCacheGroup(start,end,cache_patch_t); } // cache in misc player sprites start=W_GetNumForName("BLOODS1"); end =W_GetNumForName("PLATFRM5"); PreCacheGroup(start,end,cache_patch_t); // cache in missile smoke start=W_GetNumForName("MISSMO11"); end =W_GetNumForName("MISSMO14"); PreCacheGroup(start,end,cache_patch_t); #if (DEVELOPMENT == 1) // cache in all weapon sounds SD_PreCacheSoundGroup(SD_ATKPISTOLSND,SD_LOSEMODESND); // cache in misc player weapons #if (SHAREWARE == 0) start=W_GetNumForName("KNIFE1"); end =W_GetNumForName("DOGPAW4"); PreCacheGroup(start,end,cache_patch_t); // cache in kinetic sphere start=W_GetNumForName("KSPHERE1"); end =W_GetNumForName("KSPHERE4"); PreCacheGroup(start,end,cache_patch_t); #else start=W_GetNumForName("MPIST11"); end =W_GetNumForName("GODHAND8"); PreCacheGroup(start,end,cache_patch_t); #endif // cache in god mode stuff PreCacheGroup(W_GetNumForName("VAPO1"), W_GetNumForName("LITSOUL"), cache_patch_t); PreCacheGroup(W_GetNumForName("GODFIRE1"), W_GetNumForName("GODFIRE4"), cache_patch_t); #endif // cache in player's gun // cache in rubble start=W_GetNumForName("RUBBLE1"); end =W_GetNumForName("RUBBLE10"); PreCacheGroup(start,end,cache_patch_t); // cache in guts start=W_GetNumForName("GUTS1"); end =W_GetNumForName("GUTS12"); PreCacheGroup(start,end,cache_patch_t); // cache in player missile start=W_GetNumForName("BJMISS1"); end =W_GetNumForName("BJMISS16"); PreCacheGroup(start,end,cache_patch_t); if (gamestate.violence >= vl_high) { // cache in all gibs if (DoPanicMapping()==true) { start = W_GetNumForName("ORGAN1"); end = W_GetNumForName("ORGAN12"); } else { start = W_GetNumForName("PART1"); end = W_GetNumForName("GEYE3"); } PreCacheGroup(start,end,cache_patch_t); } } /* ======================== = = IsChristmas = ======================== */ boolean IsChristmas(void) { struct dosdate_t date; _dos_getdate(&date); if (((date.day == 24) || (date.day == 25)) && //Christmas (date.month == 12) ) return true; return false; } /* ======================== = = CheckHolidays = ======================== */ void CheckHolidays(void) { struct dosdate_t date; _dos_getdate(&date); if (IsChristmas()) DrawNormalSprite(0,0,W_GetNumForName("santahat")); else if ((date.month == 5) && (date.day == 5)) // Cinco de Mayo DrawNormalSprite(0,0,W_GetNumForName("sombrero")); else if ((date.month == 7) && (date.day == 4)) // 4th of July DrawNormalSprite(0,0,W_GetNumForName("amflag")); else if ((date.month == 10) && (date.day == 31)) // Halloween DrawNormalSprite(0,0,W_GetNumForName("witchhat")); else if ((date.month == 4) && (date.dayofweek == 0)) //Easter { int i; for(i=15;i<=21;i++) { if (date.day == i) DrawNormalSprite(0,0,W_GetNumForName("esterhat")); } } } /* ====================== = = DrawPreCache = ====================== */ extern boolean dopefish; void DrawPreCache( void ) { if (loadedgame==false) { char temp[80]; int width, height, num; char buf[30]; if ( BATTLEMODE ) { VL_DrawPostPic (W_GetNumForName("trilogo")); VWB_TBar ( 30, 23, 260, 82 ); ShowBattleOptions( false, 56, 26 ); DrawPlayers (); } else { pic_t * pic; pic=(pic_t *)W_CacheLumpName("mmbk",PU_CACHE, Cvt_pic_t, 1); VWB_DrawPic (0, 0, pic); CheckHolidays(); } DrawNormalSprite (PRECACHEBARX, PRECACHEBARY, W_GetNumForName ("cachebar")); CurrentFont=smallfont; PrintY = PRECACHEESTRINGY; PrintX = PRECACHEESTRINGX; memset (&buf[0], 0, sizeof (buf)); if ( !BATTLEMODE ) { memcpy (&buf[0], "EPISODE ", 8); itoa (gamestate.episode,&buf[8],10); } else memcpy (&buf[0], "COMM-BAT", 8); US_MeasureStr (&width, &height, "%s", &buf[0]); VWB_TBar (PrintX-2, PrintY-2, width+4, height+4); US_BufPrint (&buf[0]); PrintY = PRECACHEASTRINGY; memset (&buf[0], 0, sizeof (buf)); memcpy (&buf[0], "AREA ", 5); if ( !BATTLEMODE ) { itoa( GetLevel( gamestate.episode, gamestate.mapon ), &buf[ 5 ], 10 ); } else { itoa( gamestate.mapon + 1, &buf[ 5 ], 10 ); } US_MeasureStr (&width, &height, "%s", &buf[0]); PrintX = (300-width); VWB_TBar (PrintX-2, PrintY-2, width+4, height+4); US_BufPrint (&buf[0]); PrintY = PRECACHESTRINGY; num = (RandomNumber ("PreCacheString", 0)) % MAXSILLYSTRINGS; if ((dopefish==true) || (tedlevel == true)) strcpy (temp, &(CacheStrings[num][0])); else strcpy (temp, &(LevelName[0])); US_MeasureStr (&width, &height, "%s", &temp[0]); PrintX = (320-width) >> 1; PrintY = PRECACHESTRINGY; VWB_TBar (PrintX-2, PrintY-2, width+4, height+4); US_BufPrint (&temp[0]); VW_UpdateScreen(); MenuFadeIn (); } } #define CACHETICDELAY (6) /* ====================== = = PreCache = precache all the lumps for the level = ====================== */ void PreCache( void ) { int i; int total; byte * dummy; int maxheapsize; int newheap; int currentmem; int currentcache; int lastmem=0; int lastcache=0; int ticdelay; byte *tempbuf; double Gs; Gs = (iGLOBAL_SCREENWIDTH*100/320); Gs = Gs / 100; //SetTextMode ( ); /* #define PRECACHEBARX 28 #define PRECACHEBARY 178 #define PRECACHELED1X 9 #define PRECACHELED1Y 8 #define PRECACHELED2X 9 #define PRECACHELED2Y 12 */ if (CachingStarted==false) { if (loadedgame==false) { ClearGraphicsScreen(); MenuFadeIn (); } return; } MiscPreCache(); SortPreCache(); if (loadedgame==false) { maxheapsize=Z_HeapSize(); total=0; tempbuf=bufferofs; bufferofs=page1start; // fixed, was displayofs ticdelay=CACHETICDELAY; for (i=1;i RTL_VERSION ) { Error( "The file '%s' is a version %d.%d %s file.\n" "The highest this version of ROTT can load is %d.%d.", filename, RTLVersion >> 8, RTLVersion & 0xff, RTLSignature, RTL_VERSION >> 8, RTL_VERSION & 0xff ); } close( filehandle ); } /* ====================== = = ReadROTTMap = ====================== */ void ReadROTTMap ( char *filename, int mapnum ) { RTLMAP RTLMap; int filehandle; long pos; long compressed; long expanded; int plane; byte *buffer; CheckRTLVersion( filename ); filehandle = SafeOpenRead( filename ); // // Load map header // lseek( filehandle, RTL_HEADER_OFFSET + mapnum * sizeof( RTLMap ), SEEK_SET ); SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) ); SwapIntelLong((int *)&RTLMap.used); SwapIntelLong((int *)&RTLMap.CRC); SwapIntelLong((int *)&RTLMap.RLEWtag); SwapIntelLong((int *)&RTLMap.MapSpecials); SwapIntelLongArray((int *)&RTLMap.planestart, NUMPLANES); SwapIntelLongArray((int *)&RTLMap.planelength, NUMPLANES); if ( !RTLMap.used ) { Error( "ReadROTTMap: Tried to load a non existent map!" ); } #if ( SHAREWARE == 1 ) if ( RTLMap.RLEWtag == REGISTERED_TAG ) { Error( "Can't use maps from the registered game in shareware version." ); } if ( RTLMap.RLEWtag != SHAREWARE_TAG ) { Error( "Can't use modified maps in shareware version." ); } #endif mapwidth = 128; mapheight = 128; // Get special map flags MapSpecials = RTLMap.MapSpecials; // // load the planes in // expanded = mapwidth * mapheight * 2; for( plane = 0; plane <= 2; plane++ ) { pos = RTLMap.planestart[ plane ]; compressed = RTLMap.planelength[ plane ]; buffer = SafeMalloc( compressed ); lseek( filehandle, pos, SEEK_SET ); SafeRead( filehandle, buffer, compressed ); mapplanes[ plane ] = Z_Malloc( expanded, PU_LEVEL, &mapplanes[ plane ] ); // // unRLEW, skipping expanded length // #if ( SHAREWARE == 1 ) CA_RLEWexpand( ( word * )buffer, ( word * )mapplanes[ plane ], expanded >> 1, SHAREWARE_TAG ); #else CA_RLEWexpand( ( word * )buffer, ( word * )mapplanes[ plane ], expanded >> 1, RTLMap.RLEWtag ); #endif SafeFree( buffer ); } close(filehandle); // // get map name // strcpy( LevelName, RTLMap.Name ); } /* ====================== = = GetNextMap = ====================== */ int GetNextMap ( int tilex, int tiley ) { word next; word icon; boolean done; next = MAPSPOT( tilex, tiley, 2 ); icon = MAPSPOT( tilex, tiley, 1 ); done=false; if ( ( ( icon != EXITTILE ) && ( icon != SECRETEXITTILE ) ) || ( ( ( next&0xff00 ) != 0xe200 ) && ( ( next&0xff00 ) != 0xe400 ) ) ) { int i,j; for ( j = 0; j < mapheight; j++ ) { for ( i = 0; i < mapwidth; i++ ) { icon = MAPSPOT( i, j, 1 ); next = MAPSPOT( i, j, 2 ); if ( ( ( icon == EXITTILE ) || ( icon == SECRETEXITTILE ) ) && ( ( ( next&0xff00 ) == 0xe200 ) || ( ( next&0xff00 ) == 0xe400 ) ) ) { done=true; break; } } if ( done == true ) { break; } } if ( !done ) { Error( "GetNextMap : No exit tile on map %d.", gamestate.mapon ); } } if ( ( ( next & 0xff00 ) != 0xe200 ) && ( ( next & 0xff00 ) != 0xe400 ) ) { // Should this be DEVELOPMENT only? Error( "GetNextMap : Illegal destination map %xh at exit " "tile on map %d.", next, gamestate.mapon ); } if ( next == 0xe2ff ) { return -1; } return ( next & 0xff ); } /* ====================== = = GetMapFileInfo = ====================== */ void GetMapFileInfo ( mapfileinfo_t *mapinfo, char *filename ) { RTLMAP RTLMap[ 100 ]; int filehandle; int i; int nummaps; CheckRTLVersion( filename ); filehandle = SafeOpenRead( filename ); // // Load map header // lseek( filehandle, RTL_HEADER_OFFSET, SEEK_SET ); SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) ); close( filehandle ); nummaps = 0; for( i = 0; i < 100; i++ ) { if ( !RTLMap[ i ].used ) { continue; } mapinfo->maps[ nummaps ].number = i; strcpy( mapinfo->maps[ nummaps ].mapname, RTLMap[ i ].Name ); nummaps++; } mapinfo->nummaps = nummaps; } /* ====================== = = GetMapFileName = ====================== */ void GetMapFileName ( char * filename ) { if ( ( BATTLEMODE ) && (BattleLevels.avail == true) ) { strcpy(filename,BattleLevels.file); } else if (GameLevels.avail == true) { strcpy(filename,GameLevels.file); } else if ( BATTLEMODE ) { strcpy(filename,BATTMAPS); } else { strcpy(filename,ROTTMAPS); } } /* ====================== = = SetBattleMapFileName = ====================== */ void SetBattleMapFileName ( char * filename ) { BattleLevels.avail = true; memset (&(BattleLevels.file[0]), 0, sizeof (BattleLevels.file)); strcpy (&(BattleLevels.file[0]), filename); } /* ====================== = = GetMapCRC = ====================== */ word GetMapCRC ( int num ) { int filehandle; char filename[ 80 ]; RTLMAP RTLMap; GetMapFileName( &filename[ 0 ] ); CheckRTLVersion( filename ); filehandle = SafeOpenRead( filename ); // // Load map header // lseek( filehandle, RTL_HEADER_OFFSET + num * sizeof( RTLMap ), SEEK_SET ); SafeRead( filehandle, &RTLMap, sizeof( RTLMap ) ); close( filehandle ); return( RTLMap.CRC ); } /* ====================== = = GetAlternateMapInfo = ====================== */ void GetAlternateMapInfo (mapfileinfo_t * mapinfo, AlternateInformation *info) { if (UL_ChangeDirectory (info->path) == false) Error ("ERROR : Can't change to alternate directory %s!\n", info->path); GetMapFileInfo (mapinfo, info->file); UL_ChangeDirectory (&CWD[0]); } /* ====================== = = GetMapInfo = ====================== */ void GetMapInfo ( mapfileinfo_t *mapinfo ) { if ( ( BATTLEMODE ) && ( BattleLevels.avail == true ) ) { GetAlternateMapInfo( mapinfo, &BattleLevels ); } else if ( GameLevels.avail == true ) { GetAlternateMapInfo( mapinfo, &GameLevels ); } else if ( BATTLEMODE ) { GetMapFileInfo( mapinfo, BATTMAPS ); } else { GetMapFileInfo( mapinfo, ROTTMAPS ); } } /* ====================== = = LoadTedMap = ====================== */ void LoadTedMap ( const char *extension, int mapnum ) { long pos; long compressed; long expanded; int plane; int i; int maphandle; byte *buffer; maptype mapheader; char name[ 200 ]; mapfiletype *tinf; // // load maphead.ext (offsets and tileinfo for map file) // strcpy( name, "maphead." ); strcat( name, extension ); LoadFile( name, ( void * )&tinf ); // fix structure alignment tinf = ( void * )( ( word * )tinf - 1 ); for( i = 0 ; i < 100 ; i++ ) { tinf->headeroffsets[ i ] = IntelLong( tinf->headeroffsets[ i ] ); } // // open the data file // strcpy( name, "maptemp." ); strcat( name, extension ); maphandle = SafeOpenRead( name ); // // load map header // pos = tinf->headeroffsets[ mapnum ]; // $FFFFFFFF start is a sparse map if ( pos < 0 ) { Error( "LoadTedMap : Tried to load a non existent map!" ); } lseek( maphandle, pos, SEEK_SET ); SafeRead( maphandle, &mapheader, sizeof( maptype ) ); for( i = 0 ; i < 3; i++ ) { mapheader.planestart[ i ] = IntelLong( mapheader.planestart[ i ] ); mapheader.planelength[ i ] = IntelShort( mapheader.planelength[ i ] ); } mapheader.width = IntelShort( mapheader.width ); mapheader.height = IntelShort( mapheader.height ); mapwidth = mapheader.width; mapheight = mapheader.height; // Set special map flags MapSpecials = 0; // // load the planes in // expanded = mapheader.width * mapheader.height * 2; for( plane = 0; plane <= 2; plane++ ) { pos = mapheader.planestart[ plane ]; lseek( maphandle, pos, SEEK_SET ); compressed = mapheader.planelength[ plane ]; buffer = SafeMalloc( compressed ); SafeRead( maphandle, buffer, compressed ); mapplanes[ plane ] = Z_Malloc( expanded, PU_LEVEL, &mapplanes[ plane ] ); // // unRLEW, skipping expanded length // CA_RLEWexpand( ( word * )( buffer + 2 ), ( word * )mapplanes[ plane ], expanded >> 1, 0xabcd ); SafeFree( buffer ); } // fix structure alignment tinf = ( void * )( ( word * )tinf + 1 ); SafeFree( tinf ); if ( close( maphandle ) ) { Error( "Error closing Ted file Error #%d", errno ); } } /* ====================== = = LoadAlternateMap = ====================== */ void LoadAlternateMap (AlternateInformation *info, int mapnum) { if (UL_ChangeDirectory (info->path) == false) Error ("ERROR : Can't change to alternate directory %s!\n",info->path); ReadROTTMap (info->file, mapnum); UL_ChangeDirectory (&CWD[0]); } /* ====================== = = LoadROTTMap = ====================== */ void LoadROTTMap ( int mapnum ) { if ( tedlevel == true ) { LoadTedMap( "rot", mapnum ); } else if ( ( BATTLEMODE ) && ( BattleLevels.avail == true ) ) { LoadAlternateMap( &BattleLevels, mapnum ); } else if ( GameLevels.avail == true ) { LoadAlternateMap( &GameLevels, mapnum ); } else if ( BATTLEMODE ) { ReadROTTMap( BATTMAPS, mapnum ); } else { ReadROTTMap( ROTTMAPS, mapnum ); } } void CountAreaTiles(void) {int i,j,areanumber; word*map,tile; memset(numareatiles,0,sizeof(numareatiles)); map = mapplanes[0]; for(i=0;i= 0) && (areanumber <= NUMAREAS)) numareatiles[areanumber] ++; } } #define InitWall(lump,index,newx,newy) \ { \ PreCacheLump(lump,PU_CACHEWALLS,cache_pic_t); \ if (W_LumpLength(lump) == 0) \ Error("%s being used in shareware at %d %d",\ W_GetNameForNum(lump),newx,newy); \ actorat[newx][newy]= &walls[index]; \ tempwall = (wall_t*)actorat[newx][newy]; \ tempwall->which = WALL; \ tempwall->tile = index; \ } \ /* ================== = = SetupWalls = ================== */ void SetupWalls( void ) { int i,j,lump,index; word *map,tile; wall_t * tempwall; for (i=0;i=0) && (i<=3) && (j==0)) { map++; continue; } if ((loadedgame == false) && (MAPSPOT(i,j,2) == 0xeeee)) {_2Dpoint *tdptr; tdptr = &(MISCVARS->EPOP[MISCVARS->nextpop]); tdptr->x = i; tdptr->y = j; MISCVARS->nextpop ++; MISCVARS->popsleft ++; } tile= *map++; if ((tile > 89) || ((tile > 32) && (tile < 36)) || (tile == 44) || (tile == 45) || (tile == 0) ) { tilemap[i][j] = 0; continue; } if (tile <= 32) { index = tile; #if 0 if (tile==12) { if (MAPSPOT(i,j,2)==0) MAPSPOT(i,j,2)=21; } #endif } else index = tile-3; if ((tile > 75) && (tile <= 79)) { lump = tilemap[i][j] = GetLumpForTile(tile); PreCacheLump(lump,PU_CACHEWALLS,cache_pic_t); PreCacheLump(elevatorstart+5,PU_CACHEWALLS,cache_pic_t); PreCacheLump(elevatorstart+6,PU_CACHEWALLS,cache_pic_t); PreCacheLump(elevatorstart+7,PU_CACHEWALLS,cache_pic_t); tilemap[i][j]|=0x2000; if (MAPSPOT(i,j,2)==0) MAPSPOT(i,j,2)=21; } else if ((tile >= 47) && (tile <= 48)) { lump = tilemap[i][j] = GetLumpForTile(tile); InitWall(lump,index,i,j); tilemap[i][j]|=0x2000; if (MAPSPOT(i,j,2)==0) MAPSPOT(i,j,2)=21; } else { lump = tilemap[i][j] = GetLumpForTile(tile); InitWall(lump,index,i,j); if (MAPSPOT(i,j,2)) tilemap[i][j]|=0x2000; } } } } /* =============== = = GetNearestAreaNumber = =============== */ word GetNearestAreaNumber ( int tilex, int tiley ) { int up,dn,lt,rt; int tile; tile=MAPSPOT(tilex,tiley,0)-AREATILE; if ((tile<=NUMAREAS) && (tile>0)) return (tile+AREATILE); up=MAPSPOT(tilex,tiley-1,0)-AREATILE; dn=MAPSPOT(tilex,tiley+1,0)-AREATILE; lt=MAPSPOT(tilex-1,tiley,0)-AREATILE; rt=MAPSPOT(tilex+1,tiley,0)-AREATILE; up = ((up>0) && (up<=NUMAREAS)); dn = ((dn>0) && (dn<=NUMAREAS)); lt = ((lt>0) && (lt<=NUMAREAS)); rt = ((rt>0) && (rt<=NUMAREAS)); if (rt) return (MAPSPOT(tilex+1,tiley,0) + AREATILE); else if (lt) return (MAPSPOT(tilex-1,tiley,0) + AREATILE); else if (up) return (MAPSPOT(tilex,tiley-1,0) + AREATILE); else if (dn) return (MAPSPOT(tilex,tiley+1,0) + AREATILE); // else // Error("GetNearestAreaNumber: Couldn't fix up area at x=%ld y=%ld\n",tilex,tiley); return (NUMAREAS+AREATILE-1); } /* =============== = = SetupWindows = =============== */ void SetupWindows ( void ) { int i,j; boolean skythere; skythere = SkyExists(); for (j=0;j=0) && (i<=3) && (j==0)) continue; if (IsWindow(i,j)) { actorat[i][j]=0; if (skythere==true) { tilemap[i][j]|=0x2000; } else { MAPSPOT(i,j,2)=0; } MAPSPOT(i,j,0)=(word)(GetNearestAreaNumber(i,j)); } } } } /* ================== = = GetWallIndex = ================== */ int GetWallIndex( int texture ) { int wallstart; int exitstart; wallstart=W_GetNumForName("WALLSTRT"); exitstart=W_GetNumForName("EXITSTRT"); elevatorstart = W_GetNumForName("ELEVSTRT"); if (texture&0x1000) { texture&=~0x1000; if (texture==0) return 41; else if (texture==1) return 90; else if (texture==2) return 91; else if (texture==3) return 42; else if (texture==4) return 92; else if (texture==5) return 93; else if (texture==6) return 94; else if (texture==7) return 95; else if (texture==8) return 96; else if (texture==9) return 97; else if (texture==10) return 98; else if (texture==11) return 99; else if (texture==12) return 100; else if (texture==13) return 101; else if (texture==14) return 102; else if (texture==15) return 103; else if (texture==16) return 104; } else if (texture > elevatorstart) return (texture - elevatorstart + 68); // else if (texture > specialstart) // return (texture - specialstart + 41); else if (texture > exitstart) return (texture - exitstart + 43); else { if (texture>wallstart+63) return (texture - (wallstart + 63) + 76 ); else if (texture>wallstart+40) return (texture - (wallstart + 40) + 45 ); else return (texture - wallstart); } return 0x8000; } /* ================== = = SetupAnimatedWalls = ================== */ void SetupAnimatedWalls( void ) { int i,j; word *map,tile; wall_t * tempwall; InitAnimatedWallList(); map = mapplanes[0]; for (j=0;j=0) && (i<=3) && (j==0)) { map++; continue; } tile= *map++; if (tile == 44) { actorat[i][j]= &walls[tile-3]; tempwall = (wall_t*)actorat[i][j]; tempwall->which = WALL; tempwall->tile = tile-3; tempwall->flags = FL_W_DAMAGE; SetupAnimatedWall(0); tilemap[i][j]=0; tilemap[i][j]|=0x1000; } else if (tile == 45) { actorat[i][j]= &walls[tile-3]; tempwall = (wall_t*)actorat[i][j]; tempwall->which = WALL; tempwall->tile = tile-3; SetupAnimatedWall(3); tilemap[i][j]=3; tilemap[i][j]|=0x1000; } else if ((tile >= 106) && (tile <= 107)) { actorat[i][j]= &walls[tile-16]; tempwall = (wall_t*)actorat[i][j]; tempwall->which = WALL; tempwall->tile = tile-16; SetupAnimatedWall(tile-105); tilemap[i][j]=tile-105; tilemap[i][j]|=0x1000; } else if ((tile >= 224) && (tile <= 233)) { actorat[i][j]= &walls[tile-224+92]; tempwall = (wall_t*)actorat[i][j]; tempwall->which = WALL; tempwall->tile = tile-224+94; if (tile==233) tempwall->flags = FL_W_DAMAGE; SetupAnimatedWall(tile-224+4); tilemap[i][j]=tile-224+4; tilemap[i][j]|=0x1000; } else if ((tile >= 242) && (tile <= 244)) { actorat[i][j]= &walls[tile-242+102]; tempwall = (wall_t*)actorat[i][j]; tempwall->which = WALL; tempwall->tile = tile-242+102; SetupAnimatedWall(tile-242+14); tilemap[i][j]=tile-242+14; tilemap[i][j]|=0x1000; } } } } /* ================== = = SetupSwitches = ================== */ void SetupSwitches( void ) { int i,j; word *map,tile; map = mapplanes[0]; for (j=0;j=0) && (i<=3) && (j==0)) { map++; continue; } tile= *map++; if ((tile >= 76) && (tile <= 79)) { if (tile == 79) lastswitch->flags |= FL_ON; SpawnSwitchThingy(i,j); } else if ((tile == 157) || (tile == 175)) // hi masked switches { lastswitch->flags |= FL_W_INVERTED; lastswitch->flags |= FL_REVERSIBLE; if (tile==175) lastswitch->flags |= FL_ON; SpawnSwitchThingy(i,j); } } } } void RespawnPlayerobj(objtype *ob) {int rand,numchecked=0; int oldsetupgame,nx,ny,ndir; playertype *pstate; M_LINKSTATE(ob,pstate); if (gamestate.battlemode != battle_CaptureTheTriad) { rand = (GameRandomNumber("playerobj respawn",0) % NUMSPAWNLOCATIONS); while(numchecked < NUMSPAWNLOCATIONS) { if (!actorat[SPAWNLOC[rand].x][SPAWNLOC[rand].y]) {RevivePlayerobj(SPAWNLOC[rand].x,SPAWNLOC[rand].y,SPAWNLOC[rand].dir,ob); return; } numchecked ++; rand = (rand + 1) % NUMSPAWNLOCATIONS; } #if (DEVELOPMENT == 1) SoftError("\nno spawn locations available, using FindEmptyTile"); #endif nx = SPAWNLOC[rand].x; ny = SPAWNLOC[rand].y; ndir = SPAWNLOC[rand].dir; } else {nx = TEAM[pstate->team].tilex; ny = TEAM[pstate->team].tiley; ndir = TEAM[pstate->team].dir; } oldsetupgame = insetupgame; insetupgame = true; FindEmptyTile(&nx,&ny); insetupgame = oldsetupgame; RevivePlayerobj(nx,ny,ndir,ob); } #define SetupSpecificFlagTeamAt(whichteam, spawnlocindex) \ {int newx,newy; \ \ newx = SPAWNLOC[spawnlocindex].x; \ newy = SPAWNLOC[spawnlocindex].y; \ TEAM[whichteam].tilex = newx; \ TEAM[whichteam].tiley = newy; \ TEAM[whichteam].dir = SPAWNLOC[spawnlocindex].x; \ SpawnStatic(newx,newy,stat_collector,9); \ SpawnNewObj(newx,newy,&s_basemarker1,inertobj); \ LASTACTOR->z = LASTSTAT->z; \ LASTSTAT->flags |= FL_COLORED; \ LASTSTAT->hitpoints = whichteam; \ locspawned[spawnlocindex]=1; \ for(j=0;j 2)) Error("players selected more colors(%d) than Capture the Triad allows",numteams); } else TEAM[teamforcolor[color]].nummembers ++; PLAYERSTATE[i].team = teamforcolor[color]; } } /* ============= = = SetupTeams = ============= */ void SetupTeams(void) { int i,j,rand,sx,sy,ntilex,ntiley,dir, maxdist,currdist,spawnindex,cnt; int locspawned[MAXSPAWNLOCATIONS] = {0}; if (gamestate.battlemode == battle_CaptureTheTriad) {rand = (GameRandomNumber("net player spawn",0) % NUMSPAWNLOCATIONS); for(i=0;i TEAM[0].nummembers) ) {SetupSpecificFlagTeamAt(0,rand); break; } rand = (rand + 1)%NUMSPAWNLOCATIONS; } if (i == NUMSPAWNLOCATIONS) Error("No spawn location available for team 0, capture the flag"); maxdist = 0x80000000; for(i=0;i maxdist) {maxdist = currdist; spawnindex = i; } } SetupSpecificFlagTeamAt(1,spawnindex); } else { int badcount = 0,teamindex; if (numteams > NUMSPAWNLOCATIONS) Error("More teams than spawn locations !"); //cnt =0; //for(rand = 0;rand < NUMSPAWNLOCATIONS;rand++) for(cnt=0;cnttilex,PLAYER[i]->tiley); // Error("done"); #endif #endif } /* ================== = = SetupPlayers = ================== */ void SetupPlayers( void ) { int i,j; word *map,tile; //START in icon plane = 10 map = mapplanes[1]; for(j=0;jflags |= FL_DESIGNATED; for(i=0;imissileweapon = pstate->oldweapon = pstate->new_weapon = pstate->oldmissileweapon = pstate->weapon = wp_godhand; pstate->bulletweapon = -1; } else {pstate->missileweapon = pstate->oldweapon = pstate->new_weapon = pstate->oldmissileweapon = pstate->bulletweapon = pstate->weapon = -1; } } } PreCachePlayers(); } /* ================== = = SetupMaskedWalls = ================== */ void SetupMaskedWalls( void ) { int i,j; word *map,tile; map = mapplanes[0]; for (j=0;j= 158) && (tile <= 160)) // Multi glassed walls { SpawnMaskedWall(i,j,mw_multi1+(tile-158),MW_MULTI|MW_BLOCKING|MW_BLOCKINGCHANGES|MW_SHOOTABLE); } else if ((tile >= 176) && (tile <= 178)) // Multi shot out glassed walls { SpawnMaskedWall(i,j,mw_multi1+(tile-176),MW_BOTTOMPASSABLE); } else if ((tile >= 162) && (tile <= 171)) { switch (tile) { case 162: SpawnMaskedWall(i,j,mw_normal1,MW_SHOOTABLE|MW_BLOCKING); break; case 163: SpawnMaskedWall(i,j,mw_normal1,MW_BLOCKING); break; case 164: SpawnMaskedWall(i,j,mw_normal2,MW_SHOOTABLE|MW_BLOCKING); break; case 165: SpawnMaskedWall(i,j,mw_normal2,MW_BLOCKING); break; case 166: SpawnMaskedWall(i,j,mw_normal3,MW_SHOOTABLE|MW_BLOCKING); break; case 167: SpawnMaskedWall(i,j,mw_normal3,MW_BLOCKING); break; case 168: SpawnMaskedWall(i,j,mw_singlepane,MW_SHOOTABLE|MW_BLOCKINGCHANGES|MW_BLOCKING); break; case 169: SpawnMaskedWall(i,j,mw_singlepane,MW_BOTTOMPASSABLE); break; case 170: SpawnMaskedWall(i,j,mw_dogwall,MW_NONDOGBLOCKING|MW_WEAPONBLOCKING); break; case 171: SpawnMaskedWall(i,j,mw_peephole,MW_WEAPONBLOCKING|MW_BLOCKING); break; } } else if (tile == 172) SpawnMaskedWall(i,j,mw_exitarch,MW_BOTTOMPASSABLE); else if (tile == 173) SpawnMaskedWall(i,j,mw_secretexitarch,MW_BOTTOMPASSABLE); else if (tile == 174) // entry gate SpawnMaskedWall(i,j,mw_entrygate,MW_BLOCKING); else if (tile == 157) // hi switch off SpawnMaskedWall(i,j,mw_hiswitchoff,MW_BLOCKING); else if (tile == 175) // hi switch on SpawnMaskedWall(i,j,mw_hiswitchon,MW_BLOCKING|MW_SWITCHON); else if (tile == 179) // railing; SpawnMaskedWall(i,j,mw_railing,MW_ABOVEPASSABLE|MW_MIDDLEPASSABLE); // else if (tile == 161) // pillar // SpawnMaskedWall(i,j,mw_pillar,MW_BLOCKING); } } for (j=0;j=0) || (MAPSPOT(i,j,0)==21)) // check to see we are not on a wall { int which; which=MAPSPOT(i,j,2)-4; switch (which) { case 0: SpawnMaskedWall(i,j,mw_platform1,MW_BOTTOMPASSABLE|MW_MIDDLEPASSABLE); break; case 1: SpawnMaskedWall(i,j,mw_platform2,MW_ABOVEPASSABLE|MW_MIDDLEPASSABLE); break; case 2: SpawnMaskedWall(i,j,mw_platform3,MW_MIDDLEPASSABLE); break; case 3: SpawnMaskedWall(i,j,mw_platform4,MW_BOTTOMPASSABLE); break; case 4: SpawnMaskedWall(i,j,mw_platform5,MW_BOTTOMPASSABLE|MW_ABOVEPASSABLE); break; case 5: SpawnMaskedWall(i,j,mw_platform6,MW_ABOVEPASSABLE); break; case -3: SpawnMaskedWall(i,j,mw_platform7,MW_ABOVEPASSABLE); break; default: Error ("Illegal Maskedwall platform value at x=%d y=%d\n",i,j); break; } #if 0 if (IsPlatform(i+1,j)) { if ( (IsPlatform(i,j+1)) || (IsPlatform(i,j-1)) ) SpawnStatic(i,j,83,MAPSPOT(i,j,2)); } else if (IsPlatform(i-1,j)) { if ( (IsPlatform(i,j+1)) || (IsPlatform(i,j-1)) ) SpawnStatic(i,j,83,MAPSPOT(i,j,2)); } #endif } else Error("You have what appears to be a platform ontop\n a wall at x=%d y=%d\n",i,j); } } } /* int GetAreaNumber ( int tilex, int tiley, int dir ); void RemoveDangerWalls ( void ) { int i; int j; word *map; word tile; map = mapplanes[ 1 ]; for( j = 0; j < mapheight; j++ ) { for( i = 0; i < mapwidth; i++ ) { tile = *map++; switch( tile ) { case 256: case 257: case 258: case 259: if ( MAPSPOT( i, j, 2 ) == 0 ) { MAPSPOT( i, j, 0 ) = ( word )( GetAreaNumber( i, j, ( tile - 256 ) << 1 ) + AREATILE ); MAPSPOT( i, j, 1 ) = 0; } break; case 300: case 318: case 336: case 354: if ( MAPSPOT( i, j, 2 ) == 0 ) { MAPSPOT( i, j, 0 ) = ( word )( GetAreaNumber( i, j, ( ( tile - 300 ) / 9 ) + AREATILE ) ); MAPSPOT( i, j, 1 ) = 0; } break; } } } } */ /* ================== = = SetupPushWalls = ================== */ void SetupPushWalls( void ) { int i,j; word *map,tile; int temp; map = mapplanes[1]; for(j=0;jtilex==tx) && (pwallobjlist[i]->tiley==ty)) return i; Error ("Could not find a push wall at x=%d y=%d\n",tx,ty); return -1; } /* ================== = = SetupPushWallLinks = ================== */ void SetupPushWallLinks( void ) { int i,j; word *map,tile; word touchx,touchy; map = mapplanes[1]; for(j=0;j> 8) & 0xff); touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff); if (touchindices[touchx][touchy]) { if (MAPSPOT(i,j+1,2)!=0) { #if (DEVELOPMENT == 1) SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j); #endif } Link_To_Touchplate(touchx,touchy,ActivatePushWall,NULL,GetPushWallNumber(i,j),0); } else Error("tried to link a pushwall at x=%d y=%d to a non-existent touchplate\n",i,j); } } break; case 80: if (ActorIsPushWall(i,j)) { if (MAPSPOT(i,j,2)) { Error("You shouldn't be linking a nondirectional-push wall at x=%d y=%d\n",i,j); } } break; case 256: case 257: case 258: case 259: if (ActorIsPushWall(i,j)) { if (MAPSPOT(i,j,2)) { touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff); touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff); if (touchindices[touchx][touchy]) { if (MAPSPOT(i,j+1,2)!=0) { #if (DEVELOPMENT == 1) SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j); #endif } Link_To_Touchplate(touchx,touchy,ActivateMoveWall,NULL,GetPushWallNumber(i,j),0); } else Error("tried to link a turbomovewall at x=%d y=%d to a non-existent touchplate\n",i,j); } } break; case 300: case 318: case 336: case 354: if (ActorIsPushWall(i,j)) { if (MAPSPOT(i,j,2)) { touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff); touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff); if (touchindices[touchx][touchy]) { if (MAPSPOT(i,j+1,2)!=0) { #if (DEVELOPMENT == 1) SoftError("MAPWARNING:You left a delay for a linked push wall under the pushwall\n at x=%ld y=%ld\n",i,j); #endif } Link_To_Touchplate(touchx,touchy,ActivateMoveWall,NULL,GetPushWallNumber(i,j),0); } else Error("tried to link a movewall at x=%d y=%d to a non-existent touchplate\n",i,j); } } break; } } } } /* ================= = = SetupElevators = ================= */ void SetupElevators (void) { int j, i,x,y,starti; word *map; word tile; elevator_t *elev; doorobj_t* dptr; map = mapplanes[1]; map += 4 ; for (j = 0; j < mapheight; j++) { if (j == 0) starti = 4; else starti = 0; for (i = starti; i < mapwidth; i++) {tile = *map++; if ((tile > 89) && (tile < 98)) {elev = &ELEVATOR[tile-90]; if (!elev->sx) {elev->sx = i; elev->sy = j; elev->doortoopen = -1; elev->doorclosing = -1; elev->nextaction = -1; _numelevators ++; } else {elev->dx = i; elev->dy = j; } } } } if (_numelevators && (!ELEVATOR[0].sx)) Error("Elevators must start at 1, dumb ass."); for(i=0;i<_numelevators;i++) {elev = &ELEVATOR[i]; x = elev->sx; y = elev->sy; for(j=0;jtilex == (x+1)) && (dptr->tiley == y)) || ((dptr->tilex == (x-1)) && (dptr->tiley == y)) || ((dptr->tilex == x) && (dptr->tiley == (y+1))) || ((dptr->tilex == x) && (dptr->tiley == (y-1)))) {elev->door1 = j; dptr->eindex = i; if ((dptr->tilex == (x+1)) && (dptr->tiley == y)) {elev->esx = x-1; elev->esy = y; } else if ((dptr->tilex == (x-1)) && (dptr->tiley == y)) {elev->esx = x+1; elev->esy = y; } else if ((dptr->tilex == x) && (dptr->tiley == (y+1))) {elev->esx = x; elev->esy = y-1; } else if ((dptr->tilex == x) && (dptr->tiley == (y-1))) {elev->esx = x; elev->esy = y+1; } break; } } x = elev->dx; y = elev->dy; for(j=0;jtilex == (x+1)) && (dptr->tiley == y)) || ((dptr->tilex == (x-1)) && (dptr->tiley == y)) || ((dptr->tilex == x) && (dptr->tiley == (y+1))) || ((dptr->tilex == x) && (dptr->tiley == (y-1)))) {elev->door2 = j; dptr->eindex = i; dptr->flags |= DF_ELEVLOCKED; if ((dptr->tilex == (x+1)) && (dptr->tiley == y)) {elev->edx = x-1; elev->edy = y; } else if ((dptr->tilex == (x-1)) && (dptr->tiley == y)) {elev->edx = x+1; elev->edy = y; } else if ((dptr->tilex == x) && (dptr->tiley == (y+1))) {elev->edx = x; elev->edy = y-1; } else if ((dptr->tilex == x) && (dptr->tiley == (y-1))) {elev->edx = x; elev->edy = y+1; } break; } } } #if ((DEVELOPMENT == 1)) #if ((ELEVATORTEST == 1)) for(i=0;i<_numelevators;i++) Debug("\nelevator %d door1 %2d, door2 %2d",i,ELEVATOR[i].door1,ELEVATOR[i].door2); #endif #endif } /* ================= = = SetupDoors = ================= */ void SetupDoors (void) { int j, i; word *map; word tile; byte locked; map = mapplanes[0]; for (j = 0; j < mapheight; j++) for (i = 0; i < mapwidth; i++) { tile = *map++; if ((tile >= 33) && (tile <= 35)) { tilemap[i][j] = doornum; locked=0; if (MAPSPOT (i, j, 2)) locked = 5; SpawnDoor (i, j, locked, (tile-33)+15); } else if ((tile > 89) && (tile < 94)) { tilemap[i][j] = doornum; locked = 0; if (MAPSPOT (i, j, 2)) locked = 5; SpawnDoor (i, j, locked, tile-90); } else if ((tile > 93) && (tile < 98)) { Error("locked door %d being used at %d,%d",tile,i,j); } else if ((tile > 97) && (tile < 105)) { tilemap[i][j] = doornum; locked = 0; if (MAPSPOT (i, j, 2)) locked = 5; SpawnDoor (i, j, locked, tile-90); } else if ((tile >= 154) && (tile <= 156)) { tilemap[i][j] = doornum; locked=0; if (MAPSPOT (i, j, 2)) locked = 5; SpawnDoor (i, j, locked, (tile-154)+18); } } } /* ================== = = GetDoorNumber = ================== */ int GetDoorNumber( int tx, int ty ) { int i; for (i=0;itilex==tx) && (doorobjlist[i]->tiley==ty)) return i; Error ("Could not find a door at x=%d y=%d\n",tx,ty); return -1; } /* ================= = = SetupDoorLinks = ================= */ void SetupDoorLinks (void) { int j, i, k; word *map; int clocklinked; int clockx,clocky; int doornumber; word touchx, tile, touchy; map = mapplanes[0]; for (j = 0; j < mapheight; j++) for (i = 0; i < mapwidth; i++) { tile = *map++; if (MAPSPOT (i, j, 2)) { if (IsDoor(i,j)==1) { clocklinked = 0; doornumber=GetDoorNumber(i,j); for (k = 0; k < numclocks; k++) { clockx = Clocks[k].points_to_tilex; clocky = Clocks[k].points_to_tiley; if ((clockx == i) && (clocky == j)) { clocklinked = 1; ClockLink (LinkedOpenDoor, LinkedCloseDoor, doornumber, k); doorobjlist[doornumber]->lock = 5; doorobjlist[doornumber]->flags |= DF_TIMED; } } if (!clocklinked) { touchx = (word) ((MAPSPOT (i, j, 2) >> 8) & 0xff); touchy = (word) ((MAPSPOT (i, j, 2) >> 0) & 0xff); if (touchindices[touchx][touchy]) { if (MAPSPOT (i, j, 1) == 192) Link_To_Touchplate (touchx, touchy, LinkedCloseDoor, LinkedCloseDoor, doornumber, 0); else Link_To_Touchplate (touchx, touchy, LinkedOpenDoor, LinkedOpenDoor, doornumber, 0); } else Error ("tried to link a door at x=%d y=%d to a non-existent touchplate",i,j); } } } } } /* ================= = = FindTimeTile = ================= */ void FindTimeTile ( int * x, int * y ) { int xx,yy; xx=*x; yy=*y; if (!(tilemap[xx+1][yy]) && MAPSPOT(xx+1,yy,2)) { *x=xx+1; return; } if (!(tilemap[xx-1][yy]) && MAPSPOT(xx-1,yy,2)) { *x=xx-1; return; } if (!(tilemap[xx][yy+1]) && MAPSPOT(xx,yy+1,2)) { *y=yy+1; return; } if (!(tilemap[xx][yy-1]) && MAPSPOT(xx,yy-1,2)) { *y=yy-1; return; } Error ("Could not find an end time for a clock linked item\nat x=%d y=%d\n",*x,*y); } /* ================= = = SetupClocks = ================= */ void SetupClocks (void) { int i, j, minutes, seconds, starti; word *map, tile, mapx, mapy; int endtimex, endtimey; map = mapplanes[1]; map += 4 ; for (j = 0; j < mapheight; j++) { if (j == 0) starti = 4; else starti = 0; for (i = starti; i < mapwidth; i++) { tile = *map++; if (tile == 121) { mapx = (word) ((MAPSPOT (i, j, 2) >> 8) & 0xff); mapy = (word) ((MAPSPOT (i, j, 2) >> 0) & 0xff); minutes = (int) ((MAPSPOT (mapx, mapy, 2) >> 8) & 0xff); seconds = (int) ((MAPSPOT (mapx, mapy, 2) >> 0) & 0xff); if (seconds > 0x59) Error ("seconds of clock time must be below 0x5a (60 secs) "); seconds = 10 * (seconds/16) + (seconds % 16); minutes = 60 * (10*(minutes/16) + (minutes % 16)); // total seconds Clocks[numclocks].time1 = VBLCOUNTER*(seconds + minutes); endtimex=mapx; endtimey=mapy; FindTimeTile (&endtimex, &endtimey); minutes = (int) ((MAPSPOT (endtimex, endtimey, 2) >> 8) & 0xff); seconds = (int) ((MAPSPOT (endtimex, endtimey, 2) >> 0) & 0xff); if (seconds > 0x59) Error("seconds of clock time must be below 0x5a (60 secs)"); seconds = 10 * (seconds/16) + (seconds % 16); minutes = 60 * (10*(minutes/16) + (minutes % 16)); // total seconds Clocks[numclocks].time2 = VBLCOUNTER * (seconds + minutes); Clocks[numclocks].points_to_tilex = mapx; Clocks[numclocks].points_to_tiley = mapy; Clocks[numclocks].linkindex = lasttouch; numclocks ++; // clocks treated as virtual touchplates lasttouch ++; } } } } /* ================= = = LinkElevatorDiskGroups = ================= */ void LinkElevatorDiskGroups(void) { objtype *diskfinder1,*temp,*master; int maxplatformheight[30]={-1}; int num_distinct_max_heights=0; int i; boolean newdiskheight; #define M_ISELEVDISK(actor) \ ((actor->obclass == diskobj) && (actor->state == &s_elevdisk)) for(diskfinder1 = FIRSTACTOR;diskfinder1;diskfinder1 = diskfinder1->next) { if (!M_ISELEVDISK(diskfinder1)) continue; newdiskheight = true; for(i=0;itemp2) { newdiskheight = false; break; } } if (newdiskheight == true) maxplatformheight[num_distinct_max_heights++] = diskfinder1->temp2; } for(i=0;itemp2 = maxplatformheight[i]; for(temp = FIRSTACTOR;temp;temp = temp->next) { if (temp == master) continue; if (!M_ISELEVDISK(temp)) continue; if (temp->temp2 != maxplatformheight[i]) continue; temp->target = master; SetTilePosition(master,temp->tilex,temp->tiley); master->areanumber=AREANUMBER(master->tilex,master->tiley); } master->flags |= FL_ABP; MakeActive(master); } } /* ================= = = LinkActor = ================= */ void LinkActor (objtype *ob,int tilex,int tiley, void (*action)(long),void (*swapaction)(long) ) { word touchx,touchy; int clockx,clocky; int clocklinked,k; wall_t * tswitch; clocklinked = 0; for(k=0;k> 8) & 0xff); touchy = (word) ((MAPSPOT(tilex,tiley,2) >> 0) & 0xff); if ((MISCVARS->TOMLOC.x == touchx) && (MISCVARS->TOMLOC.y == touchy)) { objtype *tom = (objtype*)actorat[touchx][touchy]; tom->whatever = ob; } else if (touchindices[touchx][touchy]) { tswitch = (wall_t*) actorat[touchx][touchy]; if (tswitch && (ob->obclass == wallfireobj)) { tswitch->flags |= FL_REVERSIBLE; if (tswitch->flags & FL_ON) ob->flags |= FL_ACTIVE; } if (tswitch && (tswitch->flags & FL_ON)) Link_To_Touchplate(touchx,touchy,swapaction,action,(long)ob,0); else Link_To_Touchplate(touchx,touchy,action,swapaction,(long)ob,0); if (ob->obclass == gasgrateobj) { ob->temp1 = touchx; ob->temp2 = touchy; } } else Error("tried to link an object at x=%d y=%d to a non-existent touchplate supposedly at x=%d y=%d",tilex,tiley,touchx,touchy); } if (tilemap[tilex][tiley]) (MAPSPOT(tilex,tiley,2))=21; } /* ====================== = = SetupInanimateActors = ====================== */ void SetupInanimateActors (void) { int i,j,linked; word *map,tile; void (*action)(long),(*swapaction)(long); map = mapplanes[1]; // non-linked, harmless inanimate actors for(j=0;jflags |= FL_ACTIVE; if (tilemap[i][j]) MAPSPOT(i,j,2) = 21; } else LinkActor(new,i,j,action,swapaction); } else if (tilemap[i][j]) MAPSPOT(i,j,2) = 21; break; case 303: case 304: case 305: SpawnPushColumn(i,j,tile-303,east,linked); swapaction = NULL; if (linked) LinkActor(new,i,j,action,swapaction); break; case 321: case 322: case 323: SpawnPushColumn(i,j,tile-321,north,linked); swapaction = NULL; if (linked) LinkActor(new,i,j,action,swapaction); break; case 339: case 340: case 341: SpawnPushColumn(i,j,tile-339,west,linked); swapaction = NULL; if (linked) LinkActor(new,i,j,action,swapaction); break; case 357: case 358: case 359: SpawnPushColumn(i,j,tile-357,south,linked); swapaction = NULL; if (linked) LinkActor(new,i,j,action,swapaction); break; } } } //harmful actors if ((!BATTLEMODE) || (gamestate.BattleOptions.SpawnDangers)) { map = mapplanes[1]; for(j=0;jflags |= FL_ABP; MakeActive(new); swapaction = NULL; if (linked) LinkActor(new,i,j,action,swapaction); } break; case 301: case 302: SpawnBlade(i,j,east,tile-301,0); if (!linked) new->flags |= FL_ACTIVE; else LinkActor(new,i,j,action,swapaction); break; case 319: case 320: SpawnBlade(i,j,north,tile-319,0); if (!linked) new->flags |= FL_ACTIVE; else LinkActor(new,i,j,action,swapaction); break; case 337: case 338: SpawnBlade(i,j,west,tile-337,0); if (!linked) new->flags |= FL_ACTIVE; else LinkActor(new,i,j,action,swapaction); break; case 355: case 356: SpawnBlade(i,j,south,tile-355,0); if (!linked) new->flags |= FL_ACTIVE; else LinkActor(new,i,j,action,swapaction); break; case 372: SpawnFirejet(i,j,nodir,0); break; case 373: case 374: case 375: case 376: SpawnFirejet(i,j,tile-373,0); break; case 390: SpawnFirejet(i,j,nodir,1); break; case 391: case 392: case 393: case 394: SpawnFirejet(i,j,tile-391,1); break; case 278: case 279: case 280: case 281: SpawnBoulder(i,j,tile-278); if (!linked) new->flags |= FL_ACTIVE; else LinkActor(new,i,j,action,swapaction); break; } } } } LinkElevatorDiskGroups(); } /* =================== = = FixTiles = =================== */ void FixTiles(void) { word *map,tile; int i,j; map = mapplanes[1]; for(j=0;jstatnext) if (temp->flags & FL_LIGHTON) TurnOnLight(temp->tilex,temp->tiley); } /* ================= = = SetupLights = ================= */ void SetupLights(void) { int i,j,touchx,touchy; wall_t *tswitch; word *map,tile; int starti; // Initialize Lights in Area memset(LightsInArea,0,sizeof(LightsInArea)); map = mapplanes[1]; map+=5; for (j=0;jflags |= FL_LIGHTON; break; case 28: case 43: if (MAPSPOT(i,j,2)) { touchx = (word) ((MAPSPOT(i,j,2) >> 8) & 0xff); touchy = (word) ((MAPSPOT(i,j,2) >> 0) & 0xff); tswitch = (wall_t*) actorat[touchx][touchy]; if (tswitch && (tswitch->which == WALL)) {tswitch->flags |= FL_REVERSIBLE; if (!(tswitch->flags & FL_ON)) {sprites[i][j]->shapenum --; if (touchindices[touchx][touchy]) {Link_To_Touchplate(touchx,touchy,ActivateLight,DeactivateLight,(long)(sprites[i][j]),0); sprites[i][j]->linked_to = touchindices[touchx][touchy]-1; } else Error("tried to link a light at x=%d y=%d to a non-existent touchplate",i,j); } else {if (touchindices[touchx][touchy]) {Link_To_Touchplate(touchx,touchy,DeactivateLight,ActivateLight,(long)(sprites[i][j]),0); sprites[i][j]->linked_to = touchindices[touchx][touchy]-1; } else Error("tried to link a light at x=%d y=%d to a non-existent touchplate",i,j); sprites[i][j]->flags |= FL_LIGHTON; } } else {if (touchindices[touchx][touchy]) {Link_To_Touchplate(touchx,touchy,DeactivateLight,ActivateLight,(long)(sprites[i][j]),0); sprites[i][j]->linked_to = touchindices[touchx][touchy]-1; } else Error("tried to link a light at x=%d y=%d to a non-existent touchplate",i,j); sprites[i][j]->flags |= FL_LIGHTON; } } else sprites[i][j]->flags |= FL_LIGHTON; break; } } } } /* ================== = = PrintMapStats = ================== */ void PrintMapStats (void) { int size; int total; if (MAPSTATS==false) return; OpenMapDebug(); total=0; MapDebug("MAP STATS Map Number %d\n",gamestate.mapon); MapDebug("=======================\n"); size=pwallnum*sizeof(pwallobj_t); total+=size; MapDebug("Number of PushWalls : %4d size = %6d\n",pwallnum,size); size=maskednum*sizeof(maskedwallobj_t); total+=size; MapDebug("Number of MaskedWalls : %4d size = %6d\n",maskednum,size); size=doornum*sizeof(doorobj_t); total+=size; MapDebug("Number of Doors : %4d size = %6d\n",doornum,size); size=lasttouch*sizeof(touchplatetype); total+=size; MapDebug("Number of TouchPlates : %4d size = %6d\n",lasttouch,size); size=_numelevators*sizeof(elevator_t); total+=size; MapDebug("Number of Elevators : %4d size = %6d\n",_numelevators,size); size=statcount*sizeof(statobj_t); total+=size; MapDebug("Number of Sprites : %4d size = %6d\n",statcount,size); size=objcount*sizeof(objtype); total+=size; MapDebug("Number of Actors : %4d size = %6d\n",objcount,size); MapDebug("Number of Clocks : %4d\n",numclocks); MapDebug("\nTotal size of level : %6d\n",total); } boolean IsWeapon(int tile) { if ((tile >= 46) && (tile <= 56)) return true; return false; } char *WeaponName(int tile) { switch(tile) { case 46: return "Bat "; break; case 47: return "Knife "; break; case 48: return "Double Pistol "; break; case 49: return "MP40 "; break; case 50: return "Bazooka "; break; case 51: return "Firebomb "; break; case 52: return "Heatseeker "; break; case 53: return "Drunk Missile "; break; case 54: return "Flamewall "; break; case 55: return "Split Missile "; break; case 56: return "KES "; break; } return " "; } int GetLumpForTile(int tile) { int wallstart; int exitstart; wallstart=W_GetNumForName("WALLSTRT"); exitstart=W_GetNumForName("EXITSTRT"); elevatorstart = W_GetNumForName("ELEVSTRT"); if ((tile >= 1) && (tile <= 32)) { return (tile + wallstart); } else if ((tile >= 36) && (tile <= 45)) { return (tile + wallstart - 3); } else if (tile == 46) { return (wallstart + 74); } else if ((tile >= 47) && (tile <= 48)) { return (tile + exitstart - 46); } else if ((tile >= 49) && (tile <= 71)) { return (tile + wallstart - 8); } else if ((tile >= 72) && (tile <= 79)) { return (tile - 72 + elevatorstart + 1); } else if ((tile >= 80) && (tile <= 89)) { return (tile + wallstart - 16); } return -1; } #if (DEVELOPMENT == 1) /* ================== = = Insane Dump = ================== */ void InsaneDump(void) { int i,j,level; word *map,tile; int tally[1000]; int inlevel[1000][10]; if (TILESTATS==false) return; OpenMapDebug(); // WALLS memset(tally,0,sizeof(tally)); memset(inlevel,0,sizeof(inlevel)); MapDebug("=======================\n"); MapDebug("= WALLS\n"); MapDebug("=======================\n"); mapheight = mapwidth = 128; BATTLEMODE = 1; for(level=0;level<8;level ++) { GetEpisode(level); LoadROTTMap(level); map = mapplanes[0]; for (j=0;j0) tally[(*map)]++; map++; } } // Low Guards easytotal=0; hardtotal=0; for (i=108;i<=119;i++) easytotal+=tally[i]; for (i=126;i<=137;i++) hardtotal+=tally[i]; MapDebug("\nLowGuards\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Sneaky Low Guards easytotal=0; hardtotal=0; for (i=120;i<=120;i++) easytotal+=tally[i]; for (i=138;i<=138;i++) hardtotal+=tally[i]; MapDebug("\nSneakyLowGuards\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // High Guards easytotal=0; hardtotal=0; for (i=144;i<=155;i++) easytotal+=tally[i]; for (i=162;i<=173;i++) hardtotal+=tally[i]; MapDebug("\nHighGuards\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // OverPatrol Guards easytotal=0; hardtotal=0; for (i=216;i<=227;i++) easytotal+=tally[i]; for (i=234;i<=245;i++) hardtotal+=tally[i]; MapDebug("\nOverPatrolGuards\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Strike Guards easytotal=0; hardtotal=0; for (i=180;i<=191;i++) easytotal+=tally[i]; for (i=198;i<=204;i++) hardtotal+=tally[i]; MapDebug("\nStrikeGuards\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // TriadEnforcer Guards easytotal=0; hardtotal=0; for (i=288;i<=299;i++) easytotal+=tally[i]; for (i=306;i<=317;i++) hardtotal+=tally[i]; MapDebug("\nTriadEnforcer Guards\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Lightning Guards easytotal=0; hardtotal=0; for (i=324;i<=335;i++) easytotal+=tally[i]; for (i=342;i<=353;i++) hardtotal+=tally[i]; MapDebug("\nLightningGuards\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Random Actors easytotal=0; hardtotal=0; for (i=122;i<=125;i++) easytotal+=tally[i]; MapDebug("\nRandom Actors\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",easytotal); // Monks easytotal=0; hardtotal=0; for (i=360;i<=371;i++) easytotal+=tally[i]; for (i=378;i<=389;i++) hardtotal+=tally[i]; MapDebug("\nMonks\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Fire Monks easytotal=0; hardtotal=0; for (i=396;i<=407;i++) easytotal+=tally[i]; for (i=414;i<=425;i++) hardtotal+=tally[i]; MapDebug("\nFire Monks\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Robo Guards easytotal=0; hardtotal=0; for (i=158;i<=161;i++) easytotal+=tally[i]; for (i=176;i<=179;i++) hardtotal+=tally[i]; MapDebug("\nRoboGuards\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Ballistikrafts easytotal=0; hardtotal=0; for (i=408;i<=411;i++) easytotal+=tally[i]; for (i=426;i<=429;i++) hardtotal+=tally[i]; MapDebug("\nBallistikrafts\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Boulders easytotal=0; hardtotal=0; for (i=278;i<=281;i++) easytotal+=tally[i]; for (i=395;i<=395;i++) hardtotal+=tally[i]; MapDebug("\nBoulders\n"); MapDebug("-----------------------\n"); MapDebug("Boulders=%4d\n",easytotal); MapDebug("BoulderHoles=%4d\n",hardtotal); // PushColumns easytotal=0; hardtotal=0; for (i=285;i<=287;i++) easytotal+=tally[i]; for (i=303;i<=305;i++) easytotal+=tally[i]; for (i=321;i<=323;i++) easytotal+=tally[i]; for (i=339;i<=341;i++) easytotal+=tally[i]; for (i=357;i<=359;i++) easytotal+=tally[i]; MapDebug("\nPushColumns\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",easytotal); // Gun Emplacements easytotal=0; hardtotal=0; for (i=194;i<=197;i++) easytotal+=tally[i]; for (i=212;i<=215;i++) hardtotal+=tally[i]; MapDebug("\nGun Emplacements\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // 4-way guns easytotal=0; hardtotal=0; for (i=89;i<=89;i++) easytotal+=tally[i]; for (i=211;i<=211;i++) hardtotal+=tally[i]; MapDebug("\n4-way guns\n"); MapDebug("-----------------------\n"); MapDebug("EasyTotal=%4d\n",easytotal); MapDebug("HardTotal=%4d\n",hardtotal); MapDebug(" Total=%4d\n",easytotal+hardtotal); // Stabbers from above MapDebug("\nStabbers from above\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[412]); // Stabbers from below MapDebug("\nStabbers from below\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[430]); // Crushing pillar from above MapDebug("\nCrushing pillar from above\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[413]); // Crushing pillar from below MapDebug("\nCrushing pillar from below\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[431]); // Above Spinner MapDebug("\nAbove Spinner\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[156]); // Ground Spinner MapDebug("\nGround Spinner\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[174]); // Spinner from above MapDebug("\nSpinner from above\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[157]); // Spinner from below MapDebug("\nSpinner from below\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[175]); // Bosses easytotal=0; for (i=99;i<=103;i++) easytotal+=tally[i]; MapDebug("\nBosses\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",easytotal); // Spring Boards MapDebug("\nSpring Boards\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",tally[193]); // Above FlameJets easytotal=0; hardtotal=0; for (i=372;i<=376;i++) easytotal+=tally[i]; for (i=390;i<=394;i++) hardtotal+=tally[i]; MapDebug("\nFlameJets\n"); MapDebug("-----------------------\n"); MapDebug(" Above=%4d\n",easytotal); MapDebug(" Ground=%4d\n",hardtotal); // Fire Chutes easytotal=0; for (i=140;i<=143;i++) easytotal+=tally[i]; MapDebug("\nFireChutes\n"); MapDebug("-----------------------\n"); MapDebug(" Total=%4d\n",easytotal); // Sprites MapDebug("=======================\n"); MapDebug("= SPRITES\n"); MapDebug("=======================\n"); MapDebug("Sprite # Frequency\n"); MapDebug("-----------------------\n"); for (i=1;i<=72;i++) if (tally[i]!=0) MapDebug(" %4d %4d\n",i,tally[i]); for (i=210;i<=210;i++) if (tally[i]!=0) MapDebug(" %4d %4d\n",i,tally[i]); for (i=228;i<=233;i++) if (tally[i]!=0) MapDebug(" %4d %4d\n",i,tally[i]); for (i=246;i<=255;i++) if (tally[i]!=0) MapDebug(" %4d %4d\n",i,tally[i]); for (i=260;i<=273;i++) if (tally[i]!=0) MapDebug(" %4d %4d\n",i,tally[i]); for (i=282;i<=284;i++) if (tally[i]!=0) MapDebug(" %4d %4d\n",i,tally[i]); } //*************************************************************************** // // GetSongForLevel - returns song to play for current level // //*************************************************************************** int GetSongForLevel ( void ) { int i; int num; for (i=0;i>8) == 0xba ) return (num&0xff); } // Error("GetSongForLevel: could not find song in level %ld\n",gamestate.mapon); // return -1; return 0; } /* ================== = = DoSharewareConversionBackgroundPlane = ================== */ void DoSharewareConversionBackgroundPlane (void) { int i,j; word * map; for (j=0;j=90) && (crud<=97)) { levelheight=crud-89; maxheight = (levelheight << 6)-32; nominalheight = maxheight-32; } else if ((crud>=450) && (crud<=457)) { levelheight=crud-450+9; maxheight = (levelheight << 6)-32; nominalheight = maxheight-32; } else Error("You must specify a valid height sprite icon at (2,0) on map %d\n",gamestate.mapon); /* if ( ( BATTLEMODE ) && ( !gamestate.BattleOptions.SpawnDangers ) ) { RemoveDangerWalls(); } */ // pheight=maxheight-32; CountAreaTiles(); SetupWalls(); SetupClocks(); SetupAnimatedWalls(); if (loadedgame==false) { SetupSwitches(); SetupStatics (); SetupMaskedWalls(); SetupDoors(); SetupPushWalls(); SetupPlayers(); if (!BATTLEMODE) { SetupActors(); SetupRandomActors(); } SetupElevators(); SetupDoorLinks(); SetupPushWallLinks(); FixDoorAreaNumbers(); FixMaskedWallAreaNumbers(); SetupWindows(); SetupLights(); SetupInanimateActors(); } else { FixTiles(); } if (gamestate.SpawnEluder || gamestate.SpawnDeluder) { //MED for (i=0;i<25;i++) RespawnEluder(); } if ( ( BATTLEMODE ) && ( MapSpecials & MAP_SPECIAL_TOGGLE_PUSHWALLS ) ) { ActivateAllPushWalls(); } Illuminate(); if (SNAKELEVEL == 1) SetupSnakePath(); LoftSprites(); SetPlaneViewSize(); if (loadedgame==false) { ConnectAreas(); #if (DEVELOPMENT == 1) #if (PRECACHETEST == 1) SoftError("Start PreCaching\n"); #endif #endif #if (DEVELOPMENT == 1) PrintMapStats(); #endif PreCache(); #if (DEVELOPMENT == 1) #if (PRECACHETEST == 1) SoftError("Done PreCaching\n"); #endif #endif SetupPlayScreen(); SetupScreen(false); } if (BATTLEMODE) { SetModemLightLevel ( gamestate.BattleOptions.LightLevel ); } if (player != NULL) { for (i=0;i<100;i++) { UpdateLightLevel(player->areanumber); } } insetupgame=false; tedlevel = false; // turn it off once we have done any ted stuff EnableScreenStretch(); } void InitializePlayerstates(void) {int i; playertype * pstate; if (NewGame || (gamestate.mapon == 0) || tedlevel) {for(i=0;imissileweapon == wp_godhand) #if (SHAREWARE == 0) || (pstate->missileweapon == wp_dog) #endif ) { pstate->weapon=pstate->new_weapon=pstate->oldweapon; pstate->missileweapon = pstate->oldmissileweapon; } ResetPlayerstate(pstate); } NewGame = false; } void SetupSnakePath(void) { #if (SHAREWARE == 0) int i,j; word *map,tile; map = mapplanes[1]; for(j=0;j= 72) && (tile <= 79) && (!tilemap[i][j])) {SNAKEPATH[whichpath].x = i; SNAKEPATH[whichpath].y = j; whichpath ++; } } #endif } void SetupRandomActors(void) {int i,j; word *map,tile; int starti,totalrandom=0,count=0,ambush,locindex,orig; byte actorpresent[10]={0},index=0,randomtype,used[100]={0}; _2Dpoint randloc[100]; map = mapplanes[1]; map+=5; for(i=0;i<10;i++) {if (RANDOMACTORTYPE[i]) actorpresent[index++]=i; } if (!index) return; for (j=0;j= 122) && (tile <= 125)) {randloc[totalrandom].x = i; randloc[totalrandom].y = j; totalrandom++; if (totalrandom >= 100) Error("Max random actors (100) exceeded"); } } } orig = totalrandom; switch(gamestate.difficulty) { case gd_baby: totalrandom = 7*totalrandom/10; break; case gd_easy: totalrandom = 8*totalrandom/10; break; case gd_medium: totalrandom = 9*totalrandom/10; break; } while(countTOMLOC.x = i; MISCVARS->TOMLOC.y = j; break; case 102: SpawnMultiSpriteActor(b_robobossobj,i,j,tile-102); break; case 103: SpawnSnake(i,j); break; case 426: case 427: case 428: case 429: if (gamestate.difficulty < gd_hard) break; tile -= 18; case 408: case 409: case 410: case 411: SpawnPatrol(wallopobj,i,j,tile-408); break; } } } } void SetupStatics(void) { int i,j,spawnz; word *map,tile; int starti; map = mapplanes[1]; map+=5; BATTLE_NumCollectorItems = 0; for (j=0;jplayer == 1) || (locplayerstate->player == 3)) PreCacheGroup(W_GetNumForName("RFPIST1"), W_GetNumForName("LFPIST3"), cache_patch_t); else if (locplayerstate->player == 2) PreCacheGroup(W_GetNumForName("RBMPIST1"), W_GetNumForName("LBMPIST3"), cache_patch_t); else PreCacheGroup(W_GetNumForName("RMPIST1"), W_GetNumForName("LMPIST3"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); break; case 49: SD_PreCacheSound(SD_ATKMP40SND); PreCacheGroup(W_GetNumForName("MP401"), W_GetNumForName("MP403"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); break; case 50: SD_PreCacheSound(SD_MISSILEHITSND); SD_PreCacheSound(SD_MISSILEFLYSND); SD_PreCacheSound(SD_BAZOOKAFIRESND); PreCacheGroup(W_GetNumForName("BAZOOKA1"), W_GetNumForName("BAZOOKA4"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); if (loadedgame == false) gamestate.missiletotal ++; break; case 51: SD_PreCacheSound(SD_MISSILEHITSND); SD_PreCacheSound(SD_MISSILEFLYSND); SD_PreCacheSound(SD_FIREBOMBFIRESND); PreCacheGroup(W_GetNumForName("FBOMB1"), W_GetNumForName("FBOMB4"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); if (loadedgame == false) gamestate.missiletotal ++; break; case 52: SD_PreCacheSound(SD_MISSILEHITSND); SD_PreCacheSound(SD_MISSILEFLYSND); SD_PreCacheSound(SD_HEATSEEKFIRESND); PreCacheGroup(W_GetNumForName("HSEEK1"), W_GetNumForName("HSEEK4"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); if (loadedgame == false) gamestate.missiletotal ++; break; case 53: SD_PreCacheSound(SD_MISSILEHITSND); SD_PreCacheSound(SD_MISSILEFLYSND); SD_PreCacheSound(SD_DRUNKFIRESND); PreCacheGroup(W_GetNumForName("DRUNK1"), W_GetNumForName("DRUNK4"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); if (loadedgame == false) gamestate.missiletotal ++; break; case 54: SD_PreCacheSound(SD_MISSILEHITSND); SD_PreCacheSound(SD_MISSILEFLYSND); SD_PreCacheSound(SD_FLAMEWALLFIRESND); SD_PreCacheSound(SD_FLAMEWALLSND); PreCacheGroup(W_GetNumForName("FIREW1"), W_GetNumForName("FIREW3"), cache_patch_t); PreCacheGroup(W_GetNumForName("FWALL1"), W_GetNumForName("FWALL15"), cache_patch_t); PreCacheGroup(W_GetNumForName("SKEL1"), W_GetNumForName("SKEL48"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); if (loadedgame == false) gamestate.missiletotal ++; break; case 55: #if (SHAREWARE == 1) Error("\n tried to spawn split missile at %d,%d in shareware !",i,j); #endif SD_PreCacheSound(SD_MISSILEHITSND); SD_PreCacheSound(SD_MISSILEFLYSND); SD_PreCacheSound(SD_SPLITFIRESND); SD_PreCacheSound(SD_SPLITSND); PreCacheGroup(W_GetNumForName("SPLIT1"), W_GetNumForName("SPLIT4"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); if (loadedgame == false) gamestate.missiletotal ++; break; case 56: #if (SHAREWARE == 1) Error("\n tried to spawn kes at %d,%d in shareware !",i,j); #endif SD_PreCacheSound(SD_GRAVSND); SD_PreCacheSound(SD_GRAVHITSND); SD_PreCacheSound(SD_GRAVFIRESND); SD_PreCacheSound(SD_GRAVBUILDSND); PreCacheGroup(W_GetNumForName("KES1"), W_GetNumForName("KES6"), cache_patch_t); PreCacheGroup(W_GetNumForName("KSPHERE1"), W_GetNumForName("KSPHERE4"), cache_patch_t); SpawnStatic(i,j,tile-23,spawnz); if (loadedgame == false) gamestate.missiletotal ++; break; case 57: case 58: case 59: case 60: case 61: case 62: case 65: case 66: case 67: SpawnStatic(i,j,tile-23,spawnz); break; case 68: case 69: case 70: case 71: SpawnStatic(i,j,tile-23,spawnz); break; case 98: SpawnStatic(i,j,tile-98+49,spawnz); break; case 210: SpawnStatic(i,j,stat_scotthead,spawnz); break; case 228: case 229: case 230: case 231: case 232: case 233: SpawnStatic(i,j,tile-228+51,spawnz); break; case 246: case 247: case 248: case 249: case 250: case 251: SpawnStatic(i,j,tile-246+57,spawnz); break; case 264: case 265: SpawnStatic(i,j,tile-264+63,spawnz); gamestate.planttotal ++; break; case 266: SpawnStatic(i,j,stat_urn,spawnz); break; case 268: SpawnStatic(i,j,tile-265+63,spawnz); break; case 269: SpawnStatic(i,j,tile-265+63,spawnz); break; case 267: SpawnStatic(i,j,stat_emptystatue,spawnz); break; case 282: SpawnStatic(i,j,stat_heatgrate,spawnz); break; case 283: SpawnStatic(i,j,stat_standardpole,spawnz); break; case 284: if ( !BATTLEMODE ) { SpawnStatic(i,j,stat_pit,spawnz); } break; case 252: SD_PreCacheSound(SD_GRAVSND); SD_PreCacheSound(SD_GRAVHITSND); SD_PreCacheSoundGroup(SD_GODMODEFIRESND,SD_LOSEMODESND); if ((locplayerstate->player == 1) || (locplayerstate->player ==3)) SD_PreCacheSound(SD_GODWOMANSND); else SD_PreCacheSound(SD_GODMANSND); PreCacheGroup(W_GetNumForName("GODHAND1"), W_GetNumForName("GODHAND8"), cache_patch_t); PreCacheGroup(W_GetNumForName("VAPO1"), W_GetNumForName("LITSOUL"), cache_patch_t); PreCacheGroup(W_GetNumForName("GODFIRE1"), W_GetNumForName("GODFIRE4"), cache_patch_t); SpawnStatic(i,j,stat_godmode,spawnz); if (loadedgame == false) gamestate.supertotal ++; break; case 253: #if (SHAREWARE == 1) Error("DogMode Power up in shareware at x=%d y=%d\n",i,j); #endif SD_PreCacheSoundGroup(SD_DOGMODEPANTSND,SD_DOGMODELICKSND); if ((locplayerstate->player == 1) || (locplayerstate->player ==3)) SD_PreCacheSound(SD_DOGWOMANSND); else SD_PreCacheSound(SD_DOGMANSND); PreCacheGroup(W_GetNumForName("DOGNOSE1"), W_GetNumForName("DOGPAW4"), cache_patch_t); SpawnStatic(i,j,stat_dogmode,spawnz); if (loadedgame == false) gamestate.supertotal ++; break; case 254: SpawnStatic(i,j,stat_fleetfeet,spawnz); if (loadedgame == false) gamestate.supertotal ++; break; case 255: SpawnStatic(i,j,stat_random,spawnz); if (loadedgame == false) gamestate.supertotal ++; break; case 260: SpawnStatic(i,j,stat_elastic,spawnz); if (loadedgame == false) gamestate.supertotal ++; break; case 261: SpawnStatic(i,j,stat_mushroom,spawnz); if (loadedgame == false) { gamestate.supertotal ++; gamestate.democratictotal ++; } break; case 262: SpawnStatic(i,j,stat_tomlarva,spawnz); break; case 263: if (gamestate.SpawnCollectItems) { SpawnStatic(i,j,stat_collector,spawnz); LASTSTAT->flags |= FL_COLORED; LASTSTAT->hitpoints = ( GameRandomNumber("colors",0) % MAXPLAYERCOLORS ); BATTLE_NumCollectorItems++; } break; case 270: SpawnStatic(i,j,stat_bulletproof,spawnz); if (loadedgame == false) gamestate.supertotal ++; break; case 271: SpawnStatic(i,j,stat_asbesto,spawnz); if (loadedgame == false) gamestate.supertotal ++; break; case 272: SpawnStatic(i,j,stat_gasmask,spawnz); if (loadedgame == false) gamestate.supertotal ++; break; case 461: SpawnStatic(i,j,stat_disk,spawnz); break; } } } } void RaiseSprites( int x, int y, int count, int dir ) { int a,c; int dx,dy; int h; int i; int xx; int hc; int d; dx=0; dy=0; if (dir==1) dx=1; else dy=1; if (((statobj_t *)sprites[x][y])->z==-65) { c=(maxheight+20)<<8; hc=(count+1)<<7; a=(c<<8)/(hc*hc); for (i=0;i>8; ((statobj_t *)sprites[x+(dx*i)][y+(dy*i)])->z=maxheight-h; } } else { if (ActorIsSpring(x-(dx),y-(dy))) d=1; else if (ActorIsSpring(x+(dx*count),y+(dy*count))) d=0; else Error("Cannot find a spring board around a ramp ascension near x=%d y=%d\n",x,y); hc=((maxheight+20)<<16)/(count+1); h=hc<<1; for (i=0;iz=maxheight-(h>>16); else ((statobj_t *)sprites[x+(dx*(count-i-1))][y+(dy*(count-i-1))])->z=maxheight-(h>>16); h+=hc; } } } void LoftSprites( void ) { int x,y; int count; for(y=1;y