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
*/
//-------------------------------------------------------------------------
2019-10-09 16:09:05 +00:00
# include "ns.h"
2015-05-19 21:54:34 +00:00
# include "build.h"
# include "names2.h"
# include "panel.h"
2020-08-05 22:18:45 +00:00
# include "misc.h"
2021-03-25 15:45:40 +00:00
# include "hw_drawinfo.h"
2015-05-19 21:54:34 +00:00
2019-10-09 16:09:05 +00:00
BEGIN_SW_NS
2015-05-19 21:54:34 +00:00
////////////////////////////////////////////////////////////////////
//
// FLOOR ABOVE FLOOR
//
////////////////////////////////////////////////////////////////////
2021-12-28 19:19:38 +00:00
// Polymost only!
void SW_FloorPortalHack ( DSWActor * actor , int z , int match ) ;
void SW_CeilingPortalHack ( DSWActor * actor , int z , int match ) ;
2015-05-19 21:54:34 +00:00
2021-12-31 12:37:57 +00:00
enum { ZMAX = 400 } ;
struct SAVE
2015-05-19 21:54:34 +00:00
{
2021-11-24 22:16:28 +00:00
sectortype * sect [ ZMAX ] ;
2015-05-19 21:58:29 +00:00
int32_t zval [ ZMAX ] ;
int16_t pic [ ZMAX ] ;
int16_t zcount ;
int16_t slope [ ZMAX ] ;
2021-12-31 12:37:57 +00:00
} ;
2015-05-19 21:54:34 +00:00
SAVE save ;
2020-09-09 18:32:24 +00:00
bool FAF_DebugView = false ;
2015-05-19 21:54:34 +00:00
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-12-04 21:04:16 +00:00
DSWActor * insertActor ( sectortype * sect , int statnum )
2015-05-19 21:54:34 +00:00
{
2021-12-06 16:00:15 +00:00
auto pActor = static_cast < DSWActor * > ( : : InsertActor ( RUNTIME_CLASS ( DSWActor ) , sect , statnum ) ) ;
2015-05-19 21:54:34 +00:00
2022-05-23 22:30:41 +00:00
pActor - > spr . intowner = - 1 ;
2021-11-06 11:32:19 +00:00
return pActor ;
2015-05-19 21:54:34 +00:00
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-26 15:44:45 +00:00
bool FAF_Sector ( sectortype * sect )
2021-11-24 17:35:42 +00:00
{
2021-11-26 15:44:45 +00:00
SWSectIterator it ( sect ) ;
2021-11-24 17:35:42 +00:00
while ( auto actor = it . Next ( ) )
{
2021-12-24 16:52:01 +00:00
if ( actor - > spr . statnum = = STAT_FAF & &
( actor - > spr . hitag > = VIEW_LEVEL1 & & actor - > spr . hitag < = VIEW_LEVEL6 ) )
2021-11-24 17:35:42 +00:00
{
return true ;
}
}
return false ;
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-24 22:27:20 +00:00
void SetWallWarpHitscan ( sectortype * sect )
2015-05-19 21:54:34 +00:00
{
2021-11-03 15:51:38 +00:00
DSWActor * sp_warp ;
2015-05-19 21:54:34 +00:00
2021-11-24 22:27:20 +00:00
if ( ! WarpSectorInfo ( sect , & sp_warp ) )
2015-05-19 21:54:34 +00:00
return ;
if ( ! sp_warp )
return ;
2022-11-15 14:44:33 +00:00
auto start_wall = sect - > walls . Data ( ) ;
2021-11-24 19:33:47 +00:00
auto wall_num = start_wall ;
2015-05-19 21:54:34 +00:00
// Travel all the way around loop setting wall bits
do
{
2021-11-24 19:59:19 +00:00
if ( wall_num - > twoSided ( ) )
2021-12-27 17:07:45 +00:00
wall_num - > cstat | = ( CSTAT_WALL_WARP_HITSCAN ) ;
2021-11-24 19:33:47 +00:00
wall_num = wall_num - > point2Wall ( ) ;
2015-05-19 21:54:34 +00:00
}
while ( wall_num ! = start_wall ) ;
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-11-24 22:27:20 +00:00
void ResetWallWarpHitscan ( sectortype * sect )
2015-05-19 21:54:34 +00:00
{
2022-11-15 14:44:33 +00:00
auto start_wall = sect - > walls . Data ( ) ;
2021-11-24 19:33:47 +00:00
auto wall_num = start_wall ;
2015-05-19 21:54:34 +00:00
// Travel all the way around loop setting wall bits
do
{
2021-12-27 18:07:39 +00:00
wall_num - > cstat & = ~ ( CSTAT_WALL_WARP_HITSCAN ) ;
2021-11-24 19:33:47 +00:00
wall_num = wall_num - > point2Wall ( ) ;
2015-05-19 21:54:34 +00:00
}
while ( wall_num ! = start_wall ) ;
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-08 21:58:02 +00:00
void FAFhitscan ( const DVector3 & start , sectortype * sect , const DVector3 & vect , HitInfo & hit , int32_t clipmask )
2015-05-19 21:54:34 +00:00
{
2021-11-24 23:20:16 +00:00
auto newsector = sect ;
2015-05-19 21:54:34 +00:00
int startclipmask = 0 ;
2020-09-09 18:32:24 +00:00
bool plax_found = false ;
2015-05-19 21:54:34 +00:00
if ( clipmask = = CLIPMASK_MISSILE )
startclipmask = CLIPMASK_WARP_HITSCAN ;
2022-09-05 22:18:50 +00:00
hitscan ( start , sect , vect , hit , startclipmask ) ;
2015-05-19 21:54:34 +00:00
2021-11-26 00:27:44 +00:00
if ( hit . hitSector = = nullptr )
2015-05-19 21:54:34 +00:00
return ;
2021-11-26 00:27:44 +00:00
if ( hit . hitWall ! = nullptr )
2015-05-19 21:54:34 +00:00
{
// hitscan warping
2021-12-29 05:53:36 +00:00
if ( ( hit . hitWall - > cstat & CSTAT_WALL_WARP_HITSCAN ) )
2015-05-19 21:54:34 +00:00
{
// back it up a bit to get a correct warp location
2022-09-05 22:18:50 +00:00
hit . hitpos . XY ( ) - = vect . XY ( ) * ( 1 / 512. ) ;
2015-05-19 21:54:34 +00:00
// warp to new x,y,z, sectnum
2022-08-17 16:53:45 +00:00
if ( Warp ( hit . hitpos , & hit . hitSector ) )
2015-05-19 21:54:34 +00:00
{
// hitscan needs to pass through dest sect
2022-01-01 17:39:59 +00:00
ResetWallWarpHitscan ( hit . hitSector ) ;
2015-05-19 21:54:34 +00:00
// NOTE: This could be recursive I think if need be
2022-10-04 22:00:25 +00:00
auto nstart = hit . hitpos ;
hitscan ( nstart , hit . hitSector , vect , hit , startclipmask ) ;
2015-05-19 21:54:34 +00:00
// reset hitscan block for dest sect
2022-01-01 17:39:59 +00:00
SetWallWarpHitscan ( hit . hitSector ) ;
2015-05-19 21:54:34 +00:00
return ;
}
else
{
2022-01-30 07:13:35 +00:00
//ASSERT(true == false); // some maps in SWC20 trigger this due to poor design.
return ;
2015-05-19 21:54:34 +00:00
}
}
}
// make sure it hit JUST a sector before doing a check
2021-11-26 00:27:44 +00:00
if ( hit . hitWall = = nullptr & & hit . actor ( ) = = nullptr )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:53:36 +00:00
if ( ( hit . hitSector - > extra & SECTFX_WARP_SECTOR ) )
2015-05-19 21:54:34 +00:00
{
2022-11-15 14:33:35 +00:00
if ( ( hit . hitSector - > walls [ 0 ] . cstat & CSTAT_WALL_WARP_HITSCAN ) )
2015-05-19 21:54:34 +00:00
{
// hit the floor of a sector that is a warping sector
2021-12-12 04:44:53 +00:00
sectortype * newsect = nullptr ;
2022-08-17 16:53:45 +00:00
if ( Warp ( hit . hitpos , & newsect ) )
2015-05-19 21:54:34 +00:00
{
2022-10-04 22:00:25 +00:00
auto nstart = hit . hitpos ;
hitscan ( nstart , newsect , vect , hit , clipmask ) ;
2015-05-19 21:54:34 +00:00
return ;
}
}
else
{
2021-12-15 18:06:43 +00:00
sectortype * newsect = nullptr ;
2022-08-17 16:53:45 +00:00
if ( WarpPlane ( hit . hitpos , & newsect ) )
2015-05-19 21:54:34 +00:00
{
2022-10-04 22:00:25 +00:00
auto nstart = hit . hitpos ;
hitscan ( nstart , newsect , vect , hit , clipmask ) ;
2015-05-19 21:54:34 +00:00
return ;
}
}
}
2022-09-05 22:18:50 +00:00
double loz , hiz ;
2022-10-25 18:12:51 +00:00
calcSlope ( hit . hitSector , hit . hitpos , & hiz , & loz ) ;
2022-09-05 22:18:50 +00:00
if ( abs ( hit . hitpos . Z - loz ) < 4 )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:13:28 +00:00
if ( FAF_ConnectFloor ( hit . hitSector ) & & ! ( hit . hitSector - > floorstat & CSTAT_SECTOR_FAF_BLOCK_HITSCAN ) )
2015-05-19 21:54:34 +00:00
{
2022-09-05 22:18:50 +00:00
updatesectorz ( hit . hitpos . plusZ ( 12 ) , & newsector ) ;
2020-09-09 17:52:52 +00:00
plax_found = true ;
2015-05-19 21:54:34 +00:00
}
}
2022-09-05 22:18:50 +00:00
else if ( abs ( hit . hitpos . Z - hiz ) < 4 )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:13:28 +00:00
if ( FAF_ConnectCeiling ( hit . hitSector ) & & ! ( hit . hitSector - > floorstat & CSTAT_SECTOR_FAF_BLOCK_HITSCAN ) )
2015-05-19 21:54:34 +00:00
{
2022-09-05 22:18:50 +00:00
updatesectorz ( hit . hitpos . plusZ ( - 12 ) , & newsector ) ;
2020-09-09 17:52:52 +00:00
plax_found = true ;
2015-05-19 21:54:34 +00:00
}
}
}
if ( plax_found )
{
2022-10-04 22:00:25 +00:00
auto nstart = hit . hitpos ;
hitscan ( nstart , newsector , vect , hit , clipmask ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-05 22:33:56 +00:00
bool FAFcansee ( const DVector3 & start , sectortype * sects , const DVector3 & end , sectortype * secte )
2015-05-19 21:54:34 +00:00
{
2021-11-24 17:35:42 +00:00
auto newsect = sects ;
2020-09-09 18:32:24 +00:00
bool plax_found = false ;
2019-12-03 09:44:51 +00:00
// ASSERT(sects >= 0 && secte >= 0);
2015-05-19 21:54:34 +00:00
2022-10-08 16:14:51 +00:00
// luckily we do not have portal setups with otherwise connected sectors, so let's go to the original routine for all cases.
// The hack job below won't always cut it.
if ( cansee ( start , sects , end , secte ) )
{
return true ;
}
2015-05-19 21:54:34 +00:00
// early out to regular routine
2021-11-24 17:35:42 +00:00
if ( ( ! sects | | ! FAF_Sector ( sects ) ) & & ( ! secte | | ! FAF_Sector ( secte ) ) )
2015-05-19 21:54:34 +00:00
{
2022-10-08 16:14:51 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
// get angle
2022-09-05 22:33:56 +00:00
DVector3 diff = end - start ;
2022-09-30 11:36:50 +00:00
DAngle ang = diff . Angle ( ) ;
2022-09-05 22:33:56 +00:00
DVector3 vect ;
vect . XY ( ) = ang . ToVector ( ) * 1024 ;
double dist = diff . XY ( ) . Length ( ) ;
2015-05-19 21:54:34 +00:00
// get x,y,z, vectors
if ( dist ! = 0 )
{
2022-09-05 22:33:56 +00:00
if ( end . X ! = start . X )
vect . Z = vect . X * diff . Z / diff . X ;
else if ( end . Y ! = start . Y )
vect . Z = vect . Y * diff . Z / diff . Y ;
2015-05-19 21:54:34 +00:00
else
2022-09-05 22:33:56 +00:00
vect . Z = 0 ;
2015-05-19 21:54:34 +00:00
}
else
2022-09-05 22:33:56 +00:00
vect . Z = 0 ;
2015-05-19 21:54:34 +00:00
2021-12-06 11:24:22 +00:00
HitInfo hit { } ;
2022-09-05 22:33:56 +00:00
hitscan ( start , sects , vect , hit , CLIPMASK_MISSILE ) ;
2015-05-19 21:54:34 +00:00
2021-11-26 00:01:16 +00:00
if ( hit . hitSector = = nullptr )
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
// make sure it hit JUST a sector before doing a check
2021-11-26 00:01:16 +00:00
if ( hit . hitWall = = nullptr & & hit . actor ( ) = = nullptr )
2015-05-19 21:54:34 +00:00
{
2022-09-05 22:33:56 +00:00
double loz , hiz ;
2022-10-25 18:12:51 +00:00
calcSlope ( hit . hitSector , hit . hitpos . X , hit . hitpos . Y , & hiz , & loz ) ;
2022-09-05 22:33:56 +00:00
if ( abs ( hit . hitpos . Z - loz ) < 4 )
2015-05-19 21:54:34 +00:00
{
2021-11-26 00:01:16 +00:00
if ( FAF_ConnectFloor ( hit . hitSector ) )
2015-05-19 21:54:34 +00:00
{
2022-09-05 22:33:56 +00:00
updatesectorz ( hit . hitpos . plusZ ( 12 ) , & newsect ) ;
2020-09-09 17:52:52 +00:00
plax_found = true ;
2015-05-19 21:54:34 +00:00
}
}
2022-09-05 22:33:56 +00:00
else if ( abs ( hit . hitpos . Z - hiz ) < 4 )
2015-05-19 21:54:34 +00:00
{
2021-11-26 00:01:16 +00:00
if ( FAF_ConnectCeiling ( hit . hitSector ) )
2015-05-19 21:54:34 +00:00
{
2022-09-05 22:33:56 +00:00
updatesectorz ( hit . hitpos . plusZ ( - 12 ) , & newsect ) ;
2020-09-09 17:52:52 +00:00
plax_found = true ;
2015-05-19 21:54:34 +00:00
}
}
}
else
{
2022-09-05 22:33:56 +00:00
return ! ! cansee ( start , sects , end , secte ) ;
2015-05-19 21:54:34 +00:00
}
if ( plax_found )
2022-09-05 22:33:56 +00:00
return ! ! cansee ( hit . hitpos , newsect , end , secte ) ;
2015-05-19 21:54:34 +00:00
2020-09-09 17:52:52 +00:00
return false ;
2015-05-19 21:54:34 +00:00
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-10-03 21:31:02 +00:00
double GetZadjustment ( sectortype * sect , short hitag )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:13:28 +00:00
if ( sect = = nullptr | | ! ( sect - > extra & SECTFX_Z_ADJUST ) )
2021-11-24 23:37:05 +00:00
return 0 ;
2015-05-19 21:54:34 +00:00
2021-11-06 08:29:38 +00:00
SWStatIterator it ( STAT_ST1 ) ;
while ( auto itActor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-30 15:51:56 +00:00
if ( itActor - > spr . hitag = = hitag & & itActor - > sector ( ) = = sect )
2015-05-19 21:54:34 +00:00
{
2022-10-03 21:31:02 +00:00
return itActor - > spr . lotag ;
2015-05-19 21:54:34 +00:00
}
}
2021-11-24 23:37:05 +00:00
return 0 ;
2015-05-19 21:54:34 +00:00
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-10-03 21:31:02 +00:00
bool SectorZadjust ( const Collision & ceilhit , double * hiz , const Collision & florhit , double * loz )
2015-05-19 21:54:34 +00:00
{
2022-10-03 21:31:02 +00:00
double z_amt = 0 ;
2015-05-19 21:54:34 +00:00
2020-09-09 18:32:24 +00:00
bool SkipFAFcheck = false ;
2015-05-19 21:54:34 +00:00
2021-11-06 11:19:08 +00:00
if ( florhit . type ! = - 1 )
2015-05-19 21:54:34 +00:00
{
2021-11-06 11:19:08 +00:00
switch ( florhit . type )
2015-05-19 21:54:34 +00:00
{
2021-11-06 11:19:08 +00:00
case kHitSector :
2015-05-19 21:54:34 +00:00
{
2021-11-26 14:14:10 +00:00
auto hit_sector = florhit . hitSector ;
2015-05-19 21:54:34 +00:00
// don't jack with connect sectors
2021-11-24 23:45:55 +00:00
if ( FAF_ConnectFloor ( hit_sector ) )
2015-05-19 21:54:34 +00:00
{
// rippers were dying through the floor in $rock
2021-12-29 05:53:36 +00:00
if ( ( hit_sector - > floorstat & CSTAT_SECTOR_FAF_BLOCK_HITSCAN ) )
2015-05-19 21:54:34 +00:00
break ;
2021-12-29 05:53:36 +00:00
if ( ( hit_sector - > extra & SECTFX_Z_ADJUST ) )
2015-05-19 21:54:34 +00:00
{
// see if a z adjust ST1 is around
2015-05-19 22:01:22 +00:00
z_amt = GetZadjustment ( hit_sector , FLOOR_Z_ADJUST ) ;
2015-05-19 21:54:34 +00:00
if ( z_amt )
{
// explicit z adjust overrides Connect Floor
* loz + = z_amt ;
2020-09-09 17:52:52 +00:00
SkipFAFcheck = true ;
2015-05-19 21:54:34 +00:00
}
}
break ;
}
2021-12-29 05:13:28 +00:00
if ( ! ( hit_sector - > extra & SECTFX_Z_ADJUST ) )
2015-05-19 21:54:34 +00:00
break ;
// see if a z adjust ST1 is around
2015-05-19 22:01:22 +00:00
z_amt = GetZadjustment ( hit_sector , FLOOR_Z_ADJUST ) ;
2015-05-19 21:54:34 +00:00
if ( z_amt )
{
// explicit z adjust overrides plax default
* loz + = z_amt ;
}
else
// default adjustment for plax
2021-12-29 05:53:36 +00:00
if ( ( hit_sector - > floorstat & CSTAT_SECTOR_SKY ) )
2015-05-19 21:54:34 +00:00
{
* loz + = PlaxFloorGlobZadjust ;
}
break ;
}
}
}
2021-11-06 11:19:08 +00:00
if ( ceilhit . type ! = - 1 )
2015-05-19 21:54:34 +00:00
{
2021-11-06 11:19:08 +00:00
switch ( ceilhit . type )
2015-05-19 21:54:34 +00:00
{
2021-11-06 11:19:08 +00:00
case kHitSector :
2015-05-19 21:54:34 +00:00
{
2021-11-26 14:14:10 +00:00
auto hit_sector = ceilhit . hitSector ;
2015-05-19 21:54:34 +00:00
// don't jack with connect sectors
2021-11-24 23:45:55 +00:00
if ( FAF_ConnectCeiling ( hit_sector ) )
2015-05-19 21:54:34 +00:00
{
2021-12-29 05:53:36 +00:00
if ( ( hit_sector - > extra & SECTFX_Z_ADJUST ) )
2015-05-19 21:54:34 +00:00
{
// see if a z adjust ST1 is around
2015-05-19 22:01:22 +00:00
z_amt = GetZadjustment ( hit_sector , CEILING_Z_ADJUST ) ;
2015-05-19 21:54:34 +00:00
if ( z_amt )
{
// explicit z adjust overrides Connect Floor
* loz + = z_amt ;
2020-09-09 17:52:52 +00:00
SkipFAFcheck = true ;
2015-05-19 21:54:34 +00:00
}
}
break ;
}
2021-12-29 05:13:28 +00:00
if ( ! ( hit_sector - > extra & SECTFX_Z_ADJUST ) )
2015-05-19 21:54:34 +00:00
break ;
// see if a z adjust ST1 is around
2015-05-19 22:01:22 +00:00
z_amt = GetZadjustment ( hit_sector , CEILING_Z_ADJUST ) ;
2015-05-19 21:54:34 +00:00
if ( z_amt )
{
// explicit z adjust overrides plax default
* hiz - = z_amt ;
}
else
// default adjustment for plax
2021-12-29 05:53:36 +00:00
if ( ( hit_sector - > ceilingstat & CSTAT_SECTOR_SKY ) )
2015-05-19 21:54:34 +00:00
{
* hiz - = PlaxCeilGlobZadjust ;
}
break ;
}
}
}
return SkipFAFcheck ;
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-10-03 21:31:02 +00:00
void WaterAdjust ( const Collision & florhit , double * loz )
2015-05-19 21:54:34 +00:00
{
2021-11-06 11:19:08 +00:00
if ( florhit . type = = kHitSector )
2015-05-19 21:54:34 +00:00
{
2021-11-26 14:14:10 +00:00
auto sect = florhit . hitSector ;
2021-11-19 22:20:58 +00:00
if ( ! sect - > hasU ( ) ) return ;
2015-05-19 21:54:34 +00:00
2021-11-20 22:20:43 +00:00
if ( sect - > hasU ( ) & & FixedToInt ( sect - > depth_fixed ) )
2022-10-03 21:31:02 +00:00
* loz + = FixedToInt ( sect - > depth_fixed ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-29 17:52:01 +00:00
void FAFgetzrange ( const DVector3 & pos , sectortype * sect , double * hiz , Collision * ceilhit , double * loz , Collision * florhit , double clipdist , int32_t clipmask )
2015-05-19 21:54:34 +00:00
{
2022-10-03 21:43:35 +00:00
double foo1 ;
2021-11-06 11:19:08 +00:00
Collision foo2 ;
2020-09-09 18:32:24 +00:00
bool SkipFAFcheck ;
2021-11-06 11:19:08 +00:00
Collision trash ; trash . invalidate ( ) ;
2015-05-19 21:54:34 +00:00
// IMPORTANT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This will return invalid FAF ceiling and floor heights inside of analyzesprite
// because the ceiling and floors get moved out of the way for drawing.
// early out to regular routine
2021-11-26 19:07:42 +00:00
if ( sect = = nullptr | | ! FAF_ConnectArea ( sect ) )
2015-05-19 21:54:34 +00:00
{
2021-11-26 19:06:07 +00:00
getzrange ( pos , sect , hiz , * ceilhit , loz , * florhit , clipdist , clipmask ) ;
2022-10-03 21:43:35 +00:00
SectorZadjust ( * ceilhit , hiz , * florhit , loz ) ;
WaterAdjust ( * florhit , loz ) ;
2015-05-19 21:54:34 +00:00
return ;
}
2021-11-26 19:06:07 +00:00
getzrange ( pos , sect , hiz , * ceilhit , loz , * florhit , clipdist , clipmask ) ;
2022-10-03 21:43:35 +00:00
SkipFAFcheck = SectorZadjust ( * ceilhit , hiz , * florhit , loz ) ;
WaterAdjust ( * florhit , loz ) ;
2015-05-19 21:54:34 +00:00
if ( SkipFAFcheck )
return ;
2021-11-24 23:45:55 +00:00
if ( FAF_ConnectCeiling ( sect ) )
2015-05-19 21:54:34 +00:00
{
2021-11-26 19:06:07 +00:00
auto uppersect = sect ;
2022-10-03 21:43:35 +00:00
auto newpos = DVector3 ( pos . XY ( ) , * hiz - 2 ) ;
2015-05-19 21:54:34 +00:00
2021-12-01 22:30:02 +00:00
if ( ceilhit - > type = = kHitSprite ) return ;
2015-05-19 21:54:34 +00:00
2022-10-03 21:43:35 +00:00
updatesectorz ( newpos , & uppersect ) ;
2021-11-26 19:06:07 +00:00
if ( uppersect = = nullptr )
return ;
2022-10-03 21:43:35 +00:00
getzrange ( newpos , uppersect , hiz , * ceilhit , & foo1 , foo2 , clipdist , clipmask ) ;
SectorZadjust ( * ceilhit , hiz , trash , nullptr ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-29 05:13:28 +00:00
else if ( FAF_ConnectFloor ( sect ) & & ! ( sect - > floorstat & CSTAT_SECTOR_FAF_BLOCK_HITSCAN ) )
2015-05-19 21:54:34 +00:00
{
2021-11-26 19:06:07 +00:00
auto lowersect = sect ;
2022-10-03 21:43:35 +00:00
auto newpos = DVector3 ( pos . XY ( ) , * loz + 2 ) ;
2015-05-19 21:54:34 +00:00
2021-12-01 22:30:02 +00:00
if ( florhit - > type = = kHitSprite ) return ;
2015-05-19 21:54:34 +00:00
2022-10-03 21:43:35 +00:00
updatesectorz ( newpos , & lowersect ) ;
2021-11-26 19:06:07 +00:00
if ( lowersect = = nullptr )
2019-12-03 09:44:51 +00:00
return ; // _ErrMsg(ERR_STD_ARG, "Did not find a sector at %d, %d, %d", x, y, newz);
2022-10-03 21:43:35 +00:00
getzrange ( newpos , lowersect , & foo1 , foo2 , loz , * florhit , clipdist , clipmask ) ;
SectorZadjust ( trash , nullptr , * florhit , loz ) ;
WaterAdjust ( * florhit , loz ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-08 21:58:02 +00:00
void FAFgetzrangepoint ( const DVector3 & pos , sectortype * sect , double * hiz , Collision * ceilhit , double * loz , Collision * florhit )
2015-05-19 21:54:34 +00:00
{
2022-10-03 21:43:35 +00:00
double foo1 ;
2021-11-06 11:19:08 +00:00
Collision foo2 ;
2020-09-09 18:32:24 +00:00
bool SkipFAFcheck ;
2021-11-06 11:19:08 +00:00
Collision trash ; trash . invalidate ( ) ;
2015-05-19 21:54:34 +00:00
// IMPORTANT!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This will return invalid FAF ceiling and floor heights inside of analyzesprite
// because the ceiling and floors get moved out of the way for drawing.
// early out to regular routine
2021-11-24 23:45:55 +00:00
if ( ! FAF_ConnectArea ( sect ) )
2015-05-19 21:54:34 +00:00
{
2022-10-03 21:43:35 +00:00
getzrangepoint ( pos , sect , hiz , ceilhit , loz , florhit ) ;
SectorZadjust ( * ceilhit , hiz , * florhit , loz ) ;
WaterAdjust ( * florhit , loz ) ;
2015-05-19 21:54:34 +00:00
return ;
}
2022-10-03 21:43:35 +00:00
getzrangepoint ( pos , sect , hiz , ceilhit , loz , florhit ) ;
SkipFAFcheck = SectorZadjust ( * ceilhit , hiz , * florhit , loz ) ;
WaterAdjust ( * florhit , loz ) ;
2015-05-19 21:54:34 +00:00
if ( SkipFAFcheck )
return ;
2021-11-24 23:45:55 +00:00
if ( FAF_ConnectCeiling ( sect ) )
2015-05-19 21:54:34 +00:00
{
2021-11-26 19:18:30 +00:00
auto uppersect = sect ;
2022-10-03 21:43:35 +00:00
auto newpos = DVector3 ( pos . XY ( ) , * hiz - 2 ) ;
2021-11-06 11:19:08 +00:00
if ( ceilhit - > type = = kHitSprite )
2015-05-19 21:54:34 +00:00
return ;
2021-11-06 11:19:08 +00:00
2022-10-03 21:43:35 +00:00
updatesectorz ( newpos , & uppersect ) ;
2021-11-26 19:18:30 +00:00
if ( uppersect = = nullptr )
2021-11-26 19:07:42 +00:00
return ;
2022-10-03 21:43:35 +00:00
getzrangepoint ( newpos , uppersect , hiz , ceilhit , & foo1 , & foo2 ) ;
SectorZadjust ( * ceilhit , hiz , trash , nullptr ) ;
2015-05-19 21:54:34 +00:00
}
2021-12-29 05:13:28 +00:00
else if ( FAF_ConnectFloor ( sect ) & & ! ( sect - > floorstat & CSTAT_SECTOR_FAF_BLOCK_HITSCAN ) )
2015-05-19 21:54:34 +00:00
{
2021-11-26 19:18:30 +00:00
auto lowersect = sect ;
2022-10-03 21:43:35 +00:00
auto newpos = DVector3 ( pos . XY ( ) , * loz + 2 ) ;
2021-11-06 11:19:08 +00:00
if ( florhit - > type = = kHitSprite )
2015-05-19 21:54:34 +00:00
return ;
2022-10-03 21:43:35 +00:00
updatesectorz ( newpos , & lowersect ) ;
2021-11-26 19:18:30 +00:00
if ( lowersect = = nullptr )
2021-11-26 19:07:42 +00:00
return ;
2022-10-03 21:43:35 +00:00
getzrangepoint ( newpos , lowersect , & foo1 , & foo2 , loz , florhit ) ;
SectorZadjust ( trash , nullptr , * florhit , loz ) ;
WaterAdjust ( * florhit , loz ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-12-11 02:49:58 +00:00
void SetupMirrorTiles ( void )
2015-05-19 21:54:34 +00:00
{
2021-11-02 18:36:47 +00:00
SWStatIterator it ( STAT_FAF ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2022-12-06 10:11:50 +00:00
if ( actor - > sector ( ) - > ceilingtexture ( ) = = FAFPlaceMirrorPic [ 0 ] )
2015-05-19 21:54:34 +00:00
{
2022-12-06 10:11:50 +00:00
actor - > sector ( ) - > setceilingtexture ( FAFMirrorPic [ 0 ] ) ;
2021-12-30 15:51:56 +00:00
actor - > sector ( ) - > ceilingstat | = ( CSTAT_SECTOR_SKY ) ;
2015-05-19 21:54:34 +00:00
}
2022-12-06 10:11:50 +00:00
if ( actor - > sector ( ) - > floortexture ( ) = = FAFPlaceMirrorPic [ 0 ] )
2015-05-19 21:54:34 +00:00
{
2022-12-06 10:11:50 +00:00
actor - > sector ( ) - > setfloortexture ( FAFMirrorPic [ 0 ] ) ;
2021-12-30 15:51:56 +00:00
actor - > sector ( ) - > floorstat | = ( CSTAT_SECTOR_SKY ) ;
2015-05-19 21:54:34 +00:00
}
2022-12-06 10:11:50 +00:00
if ( actor - > sector ( ) - > ceilingtexture ( ) = = FAFPlaceMirrorPic [ 1 ] )
actor - > sector ( ) - > setceilingtexture ( FAFMirrorPic [ 1 ] ) ;
2015-05-19 21:54:34 +00:00
2022-12-06 10:11:50 +00:00
if ( actor - > sector ( ) - > floortexture ( ) = = FAFPlaceMirrorPic [ 1 ] )
actor - > sector ( ) - > setfloortexture ( FAFMirrorPic [ 1 ] ) ;
2015-05-19 21:54:34 +00:00
}
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-05 22:40:53 +00:00
void GetUpperLowerSector ( int match , double x , double y , sectortype * * upper , sectortype * * lower )
2015-05-19 21:54:34 +00:00
{
2021-03-25 15:45:40 +00:00
int i ;
2021-11-25 15:55:02 +00:00
sectortype * sectorlist [ 16 ] ;
2021-03-25 15:45:40 +00:00
int sln = 0 ;
2021-11-02 18:36:47 +00:00
2021-12-21 08:23:39 +00:00
for ( auto & sect : sector )
2021-11-02 18:36:47 +00:00
{
2021-11-25 15:55:02 +00:00
if ( inside ( x , y , & sect ) = = 1 )
2021-03-25 15:45:40 +00:00
{
bool found = false ;
2021-11-25 15:55:02 +00:00
SWSectIterator it ( & sect ) ;
2021-11-02 18:36:47 +00:00
while ( auto actor = it . Next ( ) )
2021-03-25 15:45:40 +00:00
{
2021-12-24 16:52:01 +00:00
if ( actor - > spr . statnum = = STAT_FAF & &
( actor - > spr . hitag > = VIEW_LEVEL1 & & actor - > spr . hitag < = VIEW_LEVEL6 )
& & actor - > spr . lotag = = match )
2021-03-25 15:45:40 +00:00
{
found = true ;
}
}
if ( ! found )
continue ;
2021-11-02 18:36:47 +00:00
if ( sln < ( int ) SIZ ( sectorlist ) )
2021-11-25 15:55:02 +00:00
sectorlist [ sln ] = & sect ;
2021-03-25 15:45:40 +00:00
sln + + ;
}
}
// might not find ANYTHING if not tagged right
if ( sln = = 0 )
{
2021-11-25 15:55:02 +00:00
* upper = nullptr ;
* lower = nullptr ;
2021-03-25 15:45:40 +00:00
return ;
}
// Map rooms have NOT been dragged on top of each other
else if ( sln = = 1 )
{
* lower = sectorlist [ 0 ] ;
* upper = sectorlist [ 0 ] ;
return ;
}
// Map rooms HAVE been dragged on top of each other
// inside will somtimes find that you are in two different sectors if the x,y
// is exactly on a sector line.
else if ( sln > 2 )
{
// try again moving the x,y pos around until you only get two sectors
2022-09-05 22:40:53 +00:00
GetUpperLowerSector ( match , x - 1 / 16. , y , upper , lower ) ;
2021-03-25 15:45:40 +00:00
}
if ( sln = = 2 )
{
2022-08-20 18:43:32 +00:00
if ( sectorlist [ 0 ] - > floorz < sectorlist [ 1 ] - > floorz )
2021-03-25 15:45:40 +00:00
{
// swap
// make sectorlist[0] the LOW sector
2021-11-25 15:55:02 +00:00
std : : swap ( sectorlist [ 0 ] , sectorlist [ 1 ] ) ;
2021-03-25 15:45:40 +00:00
}
* lower = sectorlist [ 0 ] ;
* upper = sectorlist [ 1 ] ;
}
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-05 22:40:53 +00:00
bool FindCeilingView ( int match , double * x , double * y , double z , sectortype * * sect )
2021-03-25 15:45:40 +00:00
{
2022-09-05 22:40:53 +00:00
double xoff = 0 ;
double yoff = 0 ;
2021-03-25 15:45:40 +00:00
save . zcount = 0 ;
2021-12-24 16:52:01 +00:00
DSWActor * actor = nullptr ;
2021-03-25 15:45:40 +00:00
2015-05-19 21:54:34 +00:00
// Search Stat List For closest ceiling view sprite
// Get the match, xoff, yoff from this point
2021-11-02 18:36:47 +00:00
SWStatIterator it ( STAT_FAF ) ;
2022-01-01 09:49:31 +00:00
while ( ( actor = it . Next ( ) ) )
2021-03-25 15:45:40 +00:00
{
2021-12-24 16:52:01 +00:00
if ( actor - > spr . hitag = = VIEW_THRU_CEILING & & actor - > spr . lotag = = match )
2021-03-25 15:45:40 +00:00
{
2022-09-05 22:40:53 +00:00
xoff = * x - actor - > spr . pos . X ;
yoff = * y - actor - > spr . pos . Y ;
2021-03-25 15:45:40 +00:00
break ;
}
}
it . Reset ( STAT_FAF ) ;
2022-01-01 09:49:31 +00:00
while ( ( actor = it . Next ( ) ) )
2021-03-25 15:45:40 +00:00
{
2021-12-24 16:52:01 +00:00
if ( actor - > spr . lotag = = match )
2021-03-25 15:45:40 +00:00
{
// determine x,y position
2021-12-24 16:52:01 +00:00
if ( actor - > spr . hitag = = VIEW_THRU_FLOOR )
2021-03-25 15:45:40 +00:00
{
2021-11-25 15:55:02 +00:00
sectortype * upper , * lower ;
2021-03-25 15:45:40 +00:00
2022-09-05 22:40:53 +00:00
* x = actor - > spr . pos . X + xoff ;
* y = actor - > spr . pos . Y + yoff ;
2021-03-25 15:45:40 +00:00
// get new sector
GetUpperLowerSector ( match , * x , * y , & upper , & lower ) ;
2021-11-25 18:06:52 +00:00
* sect = upper ;
2021-03-25 15:45:40 +00:00
break ;
}
}
}
2021-11-25 18:06:52 +00:00
if ( * sect = = nullptr )
2021-03-25 15:45:40 +00:00
return false ;
2021-12-24 16:52:01 +00:00
if ( ! actor | | actor - > spr . hitag ! = VIEW_THRU_FLOOR )
2021-05-10 22:59:23 +00:00
{
2021-11-25 18:06:52 +00:00
* sect = nullptr ;
2021-05-10 22:59:23 +00:00
return false ;
}
2021-03-25 15:45:40 +00:00
return true ;
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-05 22:40:53 +00:00
bool FindFloorView ( int match , double * x , double * y , double z , sectortype * * sect )
2021-03-25 15:45:40 +00:00
{
2022-09-05 22:40:53 +00:00
double xoff = 0 ;
double yoff = 0 ;
2021-03-25 15:45:40 +00:00
save . zcount = 0 ;
2021-12-24 16:52:01 +00:00
DSWActor * actor = nullptr ;
2021-03-25 15:45:40 +00:00
// Search Stat List For closest ceiling view sprite
// Get the match, xoff, yoff from this point
2021-11-02 18:36:47 +00:00
SWStatIterator it ( STAT_FAF ) ;
2022-01-01 09:49:31 +00:00
while ( ( actor = it . Next ( ) ) )
2015-05-19 21:54:34 +00:00
{
2021-12-24 16:52:01 +00:00
if ( actor - > spr . hitag = = VIEW_THRU_FLOOR & & actor - > spr . lotag = = match )
2021-03-25 15:45:40 +00:00
{
2022-09-05 22:40:53 +00:00
xoff = * x - actor - > spr . pos . X ;
yoff = * y - actor - > spr . pos . Y ;
2021-03-25 15:45:40 +00:00
break ;
}
2015-05-19 21:54:34 +00:00
}
2021-03-25 15:45:40 +00:00
it . Reset ( STAT_FAF ) ;
2022-01-01 09:49:31 +00:00
while ( ( actor = it . Next ( ) ) )
2015-05-19 21:54:34 +00:00
{
2021-12-24 16:52:01 +00:00
if ( actor - > spr . lotag = = match )
2015-05-19 21:54:34 +00:00
{
2021-03-25 15:45:40 +00:00
// determine x,y position
2021-12-24 16:52:01 +00:00
if ( actor - > spr . hitag = = VIEW_THRU_CEILING )
2021-03-25 15:45:40 +00:00
{
2021-11-25 15:55:02 +00:00
sectortype * upper , * lower ;
2015-05-19 21:54:34 +00:00
2022-09-05 22:40:53 +00:00
* x = actor - > spr . pos . X + xoff ;
* y = actor - > spr . pos . Y + yoff ;
2015-05-19 21:54:34 +00:00
2021-03-25 15:45:40 +00:00
// get new sector
GetUpperLowerSector ( match , * x , * y , & upper , & lower ) ;
2021-11-25 18:06:52 +00:00
* sect = lower ;
2021-03-25 15:45:40 +00:00
break ;
}
2015-05-19 21:54:34 +00:00
}
2021-03-25 15:45:40 +00:00
}
2021-11-25 18:06:52 +00:00
if ( * sect = = nullptr )
2021-03-25 15:45:40 +00:00
return false ;
2021-12-24 16:52:01 +00:00
if ( ! actor | | actor - > spr . hitag ! = VIEW_THRU_CEILING )
2021-05-10 22:59:23 +00:00
{
2021-11-25 18:06:52 +00:00
* sect = nullptr ;
2021-05-10 22:59:23 +00:00
return false ;
}
2021-03-25 15:45:40 +00:00
return true ;
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2022-09-05 22:40:53 +00:00
short FindViewSectorInScene ( sectortype * cursect , int level )
2021-03-25 15:45:40 +00:00
{
2022-09-05 22:40:53 +00:00
int match ;
2021-03-25 15:45:40 +00:00
2021-11-02 18:36:47 +00:00
SWStatIterator it ( STAT_FAF ) ;
while ( auto actor = it . Next ( ) )
2015-05-19 21:54:34 +00:00
{
2021-12-24 16:52:01 +00:00
if ( actor - > spr . hitag = = level )
2021-03-25 15:45:40 +00:00
{
2021-12-30 15:51:56 +00:00
if ( cursect = = actor - > sector ( ) )
2021-03-25 15:45:40 +00:00
{
// ignore case if sprite is pointing up
2022-11-25 12:13:50 +00:00
if ( actor - > spr . Angles . Yaw = = DAngle270 )
2021-03-25 15:45:40 +00:00
continue ;
// only gets to here is sprite is pointing down
// found a potential match
2021-12-24 16:52:01 +00:00
match = actor - > spr . lotag ;
2021-03-25 15:45:40 +00:00
return match ;
}
}
}
return - 1 ;
}
2022-09-05 19:26:31 +00:00
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
2021-03-25 20:21:48 +00:00
struct PortalGroup
2021-03-25 15:45:40 +00:00
{
2021-03-25 20:21:48 +00:00
TArray < int > sectors ;
int othersector = - 1 ;
2022-09-05 22:40:53 +00:00
DVector3 offset = { 0 , 0 , 0 } ;
2021-03-25 20:21:48 +00:00
} ;
2021-03-25 15:45:40 +00:00
2021-03-25 20:21:48 +00:00
// This is very messy because some portals are linked outside the actual portal sectors, so we have to use the complicated original linking logic to find the connection. :?
void CollectPortals ( )
{
TArray < PortalGroup > floorportals ;
TArray < PortalGroup > ceilingportals ;
2021-12-21 09:51:41 +00:00
BitArray floordone ( sector . Size ( ) ) , ceilingdone ( sector . Size ( ) ) ;
2021-03-25 20:21:48 +00:00
2021-12-21 09:51:41 +00:00
for ( auto & sec : sector )
2021-05-20 16:52:27 +00:00
{
2021-12-21 09:51:41 +00:00
sec . portalflags = sec . portalnum = 0 ;
2021-05-20 16:52:27 +00:00
}
2021-03-25 20:21:48 +00:00
floordone . Zero ( ) ;
ceilingdone . Zero ( ) ;
2021-05-20 16:52:27 +00:00
portalClear ( ) ;
2021-03-25 20:21:48 +00:00
2021-12-21 09:51:41 +00:00
for ( unsigned i = 0 ; i < sector . Size ( ) ; i + + )
2021-03-25 20:21:48 +00:00
{
2022-12-06 10:11:50 +00:00
if ( sector [ i ] . floortexture ( ) = = FAFMirrorPic [ 0 ] & & ! floordone [ i ] )
2021-03-25 20:21:48 +00:00
{
auto & fp = floorportals [ floorportals . Reserve ( 1 ) ] ;
fp . sectors . Push ( i ) ;
floordone . Set ( i ) ;
for ( unsigned ii = 0 ; ii < fp . sectors . Size ( ) ; ii + + )
{
2022-11-15 14:24:17 +00:00
for ( auto & wal : sector [ fp . sectors [ ii ] ] . walls )
2021-03-25 20:21:48 +00:00
{
2021-11-24 20:33:23 +00:00
if ( ! wal . twoSided ( ) ) continue ;
auto nsec = wal . nextSector ( ) ;
2022-11-15 11:03:44 +00:00
auto ns = sectindex ( nsec ) ;
2022-12-06 10:11:50 +00:00
if ( floordone [ ns ] | | nsec - > floortexture ( ) ! = FAFMirrorPic [ 0 ] ) continue ;
2021-03-25 20:21:48 +00:00
fp . sectors . Push ( ns ) ;
floordone . Set ( ns ) ;
}
}
}
2022-12-06 10:11:50 +00:00
if ( sector [ i ] . ceilingtexture ( ) = = FAFMirrorPic [ 0 ] & & ! ceilingdone [ i ] )
2021-03-25 20:21:48 +00:00
{
auto & fp = ceilingportals [ ceilingportals . Reserve ( 1 ) ] ;
fp . sectors . Push ( i ) ;
ceilingdone . Set ( i ) ;
for ( unsigned ii = 0 ; ii < fp . sectors . Size ( ) ; ii + + )
{
2022-11-15 14:24:17 +00:00
for ( auto & wal : sector [ fp . sectors [ ii ] ] . walls )
2021-03-25 20:21:48 +00:00
{
2021-11-24 20:33:23 +00:00
if ( ! wal . twoSided ( ) ) continue ;
auto nsec = wal . nextSector ( ) ;
2022-11-15 11:03:44 +00:00
auto ns = sectindex ( nsec ) ;
2022-12-06 10:11:50 +00:00
if ( ceilingdone [ ns ] | | nsec - > ceilingtexture ( ) ! = FAFMirrorPic [ 0 ] ) continue ;
2021-03-25 20:21:48 +00:00
fp . sectors . Push ( ns ) ;
ceilingdone . Set ( ns ) ;
}
}
}
}
// now try to find connections.
for ( auto & fp : ceilingportals )
2021-03-25 15:45:40 +00:00
{
2021-03-25 20:21:48 +00:00
// pick one sprite out of the sectors, repeat until we get a valid connection
for ( auto sec : fp . sectors )
{
2021-11-05 23:48:28 +00:00
SWSectIterator it ( sec ) ;
while ( auto actor = it . Next ( ) )
2021-03-25 20:21:48 +00:00
{
2022-09-05 22:40:53 +00:00
auto tpos = actor - > spr . pos ;
2021-11-25 18:06:52 +00:00
auto tsect = & sector [ sec ] ;
2021-03-25 15:45:40 +00:00
2021-11-25 18:06:52 +00:00
int match = FindViewSectorInScene ( tsect , VIEW_LEVEL1 ) ;
2021-03-25 20:21:48 +00:00
if ( match ! = - 1 )
{
2022-09-05 22:40:53 +00:00
FindCeilingView ( match , & tpos . X , & tpos . Y , tpos . Z , & tsect ) ;
2022-12-06 10:11:50 +00:00
if ( tsect ! = nullptr & & tsect - > floortexture ( ) = = FAFMirrorPic [ 0 ] )
2021-03-25 20:21:48 +00:00
{
// got something!
2022-11-15 11:03:44 +00:00
fp . othersector = sectindex ( tsect ) ;
2022-09-05 22:40:53 +00:00
fp . offset = tpos - actor - > spr . pos ;
2021-03-25 20:21:48 +00:00
goto nextfg ;
}
}
}
}
nextfg : ;
2021-03-25 15:45:40 +00:00
}
2021-03-25 20:21:48 +00:00
for ( auto & fp : floorportals )
2021-03-25 15:45:40 +00:00
{
2021-03-25 20:21:48 +00:00
for ( auto sec : fp . sectors )
2021-03-25 15:45:40 +00:00
{
2021-11-05 23:48:28 +00:00
SWSectIterator it ( sec ) ;
while ( auto actor = it . Next ( ) )
2021-03-25 20:21:48 +00:00
{
2022-09-05 22:40:53 +00:00
auto tpos = actor - > spr . pos ;
2021-11-25 18:06:52 +00:00
auto tsect = & sector [ sec ] ;
2021-03-25 15:45:40 +00:00
2021-11-25 18:06:52 +00:00
int match = FindViewSectorInScene ( tsect , VIEW_LEVEL2 ) ;
2021-03-25 20:21:48 +00:00
if ( match ! = - 1 )
{
2022-09-05 22:40:53 +00:00
FindFloorView ( match , & tpos . X , & tpos . Y , tpos . Z , & tsect ) ;
2022-12-06 10:11:50 +00:00
if ( tsect ! = nullptr & & tsect - > ceilingtexture ( ) = = FAFMirrorPic [ 0 ] )
2021-03-25 20:21:48 +00:00
{
// got something!
2022-11-15 11:03:44 +00:00
fp . othersector = sectindex ( tsect ) ;
2022-09-05 22:40:53 +00:00
fp . offset = tpos - actor - > spr . pos ;
2021-03-25 20:21:48 +00:00
goto nextcg ;
}
}
}
}
nextcg : ;
}
for ( auto & pt : floorportals )
{
if ( pt . othersector > - 1 )
{
auto findother = [ & ] ( int other ) - > PortalGroup *
{
for ( auto & pt2 : ceilingportals )
{
if ( pt2 . sectors . Find ( other ) ! = pt2 . sectors . Size ( ) ) return & pt2 ;
}
return nullptr ;
} ;
auto pt2 = findother ( pt . othersector ) ;
if ( pt2 )
{
2022-09-05 22:40:53 +00:00
pt . offset . Z = 0 ;
int pnum = portalAdd ( PORTAL_SECTOR_FLOOR , - 1 , pt . offset ) ;
2021-03-25 20:21:48 +00:00
allPortals [ pnum ] . targets = pt2 - > sectors ; // do not move! We still need the original.
for ( auto sec : pt . sectors )
{
sector [ sec ] . portalflags = PORTAL_SECTOR_FLOOR ;
sector [ sec ] . portalnum = pnum ;
}
}
}
}
for ( auto & pt : ceilingportals )
{
if ( pt . othersector > - 1 )
{
auto findother = [ & ] ( int other ) - > PortalGroup *
{
for ( auto & pt2 : floorportals )
{
if ( pt2 . sectors . Find ( other ) ! = pt2 . sectors . Size ( ) ) return & pt2 ;
}
return nullptr ;
} ;
2021-03-25 15:45:40 +00:00
2021-03-25 20:21:48 +00:00
auto pt2 = findother ( pt . othersector ) ;
if ( pt2 )
{
2022-09-05 22:40:53 +00:00
pt . offset . Z = 0 ;
int pnum = portalAdd ( PORTAL_SECTOR_CEILING , - 1 , pt . offset ) ;
2021-03-25 20:21:48 +00:00
allPortals [ pnum ] . targets = std : : move ( pt2 - > sectors ) ;
for ( auto sec : pt . sectors )
{
sector [ sec ] . portalflags = PORTAL_SECTOR_CEILING ;
sector [ sec ] . portalnum = pnum ;
}
}
2021-03-25 15:45:40 +00:00
}
2015-05-19 21:54:34 +00:00
}
}
2021-03-25 20:21:48 +00:00
2019-10-09 16:09:05 +00:00
END_SW_NS