Take a stab at hidden model switch handling. There are at least two ways by

which switches have been hidden in the original and user maps. One is to make
it face a wall, and another is to 'embed' it in e.g. the floor, like the
monitor with the burning fuse in E4L1. Both kinds show up when the switches
are rendered as models, revealing the secrets that the mapper sought to hide.
My proposal, implemented in this commit, is to apply a heuristic for such
switches at premap and make them invisible (set cstat bit 32768). The
conditions are re-checked during the game in case there is a switch coming
out of the floor, for example. A new spriteext bit is used for this feature.

git-svn-id: https://svn.eduke32.com/eduke32@1968 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-08-17 18:52:16 +00:00
parent ff5c3b660f
commit 5d79003e60
3 changed files with 104 additions and 99 deletions

View file

@ -251,6 +251,7 @@ typedef struct {
#define SPREXT_AWAY1 4
#define SPREXT_AWAY2 8
#define SPREXT_TSPRACCESS 16
#define SPREXT_TEMPINVISIBLE 32
EXTERN spriteext_t *spriteext;
EXTERN spritesmooth_t *spritesmooth;

View file

@ -8093,6 +8093,7 @@ void G_MoveWorld(void)
int32_t i, p, j, k = MAXSTATUS-1, pl;
#ifdef POLYMER
int32_t numsavedfires = 0;
int32_t ii;
#endif
do
{
@ -8128,73 +8129,47 @@ void G_MoveWorld(void)
}
}
switch (DynamicTileMap[sprite[i].picnum-1])
{
case DIPSWITCH__STATIC:
case DIPSWITCH2__STATIC:
case DIPSWITCH3__STATIC:
case PULLSWITCH__STATIC:
case SLOTDOOR__STATIC:
case LIGHTSWITCH__STATIC:
case SPACELIGHTSWITCH__STATIC:
case SPACEDOORSWITCH__STATIC:
case FRANKENSTINESWITCH__STATIC:
case POWERSWITCH1__STATIC:
case LOCKSWITCH1__STATIC:
case POWERSWITCH2__STATIC:
case TECHSWITCH__STATIC:
case ACCESSSWITCH__STATIC:
case ACCESSSWITCH2__STATIC:
{
int32_t x, y;
if ((s->cstat & 32768) || A_CheckSpriteFlags(i, SPRITE_NOLIGHT) ||
!inside(s->x+((sintable[(s->ang+512)&2047])>>9), s->y+((sintable[(s->ang)&2047])>>9), s->sectnum))
for (ii=0; ii<2; ii++)
switch (DynamicTileMap[sprite[i].picnum-1+ii])
{
if (actor[i].lightptr != NULL)
case DIPSWITCH__STATIC:
case DIPSWITCH2__STATIC:
case DIPSWITCH3__STATIC:
case PULLSWITCH__STATIC:
case SLOTDOOR__STATIC:
case LIGHTSWITCH__STATIC:
case SPACELIGHTSWITCH__STATIC:
case SPACEDOORSWITCH__STATIC:
case FRANKENSTINESWITCH__STATIC:
case POWERSWITCH1__STATIC:
case LOCKSWITCH1__STATIC:
case POWERSWITCH2__STATIC:
case TECHSWITCH__STATIC:
case ACCESSSWITCH__STATIC:
case ACCESSSWITCH2__STATIC:
{
int32_t dx = sintable[(s->ang+512)&2047];
int32_t dy = sintable[(s->ang)&2047];
int32_t madevisagain = 0;
// dynamic make-invisible check for 'hidden' switches
if (spriteext[i].flags&SPREXT_TEMPINVISIBLE)
{
polymer_deletelight(actor[i].lightId);
actor[i].lightId = -1;
actor[i].lightptr = NULL;
int16_t sprsect = s->sectnum;
updatesectorz(s->x, s->y, s->z, &sprsect);
if (sprsect < 0)
s->cstat |= 32768;
else if (inside(s->x+(dx>>9), s->y+(dx>>9), s->sectnum)==1)
{
s->cstat &= ~32768;
madevisagain = 1;
}
}
break;
}
x = ((sintable[(s->ang+512)&2047])>>7);
y = ((sintable[(s->ang)&2047])>>7);
s->x += x;
s->y += y;
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 1024, 48+(255<<8)+(48<<16),PR_LIGHT_PRIO_LOW);
s->x -= x;
s->y -= y;
}
break;
}
switch (DynamicTileMap[sprite[i].picnum])
{
case DIPSWITCH__STATIC:
case DIPSWITCH2__STATIC:
case DIPSWITCH3__STATIC:
case PULLSWITCH__STATIC:
case SLOTDOOR__STATIC:
case LIGHTSWITCH__STATIC:
case SPACELIGHTSWITCH__STATIC:
case SPACEDOORSWITCH__STATIC:
case FRANKENSTINESWITCH__STATIC:
case POWERSWITCH1__STATIC:
case LOCKSWITCH1__STATIC:
case POWERSWITCH2__STATIC:
case TECHSWITCH__STATIC:
case ACCESSSWITCH__STATIC:
case ACCESSSWITCH2__STATIC:
{
int32_t x, y;
if ((s->cstat & 32768) || A_CheckSpriteFlags(i, SPRITE_NOLIGHT) ||
!inside(s->x+((sintable[(s->ang+512)&2047])>>9), s->y+((sintable[(s->ang)&2047])>>9), s->sectnum))
(madevisagain==0 && !inside(s->x+(dx>>9), s->y+(dx>>9), s->sectnum)))
{
if (actor[i].lightptr != NULL)
{
@ -8205,18 +8180,20 @@ void G_MoveWorld(void)
break;
}
x = ((sintable[(s->ang+512)&2047])>>7);
y = ((sintable[(s->ang)&2047])>>7);
s->x += dx>>7;
s->y += dy>>7;
s->x += x;
s->y += y;
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 1024-ii*256,
ii==0 ? (48+(255<<8)+(48<<16)) : 255+(48<<8)+(48<<16), PR_LIGHT_PRIO_LOW);
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), 768, 255+(48<<8)+(48<<16),PR_LIGHT_PRIO_LOW);
s->x -= x;
s->y -= y;
s->x -= dx>>7;
s->y -= dy>>7;
}
break;
}
switch (DynamicTileMap[sprite[i].picnum])
{
case ATOMICHEALTH__STATIC:
G_AddGameLight(0, i, ((s->yrepeat*tilesizy[s->picnum])<<1), LIGHTRAD2 * 3, 128+(128<<8)+(255<<16),PR_LIGHT_PRIO_HIGH_GAME);
break;

View file

@ -1203,42 +1203,69 @@ static inline void prelevel(char g)
i = headspritestat[STAT_DEFAULT];
while (i >= 0)
{
switch (DynamicTileMap[PN-1])
{
case DIPSWITCH__STATIC:
case DIPSWITCH2__STATIC:
case PULLSWITCH__STATIC:
case HANDSWITCH__STATIC:
case SLOTDOOR__STATIC:
case LIGHTSWITCH__STATIC:
case SPACELIGHTSWITCH__STATIC:
case SPACEDOORSWITCH__STATIC:
case FRANKENSTINESWITCH__STATIC:
case LIGHTSWITCH2__STATIC:
case POWERSWITCH1__STATIC:
case LOCKSWITCH1__STATIC:
case POWERSWITCH2__STATIC:
for (j=0; j<lotaglist; j++)
if (SLT == lotags[j])
int32_t ii, dx, dy;
int16_t sprsec;
for (ii=0; ii<2; ii++)
switch (DynamicTileMap[PN-1+ii])
{
case DIPSWITCH__STATIC:
case DIPSWITCH2__STATIC:
case PULLSWITCH__STATIC:
case HANDSWITCH__STATIC:
case SLOTDOOR__STATIC:
case LIGHTSWITCH__STATIC:
case SPACELIGHTSWITCH__STATIC:
case SPACEDOORSWITCH__STATIC:
case FRANKENSTINESWITCH__STATIC:
case LIGHTSWITCH2__STATIC:
case POWERSWITCH1__STATIC:
case LOCKSWITCH1__STATIC:
case POWERSWITCH2__STATIC:
dx = sintable[(sprite[i].ang+512)&2047]>>9;
dy = sintable[(sprite[i].ang)&2047]>>9;
sprsec = sprite[i].sectnum;
// check if in 'air' (and not inside something 'solid' like
// sprite #624 in E4L1):
updatesectorz(sprite[i].x, sprite[i].y, sprite[i].z, &sprsec);
// check 2 (slightly different from 'would generate light?'):
if (sprsec >= 0)
updatesectorz(sprite[i].x+dx, sprite[i].y+dy, sprite[i].z, &sprsec);
if (sprsec < 0)
{
// dynamic re-check occurs in G_MoveWorld():
spriteext[i].flags |= SPREXT_TEMPINVISIBLE;
sprite[i].cstat |= 32768;
}
// invisi-make for both switch states, but the lower code only for one
if (ii==1)
break;
if (j == lotaglist)
{
lotags[lotaglist] = SLT;
lotaglist++;
if (lotaglist > MAXSPRITES-1)
G_GameExit("\nToo many switches.");
for (j=0; j<lotaglist; j++)
if (SLT == lotags[j])
break;
j = headspritestat[STAT_EFFECTOR];
while (j >= 0)
if (j == lotaglist)
{
if (sprite[j].lotag == 12 && sprite[j].hitag == SLT)
actor[j].t_data[0] = 1;
j = nextspritestat[j];
lotags[lotaglist] = SLT;
lotaglist++;
if (lotaglist > MAXSPRITES-1)
G_GameExit("\nToo many switches.");
for (j=headspritestat[STAT_EFFECTOR]; j>=0; j=nextspritestat[j])
{
if (sprite[j].lotag == 12 && sprite[j].hitag == SLT)
actor[j].t_data[0] = 1;
}
}
break;
}
break;
}
i = nextspritestat[i];
}