* We cansee() now through TROR portals, making enemies recognize you from above and below

* fixed subway roof interpolation; also small tweak to make this possible: http://forums.duke4.net/topic/3911-true-room-over-room/page__view__findpost__p__99099
* API change: Sect_{Set,Clear}Interpolation now takes sectnums directly


git-svn-id: https://svn.eduke32.com/eduke32@1926 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2011-07-01 17:15:07 +00:00
parent 4e0da757ef
commit 43ecbb1019
6 changed files with 155 additions and 28 deletions

View file

@ -10468,17 +10468,40 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, in
{
sectortype *sec;
walltype *wal, *wal2;
int32_t i, cnt, nexts, x, y, z, cz, fz, dasectnum, dacnt, danum;
int32_t cnt, nexts, x, y, z, cfz[2], dasectnum, dacnt, danum;
int32_t x21, y21, z21, x31, y31, x34, y34, bot, t;
static uint8_t sectbitmap[MAXSECTORS>>3];
#ifdef YAX_ENABLE
int16_t pendingsectnum;
vec3_t pendingvec;
int32_t cfz1[2], cfz2[2]; // both wrt dasectnum
int16_t bn[2];
#endif
Bmemset(&pendingvec, 0, sizeof(vec3_t)); // compiler-happy
Bmemset(sectbitmap, 0, (numsectors+7)>>3);
#ifdef YAX_ENABLE
restart_grand:
#endif
if ((x1 == x2) && (y1 == y2)) return(sect1 == sect2);
pendingsectnum = -1;
x21 = x2-x1; y21 = y2-y1; z21 = z2-z1;
sectbitmap[sect1>>3] |= (1<<(sect1&7));
clipsectorlist[0] = sect1; danum = 1;
for (dacnt=0; dacnt<danum; dacnt++)
{
dasectnum = clipsectorlist[dacnt]; sec = &sector[dasectnum];
#ifdef YAX_ENABLE
yax_getbunches(dasectnum, &bn[0], &bn[1]);
getzsofslope(dasectnum, x1,y1, &cfz1[0], &cfz1[1]);
getzsofslope(dasectnum, x2,y2, &cfz2[0], &cfz2[1]);
#endif
for (cnt=sec->wallnum,wal=&wall[sec->wallptr]; cnt>0; cnt--,wal++)
{
wal2 = &wall[wal->point2];
@ -10487,26 +10510,124 @@ int32_t cansee(int32_t x1, int32_t y1, int32_t z1, int16_t sect1, int32_t x2, in
bot = y21*x34-x21*y34; if (bot <= 0) continue;
t = y21*x31-x21*y31; if ((unsigned)t >= (unsigned)bot) continue;
t = y31*x34-x31*y34; if ((unsigned)t >= (unsigned)bot) continue;
t = y31*x34-x31*y34;
if ((unsigned)t >= (unsigned)bot)
{
if (t >= bot)
{
#ifdef YAX_ENABLE
int32_t cf, frac, ns;
for (cf=0; cf<2; cf++)
{
if ((cf==0 && bn[0]>=0 && z1 > cfz1[0] && cfz2[0] > z2) ||
(cf==1 && bn[1]>=0 && z1 < cfz1[1] && cfz2[1] < z2))
{
if ((cfz1[cf]-cfz2[cf])-(z1-z2)==0)
continue;
frac = divscale24(z1-cfz1[cf], (z1-z2)-(cfz1[cf]-cfz2[cf]));
if ((unsigned)frac >= (1<<24))
continue;
x = x1 + mulscale24(x21,frac);
y = y1 + mulscale24(y21,frac);
ns = yax_getneighborsect(x, y, dasectnum, cf, NULL);
if (ns < 0)
continue;
if (!(sectbitmap[ns>>3] & (1<<(ns&7))) && pendingsectnum==-1)
{
sectbitmap[ns>>3] |= (1<<(ns&7));
pendingsectnum = ns;
pendingvec.x = x;
pendingvec.y = y;
pendingvec.z = z1 + mulscale24(z21,frac);
}
}
}
}
#endif
continue;
}
nexts = wal->nextsector;
if ((nexts < 0) || (wal->cstat&32)) return(0);
#ifdef YAX_ENABLE
if (bn[0]<0 && bn[1]<0)
#endif
if ((nexts < 0) || (wal->cstat&32))
return(0);
t = divscale24(t,bot);
x = x1 + mulscale24(x21,t);
y = y1 + mulscale24(y21,t);
z = z1 + mulscale24(z21,t);
getzsofslope((int16_t)dasectnum,x,y,&cz,&fz);
if ((z <= cz) || (z >= fz)) return(0);
getzsofslope((int16_t)nexts,x,y,&cz,&fz);
if ((z <= cz) || (z >= fz)) return(0);
getzsofslope((int16_t)dasectnum, x,y, &cfz[0],&cfz[1]);
for (i=danum-1; i>=0; i--) if (clipsectorlist[i] == nexts) break;
if (i < 0) clipsectorlist[danum++] = nexts;
if ((z <= cfz[0]) || (z >= cfz[1]))
{
#ifdef YAX_ENABLE
int32_t cf, frac;
// XXX: Is this any good?
for (cf=0; cf<2; cf++)
if ((cf==0 && bn[0]>=0 && z <= cfz[0] && z1 >= cfz1[0]) ||
(cf==1 && bn[1]>=0 && z >= cfz[1] && z1 <= cfz1[1]))
{
if ((cfz1[cf]-cfz[cf])-(z1-z)==0)
continue;
frac = divscale24(z1-cfz1[cf], (z1-z)-(cfz1[cf]-cfz[cf]));
t = mulscale24(t, frac);
if ((unsigned)t < (1<<24))
{
x = x1 + mulscale24(x21,t);
y = y1 + mulscale24(y21,t);
nexts = yax_getneighborsect(x, y, dasectnum, cf, NULL);
if (nexts >= 0)
goto add_nextsector;
}
}
#endif
return(0);
}
#ifdef YAX_ENABLE
if ((nexts < 0) || (wal->cstat&32))
return 0;
#endif
getzsofslope((int16_t)nexts,x,y,&cfz[0],&cfz[1]);
if ((z <= cfz[0]) || (z >= cfz[1]))
return(0);
add_nextsector:
if (!(sectbitmap[nexts>>3] & (1<<(nexts&7))))
{
sectbitmap[nexts>>3] |= (1<<(nexts&7));
clipsectorlist[danum++] = nexts;
}
}
#ifdef YAX_ENABLE
if (pendingsectnum>=0)
{
sect1 = pendingsectnum;
x1 = pendingvec.x;
y1 = pendingvec.y;
z1 = pendingvec.z;
goto restart_grand;
}
#endif
}
for (i=danum-1; i>=0; i--) if (clipsectorlist[i] == sect2) return(1);
if ((sectbitmap[sect2>>3] & (1<<(sect2&7))))
return 1;
return(0);
}

View file

@ -608,9 +608,9 @@ void A_DoGutsDir(int32_t sp, int32_t gtype, int32_t n)
}
}
void Sect_SetInterpolation(int32_t i)
void Sect_SetInterpolation(int32_t sectnum)
{
int32_t k, j = sector[SECT].wallptr, endwall = j+sector[SECT].wallnum;
int32_t k, j = sector[sectnum].wallptr, endwall = j+sector[sectnum].wallnum;
for (; j<endwall; j++)
{
@ -628,9 +628,9 @@ void Sect_SetInterpolation(int32_t i)
}
}
void Sect_ClearInterpolation(int32_t i)
void Sect_ClearInterpolation(int32_t sectnum)
{
int32_t k, j = sector[SECT].wallptr, endwall = j+sector[SECT].wallnum;
int32_t k, j = sector[sectnum].wallptr, endwall = j+sector[sectnum].wallnum;
for (; j<endwall; j++)
{

View file

@ -196,7 +196,8 @@ void G_SetInterpolation(int32_t *posptr);
void G_StopInterpolation(int32_t *posptr);
extern inline void G_UpdateInterpolations(void);
void Sect_ClearInterpolation(int32_t i);
void Sect_SetInterpolation(int32_t i);
// PK 20110701: changed input argument: int32_t i (== sprite, whose sectnum...) --> sectnum directly
void Sect_ClearInterpolation(int32_t sectnum);
void Sect_SetInterpolation(int32_t sectnum);
#endif

View file

@ -5581,8 +5581,15 @@ int32_t A_Spawn(int32_t j, int32_t pn)
if (upperwall>=0 && wall[upperwall].nextsector>=0)
{
Sect_SetInterpolation(wall[upperwall].nextsector);
actor[i].t_data[9] = wall[upperwall].nextsector;
int32_t jj, uppersect=wall[upperwall].nextsector;
for (jj=headspritesect[uppersect]; jj>=0; jj=nextspritesect[jj])
if (sprite[jj].picnum==SECTOREFFECTOR && sprite[jj].lotag==sp->lotag)
break;
if (jj < 0)
{
Sect_SetInterpolation(wall[upperwall].nextsector);
actor[i].t_data[9] = wall[upperwall].nextsector;
}
}
}
#endif
@ -5636,7 +5643,7 @@ int32_t A_Spawn(int32_t j, int32_t pn)
case 15:
case 16:
case 26:
Sect_SetInterpolation(i);
Sect_SetInterpolation(sprite[i].sectnum);
break;
}

