2015-05-19 21:54:34 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 1997 , 2005 - 3 D Realms Entertainment
This file is part of Shadow Warrior version 1.2
Shadow Warrior 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 . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
Original Source : 1997 - Frank Maddin and Jim Norwood
Prepared for public release : 03 / 28 / 2005 - Charlie Wiederhold , 3 D Realms
*/
//-------------------------------------------------------------------------
// JSECTOR.C
// This is all Jim's programming having to do with sectors.
2019-10-09 16:09:05 +00:00
# include "ns.h"
2015-05-19 21:54:34 +00:00
# include "build.h"
# include "keys.h"
# include "names2.h"
# include "jnames.h"
# include "panel.h"
# include "game.h"
# include "tags.h"
# include "sector.h"
# include "player.h"
# include "sprite.h"
# include "reserve.h"
# include "jsector.h"
# include "jtags.h"
# include "lists.h"
# include "pal.h"
# include "parent.h"
2019-10-09 16:09:05 +00:00
BEGIN_SW_NS
2015-05-19 21:54:34 +00:00
// V A R I A B L E D E C L A R A T I O N S //////////////////////////////////////////////////////
MIRRORTYPE mirror [ MAXMIRRORS ] ;
short mirrorcnt ; //, floormirrorcnt;
//short floormirrorsector[MAXMIRRORS];
2015-05-19 21:58:29 +00:00
SWBOOL mirrorinview ;
2015-05-19 21:54:34 +00:00
static char tempbuf [ /*max(576, */ MAXXDIM /*)*/ ] ;
2015-05-19 21:58:29 +00:00
SWBOOL MirrorMoveSkip16 = 0 ;
2015-05-19 21:54:34 +00:00
// Voxel stuff
2015-05-19 21:58:29 +00:00
//SWBOOL bVoxelsOn = TRUE; // Turn voxels on by default
SWBOOL bSpinBobVoxels = FALSE ; // Do twizzly stuff to voxels, but
2015-05-19 21:54:34 +00:00
// not by default
2015-05-19 21:58:29 +00:00
SWBOOL bAutoSize = TRUE ; // Autosizing on/off
2015-05-19 21:54:34 +00:00
//extern int chainnumpages;
extern AMB_INFO ambarray [ ] ;
extern short NormalVisibility ;
extern ParentalStruct aVoxelArray [ MAXTILES ] ;
// F U N C T I O N S //////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////
// SpawnWallSound
/////////////////////////////////////////////////////
2019-11-17 17:02:17 +00:00
void SpawnWallSound ( short sndnum , short i )
2015-05-19 21:54:34 +00:00
{
short SpriteNum ;
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
vec3_t mid ;
2015-05-19 21:54:34 +00:00
SPRITEp sp ;
SpriteNum = COVERinsertsprite ( 0 , STAT_DEFAULT ) ;
if ( SpriteNum < 0 )
return ;
sp = & sprite [ SpriteNum ] ;
sp - > cstat = 0 ;
sp - > extra = 0 ;
// Get wall midpoint for offset in mirror view
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
mid . x = ( wall [ i ] . x + wall [ wall [ i ] . point2 ] . x ) / 2 ;
mid . y = ( wall [ i ] . y + wall [ wall [ i ] . point2 ] . y ) / 2 ;
mid . z = ( sector [ wall [ i ] . nextsector ] . ceilingz + sector [ wall [ i ] . nextsector ] . floorz ) / 2 ;
setspritez ( SpriteNum , & mid ) ;
2015-05-19 21:54:34 +00:00
sp = & sprite [ SpriteNum ] ;
2019-12-18 18:17:37 +00:00
PlaySound ( sndnum , sp , v3df_dontpan | v3df_doppler ) ;
2015-05-19 21:54:34 +00:00
}
short
CheckTileSound ( short picnum )
{
short sndnum = - 1 ;
switch ( picnum )
{
case 163 : // Sizzly Lava
case 167 :
sndnum = DIGI_VOLCANOSTEAM1 ;
break ;
case 175 : // Flowing Lava
sndnum = DIGI_ERUPTION ;
break ;
case 179 : // Bubbly lava
sndnum = DIGI_LAVAFLOW1 ;
break ;
case 300 : // Water fall tile
sndnum = DIGI_WATERFALL1 ;
break ;
case 334 : // Teleporter Pad
sndnum = DIGI_ENGROOM1 ;
break ;
case 2690 : // Jet engine fan
sndnum = DIGI_JET ;
break ;
case 2672 : // X-Ray Machine engine
sndnum = DIGI_ENGROOM5 ;
break ;
case 768 : // Electricity
// sndnum = DIGI_;
break ;
case 2714 : // Pachinko Machine
// sndnum = DIGI_;
break ;
case 2782 : // Telepad
sndnum = DIGI_ENGROOM4 ;
break ;
case 3382 : // Gears
sndnum = DIGI_ENGROOM5 ;
break ;
case 2801 : // Computers
case 2804 :
case 2807 :
case 3352 :
case 3385 :
case 3389 :
case 3393 :
case 3397 :
case 3401 :
case 3405 :
// sndnum = DIGI_;
break ;
case 3478 : // Radar screen
// sndnum = DIGI_;
break ;
default :
sndnum = - 1 ;
break ;
}
return sndnum ;
}
2019-10-09 17:58:09 +00:00
ANIMATOR GenerateDrips ;
2015-05-19 21:54:34 +00:00
/////////////////////////////////////////////////////
// Initialize any of my special use sprites
/////////////////////////////////////////////////////
void
JS_SpriteSetup ( void )
{
SPRITEp sp ;
short SpriteNum = 0 , NextSprite , ndx ;
USERp u ;
short i , num ;
TRAVERSE_SPRITE_STAT ( headspritestat [ 0 ] , SpriteNum , NextSprite )
{
short tag ;
short bit ;
sp = & sprite [ SpriteNum ] ;
tag = sp - > hitag ;
// Non static camera. Camera sprite will be drawn!
if ( tag = = MIRROR_CAM & & sprite [ SpriteNum ] . picnum ! = ST1 )
{
// Just change it to static, sprite has all the info I need
// u = SpawnUser(SpriteNum, sp->picnum, NULL);
// RESET(sp->cstat, CSTAT_SPRITE_BLOCK);
// SET(sp->cstat, CSTAT_SPRITE_BLOCK_HITSCAN);
change_sprite_stat ( SpriteNum , STAT_SPAWN_SPOT ) ;
}
switch ( sprite [ SpriteNum ] . picnum )
{
case ST1 :
if ( tag = = MIRROR_CAM )
{
// Just change it to static, sprite has all the info I need
// ST1 cameras won't move with SOBJ's!
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
}
else if ( tag = = MIRROR_SPAWNSPOT )
{
// Just change it to static, sprite has all the info I need
change_sprite_stat ( SpriteNum , STAT_ST1 ) ;
}
else if ( tag = = AMBIENT_SOUND )
{
change_sprite_stat ( SpriteNum , STAT_AMBIENT ) ;
}
else if ( tag = = TAG_ECHO_SOUND )
{
change_sprite_stat ( SpriteNum , STAT_ECHO ) ;
}
else if ( tag = = TAG_DRIPGEN )
{
u = SpawnUser ( SpriteNum , 0 , NULL ) ;
ASSERT ( u ! = NULL ) ;
u - > RotNum = 0 ;
u - > WaitTics = sp - > lotag * 120 ;
u - > ActorActionFunc = GenerateDrips ;
change_sprite_stat ( SpriteNum , STAT_NO_STATE ) ;
SET ( sp - > cstat , CSTAT_SPRITE_INVISIBLE ) ;
}
break ;
// Sprites in editart that should play ambient sounds
// automatically
case 380 :
case 396 :
case 430 :
case 443 :
case 512 :
case 521 :
case 541 :
case 2720 :
case 3143 :
case 3157 :
2019-12-18 18:17:37 +00:00
PlaySound ( DIGI_FIRE1 , sp , v3df_follow | v3df_dontpan | v3df_doppler ) ;
2015-05-19 21:54:34 +00:00
break ;
case 795 :
case 880 :
2019-12-18 18:17:37 +00:00
PlaySound ( DIGI_WATERFLOW1 , sp , v3df_follow | v3df_dontpan | v3df_doppler ) ;
2015-05-19 21:54:34 +00:00
break ;
case 460 : // Wind Chimes
2019-12-19 00:20:43 +00:00
InitAmbient ( 79 , sp ) ;
2015-05-19 21:54:34 +00:00
break ;
}
}
// Check for certain walls to make sounds
for ( i = 0 ; i < numwalls ; i + + )
{
short picnum ;
short sndnum ;
picnum = wall [ i ] . picnum ;
// Set the don't stick bit for liquid tiles
switch ( picnum )
{
case 175 :
case 179 :
case 300 :
case 320 :
case 330 :
case 352 :
case 780 :
case 890 :
case 2608 :
case 2616 :
//case 3834:
SET ( wall [ i ] . extra , WALLFX_DONT_STICK ) ;
break ;
}
#if 0
if ( ( sndnum = CheckTileSound ( picnum ) ) ! = - 1 )
{
SpawnWallSound ( sndnum , i ) ;
}
picnum = wall [ i ] . overpicnum ;
if ( ( sndnum = CheckTileSound ( picnum ) ) ! = - 1 )
{
SpawnWallSound ( sndnum , i ) ;
}
# endif
}
}
/////////////////////////////////////////////////////
// Initialize the mirrors
/////////////////////////////////////////////////////
2019-11-17 17:02:17 +00:00
void JS_InitMirrors ( void )
2015-05-19 21:54:34 +00:00
{
short startwall , endwall , dasector ;
int i , j , k , s , dax , day , daz , dax2 , day2 ;
short SpriteNum = 0 , NextSprite ;
SPRITEp sp ;
static short on_cam = 0 ;
2015-05-19 21:58:29 +00:00
SWBOOL Found_Cam = FALSE ;
2015-05-19 21:54:34 +00:00
// Set all the mirror struct values to -1
memset ( mirror , 0xFF , sizeof ( mirror ) ) ;
mirrorinview = FALSE ; // Initially set global mirror flag
// to no mirrors seen
// Scan wall tags for mirrors
mirrorcnt = 0 ;
2019-10-11 19:04:31 +00:00
tileDelete ( MIRROR ) ;
2015-05-19 21:54:34 +00:00
for ( i = 0 ; i < MAXMIRRORS ; i + + )
{
2019-10-11 19:04:31 +00:00
tileDelete ( i + MIRRORLABEL ) ;
2015-05-19 21:54:34 +00:00
mirror [ i ] . campic = - 1 ;
mirror [ i ] . camsprite = - 1 ;
mirror [ i ] . camera = - 1 ;
mirror [ i ] . ismagic = FALSE ;
}
for ( i = 0 ; i < numwalls ; i + + )
{
s = wall [ i ] . nextsector ;
if ( ( s > = 0 ) & & ( wall [ i ] . overpicnum = = MIRROR ) & & ( wall [ i ] . cstat & 32 ) )
{
if ( ( sector [ s ] . floorstat & 1 ) = = 0 )
{
wall [ i ] . overpicnum = MIRRORLABEL + mirrorcnt ;
wall [ i ] . picnum = MIRRORLABEL + mirrorcnt ;
sector [ s ] . ceilingpicnum = MIRRORLABEL + mirrorcnt ;
sector [ s ] . floorpicnum = MIRRORLABEL + mirrorcnt ;
sector [ s ] . floorstat | = 1 ;
mirror [ mirrorcnt ] . mirrorwall = i ;
mirror [ mirrorcnt ] . mirrorsector = s ;
mirror [ mirrorcnt ] . numspawnspots = 0 ;
mirror [ mirrorcnt ] . ismagic = FALSE ;
if ( wall [ i ] . lotag = = TAG_WALL_MAGIC_MIRROR )
{
short ii , nextii ;
SPRITEp sp ;
USERp u ;
mirror [ mirrorcnt ] . ismagic = TRUE ;
Found_Cam = FALSE ;
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_ST1 ] , ii , nextii )
{
sp = & sprite [ ii ] ;
// if correct type and matches
if ( sp - > hitag = = MIRROR_CAM & & sp - > lotag = = wall [ i ] . hitag )
{
mirror [ mirrorcnt ] . camera = ii ;
// Set up camera varialbes
SP_TAG5 ( sp ) = sp - > ang ; // Set current angle to
// sprite angle
Found_Cam = TRUE ;
}
}
ii = nextii = 0 ;
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_SPAWN_SPOT ] , ii , nextii )
{
sp = & sprite [ ii ] ;
// if correct type and matches
if ( sp - > hitag = = MIRROR_CAM & & sp - > lotag = = wall [ i ] . hitag )
{
mirror [ mirrorcnt ] . camera = ii ;
// Set up camera varialbes
SP_TAG5 ( sp ) = sp - > ang ; // Set current angle to
// sprite angle
Found_Cam = TRUE ;
}
}
if ( ! Found_Cam )
{
2019-04-08 06:25:33 +00:00
printf ( " Cound not find the camera view sprite for match %d \n " , TrackerCast ( wall [ i ] . hitag ) ) ;
printf ( " Map Coordinates: x = %d, y = %d \n " , TrackerCast ( wall [ i ] . x ) , TrackerCast ( wall [ i ] . y ) ) ;
2015-05-19 21:54:34 +00:00
exit ( 0 ) ;
}
Found_Cam = FALSE ;
if ( TEST_BOOL1 ( & sprite [ mirror [ mirrorcnt ] . camera ] ) )
{
TRAVERSE_SPRITE_STAT ( headspritestat [ 0 ] , SpriteNum , NextSprite )
{
sp = & sprite [ SpriteNum ] ;
if ( sp - > picnum > = CAMSPRITE & & sp - > picnum < CAMSPRITE + 8 & &
sp - > hitag = = wall [ i ] . hitag )
{
mirror [ mirrorcnt ] . campic = sp - > picnum ;
mirror [ mirrorcnt ] . camsprite = SpriteNum ;
// JBF: commenting out this line results in the screen in $BULLET being visible
2019-10-11 19:04:31 +00:00
tileDelete ( mirror [ mirrorcnt ] . campic ) ;
2015-05-19 21:54:34 +00:00
Found_Cam = TRUE ;
}
}
if ( ! Found_Cam )
{
printf ( " Did not find drawtotile for camera number %d \n " , mirrorcnt ) ;
2019-04-08 06:25:33 +00:00
printf ( " wall[%d].hitag == %d \n " , i , TrackerCast ( wall [ i ] . hitag ) ) ;
printf ( " Map Coordinates: x = %d, y = %d \n " , TrackerCast ( wall [ i ] . x ) , TrackerCast ( wall [ i ] . y ) ) ;
2015-05-19 21:54:34 +00:00
exit ( 0 ) ;
}
}
// For magic mirrors, set allowable viewing time to 30
// secs
// Base rate is supposed to be 120, but time is double
// what I expect
mirror [ mirrorcnt ] . maxtics = 60 * 30 ;
}
mirror [ mirrorcnt ] . mstate = m_normal ;
// Set tics used to none
mirror [ mirrorcnt ] . tics = 0 ;
if ( mirror [ mirrorcnt ] . ismagic )
{
//DSPRINTF(ds, "mirror.mirrorwall %d", mirror[mirrorcnt].mirrorwall);
MONO_PRINT ( ds ) ;
//DSPRINTF(ds, "mirror.mirrorsector %d", mirror[mirrorcnt].mirrorsector);
MONO_PRINT ( ds ) ;
//DSPRINTF(ds, "mirror.camera %d", mirror[mirrorcnt].camera);
MONO_PRINT ( ds ) ;
}
mirrorcnt + + ;
ASSERT ( mirrorcnt < MAXMIRRORS ) ;
}
else
wall [ i ] . overpicnum = sector [ s ] . ceilingpicnum ;
}
}
// Invalidate textures in sector behind mirror
for ( i = 0 ; i < mirrorcnt ; i + + )
{
startwall = sector [ mirror [ i ] . mirrorsector ] . wallptr ;
endwall = startwall + sector [ mirror [ i ] . mirrorsector ] . wallnum ;
for ( j = startwall ; j < endwall ; j + + )
{
wall [ j ] . picnum = MIRROR ;
wall [ j ] . overpicnum = MIRROR ;
}
}
} // InitMirrors
/////////////////////////////////////////////////////
// Draw a 3d screen to a specific tile
/////////////////////////////////////////////////////
void drawroomstotile ( int daposx , int daposy , int daposz ,
short daang , int dahoriz , short dacursectnum , short tilenume )
{
2019-10-15 21:18:52 +00:00
TileFiles . tileCreate ( tilenume , tilesiz [ tilenume ] . x , tilesiz [ tilenume ] . y ) ;
2015-05-19 21:54:34 +00:00
2019-04-08 06:26:36 +00:00
renderSetTarget ( tilenume , tilesiz [ tilenume ] . x , tilesiz [ tilenume ] . y ) ;
2015-05-19 21:54:34 +00:00
drawrooms ( daposx , daposy , daposz , daang , dahoriz , dacursectnum ) ;
analyzesprites ( daposx , daposy , daposz , FALSE ) ;
2019-04-08 06:26:36 +00:00
renderDrawMasks ( ) ;
2015-05-19 21:54:34 +00:00
2019-04-08 06:26:36 +00:00
renderRestoreTarget ( ) ;
2015-05-19 21:54:34 +00:00
squarerotatetile ( tilenume ) ;
2019-04-08 06:26:36 +00:00
tileInvalidate ( tilenume , - 1 , - 1 ) ;
2015-05-19 21:54:34 +00:00
}
void
JS_ProcessEchoSpot ( )
{
short i , nexti ;
SPRITEp tp ;
int j , dist ;
PLAYERp pp = Player + screenpeek ;
2015-05-19 21:58:29 +00:00
int16_t reverb ;
SWBOOL reverb_set = FALSE ;
2015-05-19 21:54:34 +00:00
// Process echo sprites
TRAVERSE_SPRITE_STAT ( headspritestat [ STAT_ECHO ] , i , nexti )
{
dist = 0x7fffffff ;
tp = & sprite [ i ] ;
j = klabs ( tp - > x - pp - > posx ) ;
j + = klabs ( tp - > y - pp - > posy ) ;
if ( j < dist )
dist = j ;
if ( dist < = SP_TAG4 ( tp ) ) // tag4 = ang
{
reverb = SP_TAG2 ( tp ) ;
if ( reverb > 200 ) reverb = 200 ;
if ( reverb < 100 ) reverb = 100 ;
COVER_SetReverb ( reverb ) ;
reverb_set = TRUE ;
}
}
if ( ! TEST ( pp - > Flags , PF_DIVING ) & & ! reverb_set & & pp - > Reverb < = 0 )
COVER_SetReverb ( 0 ) ;
}
/////////////////////////////////////////////////////
// Draw one mirror, the one closest to player
// Cams and see to teleporters do NOT support room above room!
/////////////////////////////////////////////////////
# define MAXCAMDIST 8000
int camloopcnt = 0 ; // Timer to cycle through player
// views
short camplayerview = 1 ; // Don't show yourself!
void
JS_DrawMirrors ( PLAYERp pp , int tx , int ty , int tz , short tpang , int tphoriz )
{
int j , dx , dy , top , bot , cnt ;
int x1 , y1 , x2 , y2 , ox1 , oy1 , ox2 , oy2 , dist , maxdist ;
int tposx , tposy , thoriz ;
int tcx , tcy , tcz ; // Camera
int tiltlock , * longptr ;
2019-04-08 06:26:36 +00:00
fix16_t tang ;
2015-05-19 21:54:34 +00:00
char ch , * ptr , * ptr2 , * ptr3 , * ptr4 ;
char tvisibility , palok ;
2019-11-17 17:02:17 +00:00
// int tx, ty, tz, tpang; // Interpolate so mirror doesn't
2015-05-19 21:54:34 +00:00
// drift!
2015-05-19 21:58:29 +00:00
SWBOOL bIsWallMirror = FALSE ;
2015-05-19 21:54:34 +00:00
MirrorMoveSkip16 = ( MirrorMoveSkip16 + 1 ) & 15 ;
2019-08-27 13:39:54 +00:00
camloopcnt + = ( int32_t ) ( totalclock - ototalclock ) ;
2015-05-19 21:54:34 +00:00
if ( camloopcnt > ( 60 * 5 ) ) // 5 seconds per player view
{
camloopcnt = 0 ;
camplayerview + + ;
if ( camplayerview > = numplayers )
camplayerview = 1 ;
}
// WARNING! Assuming (MIRRORLABEL&31) = 0 and MAXMIRRORS = 64 <-- JBF: wrong
longptr = ( int * ) & gotpic [ MIRRORLABEL > > 3 ] ;
if ( longptr & & ( longptr [ 0 ] | | longptr [ 1 ] ) )
{
for ( cnt = MAXMIRRORS - 1 ; cnt > = 0 ; cnt - - )
//if (TEST_GOTPIC(cnt + MIRRORLABEL) || TEST_GOTPIC(cnt + CAMSPRITE))
2019-11-26 08:24:23 +00:00
if ( TEST_GOTPIC ( cnt + MIRRORLABEL ) | | ( ( unsigned ) mirror [ cnt ] . campic < MAXTILES & & TEST_GOTPIC ( mirror [ cnt ] . campic ) ) )
2015-05-19 21:54:34 +00:00
{
bIsWallMirror = FALSE ;
if ( TEST_GOTPIC ( cnt + MIRRORLABEL ) )
{
bIsWallMirror = TRUE ;
RESET_GOTPIC ( cnt + MIRRORLABEL ) ;
}
//else if (TEST_GOTPIC(cnt + CAMSPRITE))
2019-11-26 08:24:23 +00:00
else if ( ( unsigned ) mirror [ cnt ] . campic < MAXTILES & & TEST_GOTPIC ( mirror [ cnt ] . campic ) )
2015-05-19 21:54:34 +00:00
{
//RESET_GOTPIC(cnt + CAMSPRITE);
RESET_GOTPIC ( mirror [ cnt ] . campic ) ;
}
mirrorinview = TRUE ;
2017-06-24 09:20:21 +00:00
// tx = pp->oposx + mulscale16(pp->posx - pp->oposx, smoothratio);
// ty = pp->oposy + mulscale16(pp->posy - pp->oposy, smoothratio);
// tz = pp->oposz + mulscale16(pp->posz - pp->oposz, smoothratio);
// tpang = pp->oang + mulscale16(((pp->pang + 1024 - pp->oang) & 2047) - 1024, smoothratio);
2015-05-19 21:54:34 +00:00
dist = 0x7fffffff ;
if ( bIsWallMirror )
{
j = klabs ( wall [ mirror [ cnt ] . mirrorwall ] . x - tx ) ;
j + = klabs ( wall [ mirror [ cnt ] . mirrorwall ] . y - ty ) ;
if ( j < dist )
dist = j ;
}
else
{
SPRITEp tp ;
tp = & sprite [ mirror [ cnt ] . camsprite ] ;
j = klabs ( tp - > x - tx ) ;
j + = klabs ( tp - > y - ty ) ;
if ( j < dist )
dist = j ;
}
// //DSPRINTF(ds,"mirror.tics == %ul", mirror[i].tics);
// MONO_PRINT(ds);
if ( mirror [ cnt ] . ismagic )
{
SPRITEp sp = NULL ;
int camhoriz ;
short wall_ang , w , nw , da , tda ;
int dx , dy , dz , tdx , tdy , tdz , midx , midy ;
ASSERT ( mirror [ cnt ] . camera ! = - 1 ) ;
sp = & sprite [ mirror [ cnt ] . camera ] ;
ASSERT ( sp ) ;
2015-05-19 22:03:30 +00:00
// tvisibility = g_visibility;
// g_visibility <<= 1; // Make mirror darker
2015-05-19 21:54:34 +00:00
// Make TV cam style mirror seem to shimmer
// if (mirror[cnt].ismagic && STD_RANDOM_P2(256) > 128)
2015-05-19 22:03:30 +00:00
// g_visibility -= STD_RANDOM_P2(128);
2015-05-19 21:54:34 +00:00
// Calculate the angle of the mirror wall
w = mirror [ cnt ] . mirrorwall ;
nw = wall [ w ] . point2 ;
// Get wall midpoint for offset in mirror view
midx = ( wall [ w ] . x + wall [ wall [ w ] . point2 ] . x ) / 2 ;
midy = ( wall [ w ] . y + wall [ wall [ w ] . point2 ] . y ) / 2 ;
// Finish finding offsets
tdx = klabs ( midx - tx ) ;
tdy = klabs ( midy - ty ) ;
if ( midx > = tx )
dx = sp - > x - tdx ;
else
dx = sp - > x + tdx ;
if ( midy > = ty )
dy = sp - > y - tdy ;
else
dy = sp - > y + tdy ;
tdz = klabs ( tz - sp - > z ) ;
if ( tz > = sp - > z )
dz = sp - > z + tdz ;
else
dz = sp - > z - tdz ;
// Is it a TV cam or a teleporter that shows destination?
// TRUE = It's a TV cam
mirror [ cnt ] . mstate = m_normal ;
if ( TEST_BOOL1 ( sp ) )
mirror [ cnt ] . mstate = m_viewon ;
// Show teleport destination
// NOTE: Adding MAXSECTORS lets you draw a room, even if
// you are outside of it!
2019-04-08 06:27:58 +00:00
if ( mirror [ cnt ] . mstate ! = m_viewon )
2015-05-19 21:54:34 +00:00
{
2019-10-11 19:04:31 +00:00
tileDelete ( MIRROR ) ;
2015-05-19 21:54:34 +00:00
// Set TV camera sprite size to 0 to show mirror
// behind in this case!
if ( mirror [ cnt ] . campic ! = - 1 )
2019-10-11 19:04:31 +00:00
tileDelete ( mirror [ cnt ] . campic ) ;
2015-05-19 21:54:34 +00:00
drawrooms ( dx , dy , dz , tpang , tphoriz , sp - > sectnum + MAXSECTORS ) ;
analyzesprites ( dx , dy , dz , FALSE ) ;
2019-04-08 06:26:36 +00:00
renderDrawMasks ( ) ;
2015-05-19 21:54:34 +00:00
}
else
{
2015-05-19 21:58:29 +00:00
SWBOOL DoCam = FALSE ;
2015-05-19 21:54:34 +00:00
if ( mirror [ cnt ] . campic = = - 1 )
{
TerminateGame ( ) ;
printf ( " Missing campic for mirror %d \n " , cnt ) ;
printf ( " Map Coordinates: x = %d, y = %d \n " , midx , midy ) ;
exit ( 0 ) ;
}
// BOOL2 = Oscilate camera
if ( TEST_BOOL2 ( sp ) & & MoveSkip2 = = 0 )
{
if ( TEST_BOOL3 ( sp ) ) // If true add increment to
// angle else subtract
{
// Store current angle in TAG5
SP_TAG5 ( sp ) = NORM_ANGLE ( ( SP_TAG5 ( sp ) + 4 ) ) ;
// TAG6 = Turn radius
if ( klabs ( GetDeltaAngle ( SP_TAG5 ( sp ) , sp - > ang ) ) > = SP_TAG6 ( sp ) )
{
RESET_BOOL3 ( sp ) ; // Reverse turn
// direction.
}
}
else
{
// Store current angle in TAG5
SP_TAG5 ( sp ) = NORM_ANGLE ( ( SP_TAG5 ( sp ) - 4 ) ) ;
// TAG6 = Turn radius
if ( klabs ( GetDeltaAngle ( SP_TAG5 ( sp ) , sp - > ang ) ) > = SP_TAG6 ( sp ) )
{
SET_BOOL3 ( sp ) ; // Reverse turn
// direction.
}
}
}
else if ( ! TEST_BOOL2 ( sp ) )
{
SP_TAG5 ( sp ) = sp - > ang ; // Copy sprite angle to
// tag5
}
// See if there is a horizon value. 0 defaults to
// 100!
if ( SP_TAG7 ( sp ) ! = 0 )
{
camhoriz = SP_TAG7 ( sp ) ;
if ( camhoriz > PLAYER_HORIZ_MAX )
camhoriz = PLAYER_HORIZ_MAX ;
else if ( camhoriz < PLAYER_HORIZ_MIN )
camhoriz = PLAYER_HORIZ_MIN ;
}
else
camhoriz = 100 ; // Default
// If player is dead still then update at MoveSkip4
// rate.
if ( pp - > posx = = pp - > oposx & & pp - > posy = = pp - > oposy & & pp - > posz = = pp - > oposz )
DoCam = TRUE ;
// Set up the tile for drawing
2019-10-15 21:18:52 +00:00
TileFiles . tileCreate ( mirror [ cnt ] . campic , 128 , 128 ) ;
2015-05-19 21:54:34 +00:00
if ( MirrorMoveSkip16 = = 0 | | ( DoCam & & ( MoveSkip4 = = 0 ) ) )
{
if ( dist < MAXCAMDIST )
{
PLAYERp cp = Player + camplayerview ;
if ( TEST_BOOL11 ( sp ) & & numplayers > 1 )
{
drawroomstotile ( cp - > posx , cp - > posy , cp - > posz , cp - > pang , cp - > horiz , cp - > cursectnum , mirror [ cnt ] . campic ) ;
}
else
{
drawroomstotile ( sp - > x , sp - > y , sp - > z , SP_TAG5 ( sp ) , camhoriz , sp - > sectnum , mirror [ cnt ] . campic ) ;
}
}
}
}
}
else
{
// It's just a mirror
// Prepare drawrooms for drawing mirror and calculate
// reflected
// position into tposx, tposy, and tang (tposz == cposz)
// Must call preparemirror before drawrooms and
// completemirror after drawrooms
2019-06-25 18:35:16 +00:00
renderPrepareMirror ( tx , ty , tz , fix16_from_int ( tpang ) , tphoriz ,
SW: setsprite, setspritez, getzrange, clipmove, pushmove, neartag, dragpoint, screencapture, md_tilehasmodel, preparemirror, saveboard, loadboard, pos
git-svn-id: https://svn.eduke32.com/eduke32@5201 1a8010ca-5511-0410-912e-c29ae57300e0
2015-05-19 22:00:38 +00:00
mirror [ cnt ] . mirrorwall , /*mirror[cnt].mirrorsector,*/ & tposx , & tposy , & tang ) ;
2015-05-19 21:54:34 +00:00
2019-04-08 06:26:36 +00:00
drawrooms ( tposx , tposy , tz , fix16_to_int ( tang ) , tphoriz , mirror [ cnt ] . mirrorsector + MAXSECTORS ) ;
2015-05-19 21:54:34 +00:00
analyzesprites ( tposx , tposy , tz , TRUE ) ;
2019-04-08 06:26:36 +00:00
renderDrawMasks ( ) ;
2015-05-19 21:54:34 +00:00
2019-04-08 06:26:36 +00:00
renderCompleteMirror ( ) ; // Reverse screen x-wise in this
2015-05-19 21:54:34 +00:00
// function
}
2015-05-19 22:03:30 +00:00
// g_visibility = tvisibility;
// g_visibility = NormalVisibility;
2015-05-19 21:54:34 +00:00
// drawrooms(tx, ty, tz, tpang, tphoriz, pp->cursectnum);
// Clean up anything that the camera view might have done
SetFragBar ( pp ) ;
2019-10-11 19:04:31 +00:00
tileDelete ( MIRROR ) ;
2015-05-19 21:54:34 +00:00
wall [ mirror [ cnt ] . mirrorwall ] . overpicnum = MIRRORLABEL + cnt ;
}
else
mirrorinview = FALSE ;
}
}
void
2017-01-23 11:21:08 +00:00
DoAutoSize ( uspritetype * tspr )
2015-05-19 21:54:34 +00:00
{
short i ;
if ( ! bAutoSize )
return ;
switch ( tspr - > picnum )
{
case ICON_STAR : // 1793
break ;
case ICON_UZI : // 1797
tspr - > xrepeat = 43 ;
tspr - > yrepeat = 40 ;
break ;
case ICON_UZIFLOOR : // 1807
tspr - > xrepeat = 43 ;
tspr - > yrepeat = 40 ;
break ;
case ICON_LG_UZI_AMMO : // 1799
break ;
case ICON_HEART : // 1824
break ;
case ICON_HEART_LG_AMMO : // 1820
break ;
case ICON_GUARD_HEAD : // 1814
break ;
case ICON_FIREBALL_LG_AMMO : // 3035
break ;
case ICON_ROCKET : // 1843
break ;
case ICON_SHOTGUN : // 1794
tspr - > xrepeat = 57 ;
tspr - > yrepeat = 58 ;
break ;
case ICON_LG_ROCKET : // 1796
break ;
case ICON_LG_SHOTSHELL : // 1823
break ;
case ICON_MICRO_GUN : // 1818
break ;
case ICON_MICRO_BATTERY : // 1800
break ;
case ICON_GRENADE_LAUNCHER : // 1817
tspr - > xrepeat = 54 ;
tspr - > yrepeat = 52 ;
break ;
case ICON_LG_GRENADE : // 1831
break ;
case ICON_LG_MINE : // 1842
break ;
case ICON_RAIL_GUN : // 1811
tspr - > xrepeat = 50 ;
tspr - > yrepeat = 54 ;
break ;
case ICON_RAIL_AMMO : // 1812
break ;
case ICON_SM_MEDKIT : // 1802
break ;
case ICON_MEDKIT : // 1803
break ;
case ICON_CHEMBOMB :
tspr - > xrepeat = 64 ;
tspr - > yrepeat = 47 ;
break ;
case ICON_FLASHBOMB :
tspr - > xrepeat = 32 ;
tspr - > yrepeat = 34 ;
break ;
case ICON_NUKE :
break ;
case ICON_CALTROPS :
tspr - > xrepeat = 37 ;
tspr - > yrepeat = 30 ;
break ;
case ICON_BOOSTER : // 1810
tspr - > xrepeat = 30 ;
tspr - > yrepeat = 38 ;
break ;
case ICON_HEAT_CARD : // 1819
tspr - > xrepeat = 46 ;
tspr - > yrepeat = 47 ;
break ;
case ICON_REPAIR_KIT : // 1813
break ;
case ICON_EXPLOSIVE_BOX : // 1801
break ;
case ICON_ENVIRON_SUIT : // 1837
break ;
case ICON_FLY : // 1782
break ;
case ICON_CLOAK : // 1826
break ;
case ICON_NIGHT_VISION : // 3031
tspr - > xrepeat = 59 ;
tspr - > yrepeat = 71 ;
break ;
case ICON_NAPALM : // 3046
break ;
case ICON_RING : // 3050
break ;
case ICON_RINGAMMO : // 3054
break ;
case ICON_NAPALMAMMO : // 3058
break ;
case ICON_GRENADE : // 3059
break ;
case ICON_ARMOR : // 3030
tspr - > xrepeat = 82 ;
tspr - > yrepeat = 84 ;
break ;
case BLUE_KEY : // 1766
break ;
case RED_KEY : // 1770
break ;
case GREEN_KEY : // 1774
break ;
case YELLOW_KEY : // 1778
break ;
case BLUE_CARD :
case RED_CARD :
case GREEN_CARD :
case YELLOW_CARD :
tspr - > xrepeat = 36 ;
tspr - > yrepeat = 33 ;
break ;
case GOLD_SKELKEY :
case SILVER_SKELKEY :
case BRONZE_SKELKEY :
case RED_SKELKEY :
tspr - > xrepeat = 39 ;
tspr - > yrepeat = 45 ;
break ;
case SKEL_LOCKED :
case SKEL_UNLOCKED :
tspr - > xrepeat = 47 ;
tspr - > yrepeat = 40 ;
break ;
case RAMCARD_LOCKED :
case RAMCARD_UNLOCKED :
case CARD_LOCKED :
case CARD_UNLOCKED :
break ;
default :
break ;
}
}
// Rotation angles for sprites
short rotang = 0 ;
2019-11-17 17:02:17 +00:00
void JAnalyzeSprites ( uspritetype * tspr )
2015-05-19 21:54:34 +00:00
{
int i , currsprite ;
rotang + = 4 ;
if ( rotang > 2047 )
rotang = 0 ;
// Take care of autosizing
DoAutoSize ( tspr ) ;
2019-10-23 19:11:37 +00:00
if ( videoGetRenderMode ( ) > = REND_POLYMOST & & md_tilehasmodel ( tspr - > picnum , 0 ) > = 0 & & hw_models ) return ;
2015-05-19 21:54:34 +00:00
// Check for voxels
//if (bVoxelsOn)
2019-10-27 15:53:00 +00:00
if ( r_voxels )
2015-05-19 21:54:34 +00:00
{
if ( aVoxelArray [ tspr - > picnum ] . Voxel > = 0 )
{
// Turn on voxels
tspr - > picnum = aVoxelArray [ tspr - > picnum ] . Voxel ; // Get the voxel number
tspr - > cstat | = 48 ; // Set stat to voxelize sprite
}
}
else
{
switch ( tspr - > picnum )
{
case 764 : // Gun barrel
if ( aVoxelArray [ tspr - > picnum ] . Voxel > = 0 )
{
// Turn on voxels
tspr - > picnum = aVoxelArray [ tspr - > picnum ] . Voxel ; // Get the voxel number
tspr - > cstat | = 48 ; // Set stat to voxelize sprite
}
break ;
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
// Parental Lockout Stuff
//////////////////////////////////////////////////////////////////////////////////////////////
OrgTileList orgwalllist ; // The list containing orginal wall
// pics
OrgTileList orgwalloverlist ; // The list containing orginal wall
// over pics
OrgTileList orgsectorceilinglist ; // The list containing orginal sector
// ceiling pics
OrgTileList orgsectorfloorlist ; // The list containing orginal sector
// floor pics
void
InsertOrgTile ( OrgTileP tp , OrgTileListP thelist )
{
OrgTileP cur , nxt ;
ASSERT ( tp ) ;
ASSERT ( ValidPtr ( tp ) ) ;
// if list is empty, insert at front
if ( EMPTY ( thelist ) )
{
INSERT ( thelist , tp ) ;
return ;
}
// Otherwise insert it at end
INSERT_TAIL ( thelist , tp ) ;
return ;
}
OrgTileP
InitOrgTile ( OrgTileListP thelist )
{
int i ;
OrgTileP tp ;
2019-04-08 06:25:59 +00:00
tp = ( OrgTileP ) CallocMem ( sizeof ( OrgTile ) , 1 ) ;
2015-05-19 21:54:34 +00:00
ASSERT ( tp ) ;
InsertOrgTile ( tp , thelist ) ;
return tp ;
}
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
KillOrgTile ( OrgTileP tp )
{
ASSERT ( tp ) ;
ASSERT ( ValidPtr ( tp ) ) ;
2015-05-19 21:59:39 +00:00
REMOVE ( tp ) ;
2015-05-19 21:54:34 +00:00
FreeMem ( tp ) ;
}
OrgTileP
FindOrgTile ( short index , OrgTileListP thelist )
{
OrgTileP tp , next_tp ;
if ( EMPTY ( thelist ) )
return NULL ;
TRAVERSE ( thelist , tp , next_tp )
{
if ( tp - > index = = index )
return tp ;
}
return NULL ;
}
// Call this at terminate game time
2015-05-19 21:58:29 +00:00
void
2015-05-19 21:54:34 +00:00
JS_UnInitLockouts ( void )
{
OrgTileP tp = NULL , next_tp = NULL ;
TRAVERSE ( & orgwalllist , tp , next_tp )
{
KillOrgTile ( tp ) ;
}
TRAVERSE ( & orgwalloverlist , tp , next_tp )
{
KillOrgTile ( tp ) ;
}
TRAVERSE ( & orgsectorceilinglist , tp , next_tp )
{
KillOrgTile ( tp ) ;
}
TRAVERSE ( & orgsectorfloorlist , tp , next_tp )
{
KillOrgTile ( tp ) ;
}
}
/////////////////////////////////////////////////////
// Initialize the original tiles list
// Creates a list of all orginal tiles and their
// replacements. Several tiles can use the same
// replacement tilenum, so the list is built
// using the original tilenums as a basis for
// memory allocation
// t == 1 - wall
// t == 2 - overpicnum
// t == 3 - ceiling
// t == 4 - floor
/////////////////////////////////////////////////////
void
JS_PlockError ( short wall_num , short t )
{
TerminateGame ( ) ;
printf ( " ERROR: JS_InitLockouts(), out of range tile number \n " ) ;
switch ( t )
{
case 1 :
2019-04-08 06:25:33 +00:00
printf ( " wall %d, x %d, y %d, pic %d \n " , wall_num , TrackerCast ( wall [ wall_num ] . x ) , TrackerCast ( wall [ wall_num ] . y ) , TrackerCast ( wall [ wall_num ] . picnum ) ) ;
2015-05-19 21:54:34 +00:00
break ;
case 2 :
2019-04-08 06:25:33 +00:00
printf ( " wall %d, x %d, y %d, OVERpic %d \n " , wall_num , TrackerCast ( wall [ wall_num ] . x ) , TrackerCast ( wall [ wall_num ] . y ) , TrackerCast ( wall [ wall_num ] . overpicnum ) ) ;
2015-05-19 21:54:34 +00:00
break ;
case 3 :
2019-04-08 06:25:33 +00:00
printf ( " sector %d, ceiling %d \n " , wall_num , TrackerCast ( sector [ wall_num ] . ceilingpicnum ) ) ;
2015-05-19 21:54:34 +00:00
break ;
case 4 :
2019-04-08 06:25:33 +00:00
printf ( " sector %d, floor %d \n " , wall_num , TrackerCast ( sector [ wall_num ] . floorpicnum ) ) ;
2015-05-19 21:54:34 +00:00
break ;
}
exit ( 0 ) ;
}
void
JS_InitLockouts ( void )
{
SPRITEp sp ;
short i , num ;
OrgTileP tp ;
INITLIST ( & orgwalllist ) ; // The list containing orginal wall
// pics
INITLIST ( & orgwalloverlist ) ; // The list containing orginal wall
// over pics
INITLIST ( & orgsectorceilinglist ) ; // The list containing orginal sector
// ceiling pics
INITLIST ( & orgsectorfloorlist ) ; // The list containing orginal sector
// floor pics
// Check all walls
for ( i = 0 ; i < numwalls ; i + + )
{
short picnum ;
picnum = wall [ i ] . picnum ;
if ( aVoxelArray [ picnum ] . Parental > = INVISTILE )
JS_PlockError ( i , 1 ) ;
if ( aVoxelArray [ picnum ] . Parental > = 0 )
{
if ( ( tp = FindOrgTile ( i , & orgwalllist ) ) = = NULL )
tp = InitOrgTile ( & orgwalllist ) ;
tp - > index = i ;
tp - > orgpicnum = wall [ i ] . picnum ;
}
picnum = wall [ i ] . overpicnum ;
if ( aVoxelArray [ picnum ] . Parental > = INVISTILE )
JS_PlockError ( i , 2 ) ;
if ( aVoxelArray [ picnum ] . Parental > = 0 )
{
if ( ( tp = FindOrgTile ( i , & orgwalloverlist ) ) = = NULL )
tp = InitOrgTile ( & orgwalloverlist ) ;
tp - > index = i ;
tp - > orgpicnum = wall [ i ] . overpicnum ;
}
}
// Check all ceilings and floors
for ( i = 0 ; i < numsectors ; i + + )
{
short picnum ;
picnum = sector [ i ] . ceilingpicnum ;
if ( aVoxelArray [ picnum ] . Parental > = INVISTILE )
JS_PlockError ( i , 3 ) ;
if ( aVoxelArray [ picnum ] . Parental > = 0 )
{
if ( ( tp = FindOrgTile ( i , & orgsectorceilinglist ) ) = = NULL )
tp = InitOrgTile ( & orgsectorceilinglist ) ;
tp - > index = i ;
tp - > orgpicnum = sector [ i ] . ceilingpicnum ;
}
picnum = sector [ i ] . floorpicnum ;
if ( aVoxelArray [ picnum ] . Parental > = INVISTILE )
JS_PlockError ( i , 2 ) ;
if ( aVoxelArray [ picnum ] . Parental > = 0 )
{
if ( ( tp = FindOrgTile ( i , & orgsectorfloorlist ) ) = = NULL )
tp = InitOrgTile ( & orgsectorfloorlist ) ;
tp - > index = i ;
tp - > orgpicnum = sector [ i ] . floorpicnum ;
}
}
}
/////////////////////////////////////////////////////
// Switch back and forth between locked out stuff
/////////////////////////////////////////////////////
void
JS_ToggleLockouts ( void )
{
SPRITEp sp ;
short i , num ;
OrgTileP tp ;
// Check all walls
for ( i = 0 ; i < numwalls ; i + + )
{
short picnum ;
2019-10-27 12:40:24 +00:00
if ( adult_lockout )
2015-05-19 21:54:34 +00:00
{
picnum = wall [ i ] . picnum ;
ASSERT ( aVoxelArray [ picnum ] . Parental < INVISTILE ) ; // Invalid, walls can't
// be invisible
if ( aVoxelArray [ picnum ] . Parental > = 0 )
{
wall [ i ] . picnum = aVoxelArray [ picnum ] . Parental ;
}
}
else if ( ( tp = FindOrgTile ( i , & orgwalllist ) ) ! = NULL )
wall [ i ] . picnum = tp - > orgpicnum ; // Restore them
2019-10-27 12:40:24 +00:00
if ( adult_lockout )
2015-05-19 21:54:34 +00:00
{
picnum = wall [ i ] . overpicnum ;
ASSERT ( aVoxelArray [ picnum ] . Parental < INVISTILE ) ; // Invalid, walls can't
// be invisible
if ( aVoxelArray [ picnum ] . Parental > = 0 )
{
wall [ i ] . overpicnum = aVoxelArray [ picnum ] . Parental ;
}
}
else if ( ( tp = FindOrgTile ( i , & orgwalloverlist ) ) ! = NULL )
wall [ i ] . overpicnum = tp - > orgpicnum ; // Restore them
}
// Check all sectors
for ( i = 0 ; i < numsectors ; i + + )
{
short picnum ;
2019-10-27 12:40:24 +00:00
if ( adult_lockout )
2015-05-19 21:54:34 +00:00
{
picnum = sector [ i ] . ceilingpicnum ;
ASSERT ( aVoxelArray [ picnum ] . Parental < INVISTILE ) ; // Invalid, walls can't
// be invisible
if ( aVoxelArray [ picnum ] . Parental > = 0 )
{
sector [ i ] . ceilingpicnum = aVoxelArray [ picnum ] . Parental ;
}
}
else if ( ( tp = FindOrgTile ( i , & orgsectorceilinglist ) ) ! = NULL )
sector [ i ] . ceilingpicnum = tp - > orgpicnum ; // Restore them
2019-10-27 12:40:24 +00:00
if ( adult_lockout )
2015-05-19 21:54:34 +00:00
{
picnum = sector [ i ] . floorpicnum ;
ASSERT ( aVoxelArray [ picnum ] . Parental < INVISTILE ) ; // Invalid, walls can't
// be invisible
if ( aVoxelArray [ picnum ] . Parental > = 0 )
{
sector [ i ] . floorpicnum = aVoxelArray [ picnum ] . Parental ;
}
}
else if ( ( tp = FindOrgTile ( i , & orgsectorfloorlist ) ) ! = NULL )
sector [ i ] . floorpicnum = tp - > orgpicnum ; // Restore them
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void
2015-05-19 22:01:22 +00:00
UnlockKeyLock ( short key_num , short hit_sprite )
2015-05-19 21:54:34 +00:00
{
SPRITEp sp ;
int SpriteNum = 0 , NextSprite = 0 , color = 0 ;
// Get palette by looking at key number
switch ( key_num - 1 )
{
case 0 : // RED_KEY
color = PALETTE_PLAYER9 ;
break ;
case 1 : // BLUE_KEY
color = PALETTE_PLAYER7 ;
break ;
case 2 : // GREEN_KEY
color = PALETTE_PLAYER6 ;
break ;
case 3 : // YELLOW_KEY
color = PALETTE_PLAYER4 ;
break ;
case 4 : // SILVER_SKELKEY
color = PALETTE_PLAYER4 ;
break ;
case 5 : // GOLD_SKELKEY
color = PALETTE_PLAYER1 ;
break ;
case 6 : // BRONZE_SKELKEY
color = PALETTE_PLAYER8 ;
break ;
case 7 : // RED_SKELKEY
color = PALETTE_PLAYER9 ;
break ;
}
TRAVERSE_SPRITE_STAT ( headspritestat [ 0 ] , SpriteNum , NextSprite )
{
sp = & sprite [ SpriteNum ] ;
switch ( sp - > picnum )
{
case SKEL_LOCKED :
if ( sp - > pal = = color )
{
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_UNLOCK , sp , v3df_doppler | v3df_dontpan ) ;
2015-05-19 22:01:22 +00:00
if ( SpriteNum = = hit_sprite )
2015-05-19 21:54:34 +00:00
sp - > picnum = SKEL_UNLOCKED ;
}
break ;
case RAMCARD_LOCKED :
if ( sp - > pal = = color )
{
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_CARDUNLOCK , sp , v3df_doppler | v3df_dontpan ) ;
2015-05-19 21:54:34 +00:00
sp - > picnum = RAMCARD_UNLOCKED ;
}
break ;
case CARD_LOCKED :
if ( sp - > pal = = color )
{
2019-12-18 10:09:01 +00:00
PlaySound ( DIGI_RAMUNLOCK , sp , v3df_doppler | v3df_dontpan ) ;
2015-05-19 22:01:22 +00:00
if ( SpriteNum = = hit_sprite )
2015-05-19 21:54:34 +00:00
sp - > picnum = CARD_UNLOCKED ;
else
sp - > picnum = CARD_UNLOCKED + 1 ;
}
break ;
}
}
}
2019-10-09 16:09:05 +00:00
END_SW_NS