View file

@ -2478,7 +2478,7 @@ nullquote:
case CON_SECTCLEARINTERPOLATION:
insptr++;
{
int32_t sectnum = Gv_GetVarX(*insptr++), osectnum;
int32_t sectnum = Gv_GetVarX(*insptr++);
if ((unsigned)sectnum >= (unsigned)numsectors)
{
@ -2486,13 +2486,10 @@ nullquote:
continue;
}
osectnum = sprite[MAXSPRITES-1].sectnum;
sprite[MAXSPRITES-1].sectnum = sectnum;
if (tw==CON_SECTSETINTERPOLATION)
Sect_SetInterpolation(MAXSPRITES-1);
Sect_SetInterpolation(sectnum);
else
Sect_ClearInterpolation(MAXSPRITES-1);
sprite[MAXSPRITES-1].sectnum = osectnum;
Sect_ClearInterpolation(sectnum);
continue;
}
@ -5184,6 +5181,7 @@ void G_RestoreMapState(mapstate_t *save)
}
}
// TODO: sync with TROR special interpolations? (e.g. upper floor of subway)
g_numInterpolations = 0;
startofdynamicinterpolations = 0;
@ -5215,7 +5213,7 @@ void G_RestoreMapState(mapstate_t *save)
case 16:
case 26:
case 30:
Sect_SetInterpolation(k);
Sect_SetInterpolation(sprite[k].sectnum);
break;
}

View file

@ -583,7 +583,7 @@ int32_t G_LoadPlayer(int32_t spot)
case 16:
case 26:
case 30:
Sect_SetInterpolation(k);
Sect_SetInterpolation(sprite[k].sectnum);
break;
}
@ -2284,7 +2284,7 @@ static void postloadplayer1()
case 16:
case 26:
case 30:
Sect_SetInterpolation(i);
Sect_SetInterpolation(sprite[i].sectnum);
break;
}