2019-11-20 16:21:32 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 2010 - 2019 EDuke32 developers and contributors
Copyright ( C ) 2019 sirlemonhead , Nuke . YKT
This file is part of PCExhumed .
PCExhumed is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation .
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 .
*/
//-------------------------------------------------------------------------
2019-11-22 23:11:37 +00:00
# include "ns.h"
2019-08-26 03:59:14 +00:00
# include "engine.h"
2020-08-18 07:52:08 +00:00
# include "aistuff.h"
2019-08-26 03:59:14 +00:00
# include "exhumed.h"
# include "view.h"
# include "sound.h"
# include "names.h"
# include "sequence.h"
# include "player.h"
2021-01-04 19:34:27 +00:00
# include "interpolate.h"
2020-08-23 14:24:54 +00:00
# include "mapinfo.h"
2019-08-26 03:59:14 +00:00
# include <string.h>
# include <assert.h>
2019-11-22 23:11:37 +00:00
BEGIN_PS_NS
2019-08-26 03:59:14 +00:00
static short ObjectSeq [ ] = {
2019-08-31 07:47:15 +00:00
46 , - 1 , 72 , - 1
2019-08-26 03:59:14 +00:00
} ;
static short ObjectStatnum [ ] = {
2019-08-31 07:47:15 +00:00
kStatExplodeTrigger , kStatExplodeTarget , 98 , kStatDestructibleSprite
2019-08-26 03:59:14 +00:00
} ;
struct Trail
{
2019-08-31 07:47:15 +00:00
short field_0 ;
short field_2 ;
short field_4 ;
2019-08-26 03:59:14 +00:00
} ;
struct TrailPoint
{
2019-08-31 07:47:15 +00:00
int x ;
int y ;
2020-11-29 23:49:25 +00:00
char nTrailPointVal ;
short nTrailPointPrev ;
short nTrailPointNext ;
2019-08-26 03:59:14 +00:00
} ;
struct Bob
{
2019-08-31 07:47:15 +00:00
short nSector ;
char field_2 ;
char field_3 ;
int z ;
2020-11-29 23:49:25 +00:00
short sBobID ;
2019-08-26 03:59:14 +00:00
} ;
struct Drip
{
2019-08-31 07:47:15 +00:00
short nSprite ;
short field_2 ;
2019-08-26 03:59:14 +00:00
} ;
// 56 bytes
struct Elev
{
2019-08-31 07:47:15 +00:00
short field_0 ;
short nChannel ;
short nSector ;
int field_6 ;
int field_A ;
short nCountZOffsets ; // count of items in zOffsets
short nCurZOffset ;
int zOffsets [ 8 ] ; // different Z offsets
short field_32 ;
short nSprite ;
short field_36 ;
2019-08-26 03:59:14 +00:00
} ;
// 16 bytes
struct MoveSect
{
2019-08-31 07:47:15 +00:00
short nSector ;
short nTrail ;
short nTrailPoint ;
short field_6 ;
short field_8 ; // nSector?
int field_10 ;
short field_14 ; // nChannel?
2020-11-29 23:49:25 +00:00
short sMoveDir ;
2019-08-26 03:59:14 +00:00
} ;
struct wallFace
{
2019-08-31 07:47:15 +00:00
short nChannel ;
short nWall ;
short field_4 ;
short field_6 [ 8 ] ;
2019-08-26 03:59:14 +00:00
} ;
2020-11-29 23:49:25 +00:00
struct slideData
2019-08-26 03:59:14 +00:00
{
2021-10-21 10:08:22 +00:00
DExhumedActor * pActor ;
2019-08-31 07:47:15 +00:00
short nChannel ;
2021-10-21 10:08:22 +00:00
short nStart ;
2020-11-29 23:49:25 +00:00
short field_4a ;
short field_8a ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int field_0 ;
int field_4 ;
int field_8 ;
int field_C ;
2020-02-04 21:45:10 +00:00
int x1 ;
int y1 ;
int x2 ;
int y2 ;
2021-10-21 10:08:22 +00:00
int x3 ;
int y3 ;
int x4 ;
int y4 ;
int x5 ;
int y5 ;
int x6 ;
int y6 ;
2019-08-26 03:59:14 +00:00
} ;
struct Point
{
2021-10-21 10:08:22 +00:00
short nSector ;
2019-08-31 07:47:15 +00:00
short field_2 ;
short field_4 ;
short field_6 ;
short field_8 ;
short field_A ;
short field_C ;
2021-10-21 10:08:22 +00:00
short nNext ;
2019-08-26 03:59:14 +00:00
} ;
struct Trap
{
2021-10-21 11:09:29 +00:00
DExhumedActor * pActor ;
2019-08-31 07:47:15 +00:00
short field_0 ;
short nType ;
short field_6 ;
short field_8 ;
short field_A ;
short field_C ;
short field_E ;
2020-11-29 23:49:25 +00:00
short nTrapInterval ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
} ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
TArray < Point > PointList ;
TArray < Trap > sTrap ;
TArray < Bob > sBob ;
TArray < Trail > sTrail ;
TArray < TrailPoint > sTrailPoint ;
TArray < Elev > Elevator ;
2021-10-21 15:24:52 +00:00
TArray < DExhumedActor * > ObjectList ;
2020-11-29 23:49:25 +00:00
TArray < MoveSect > sMoveSect ;
TArray < slideData > SlideData ;
TArray < wallFace > WallFace ;
TArray < Drip > sDrip ;
2021-10-21 13:02:18 +00:00
TArray < DExhumedActor * > EnergyBlocks ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int lFinaleStart ;
2019-08-26 03:59:14 +00:00
short nFinaleStage ;
2021-10-21 11:20:00 +00:00
DExhumedActor * pFinaleSpr ;
2019-08-26 03:59:14 +00:00
short nDronePitch = 0 ;
short nSmokeSparks = 0 ;
2020-11-29 23:49:25 +00:00
FSerializer & Serialize ( FSerializer & arc , const char * keyname , Trail & w , Trail * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " at0 " , w . field_0 )
( " at2 " , w . field_2 )
( " at4 " , w . field_4 )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , TrailPoint & w , TrailPoint * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " x " , w . x )
( " y " , w . y )
( " val " , w . nTrailPointVal )
( " next " , w . nTrailPointNext )
( " prev " , w . nTrailPointPrev )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , Bob & w , Bob * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " sector " , w . nSector )
( " at2 " , w . field_2 )
( " at3 " , w . field_3 )
( " z " , w . z )
( " id " , w . sBobID )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , Drip & w , Drip * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " sprite " , w . nSprite )
( " at2 " , w . field_2 )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , Elev & w , Elev * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " at0 " , w . field_0 )
( " channel " , w . nChannel )
( " sector " , w . nSector )
( " at6 " , w . field_6 )
( " ata " , w . field_A )
( " countz " , w . nCountZOffsets )
( " curz " , w . nCurZOffset )
. Array ( " zofs " , w . zOffsets , 8 )
( " at32 " , w . field_32 )
( " sprite " , w . nSprite )
( " at36 " , w . field_36 )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , MoveSect & w , MoveSect * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " sector " , w . nSector )
( " trail " , w . nTrail )
( " trailpoint " , w . nTrailPoint )
( " at6 " , w . field_6 )
( " at8 " , w . field_8 )
( " at10 " , w . field_10 )
( " at14 " , w . field_14 )
( " movedir " , w . sMoveDir )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
2021-10-21 15:24:52 +00:00
2020-11-29 23:49:25 +00:00
FSerializer & Serialize ( FSerializer & arc , const char * keyname , wallFace & w , wallFace * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " channel " , w . nChannel )
( " wall " , w . nWall )
( " at4 " , w . field_4 )
. Array ( " at6 " , w . field_6 , 8 )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , slideData & w , slideData * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " at0 " , w . field_0 )
( " at4 " , w . field_4 )
( " at8 " , w . field_8 )
( " atc " , w . field_C )
( " x1 " , w . x1 )
( " y1 " , w . y1 )
( " x2 " , w . x2 )
( " y2 " , w . y2 )
2021-10-21 10:08:22 +00:00
( " at20 " , w . x3 )
( " at24 " , w . y3 )
( " at28 " , w . x4 )
( " at2c " , w . y4 )
( " at30 " , w . x5 )
( " at34 " , w . y5 )
( " at38 " , w . x6 )
( " at3c " , w . y6 )
2021-10-15 20:13:05 +00:00
( " channel " , w . nChannel )
2021-10-21 10:08:22 +00:00
( " at2a " , w . nStart )
2021-10-15 20:13:05 +00:00
( " at4a " , w . field_4a )
2021-10-21 10:08:22 +00:00
( " at6a " , w . pActor )
2021-10-15 20:13:05 +00:00
( " at8a " , w . field_8a )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , Point & w , Point * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
2021-10-21 10:08:22 +00:00
arc ( " at0 " , w . nSector )
2021-10-15 20:13:05 +00:00
( " at2 " , w . field_2 )
( " at4 " , w . field_4 )
( " at6 " , w . field_6 )
( " at8 " , w . field_8 )
( " ata " , w . field_A )
( " atc " , w . field_C )
2021-10-21 10:08:22 +00:00
( " ate " , w . nNext )
2021-10-15 20:13:05 +00:00
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , Trap & w , Trap * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " at0 " , w . field_0 )
2021-10-21 11:09:29 +00:00
( " sprite " , w . pActor )
2021-10-15 20:13:05 +00:00
( " type " , w . nType )
( " at6 " , w . field_6 )
( " at8 " , w . field_8 )
( " ata " , w . field_A )
( " atc " , w . field_C )
( " ate " , w . field_E )
( " interval " , w . nTrapInterval )
. EndObject ( ) ;
}
return arc ;
2020-11-29 23:49:25 +00:00
}
void SerializeObjects ( FSerializer & arc )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( " objects " ) )
{
arc ( " points " , PointList )
( " traps " , sTrap )
( " bob " , sBob )
( " trails " , sTrail )
( " trailpoints " , sTrailPoint )
( " elevators " , Elevator )
( " objects " , ObjectList )
( " movesect " , sMoveSect )
( " slides " , SlideData )
( " wallface " , WallFace )
( " drips " , sDrip )
( " finalestart " , lFinaleStart )
2021-10-21 13:02:18 +00:00
( " energyblocks " , EnergyBlocks )
2021-10-15 20:13:05 +00:00
( " finalestage " , nFinaleStage )
2021-10-21 11:20:00 +00:00
( " finalespr " , pFinaleSpr )
2021-10-15 20:13:05 +00:00
( " dronepitch " , nDronePitch )
( " smokesparks " , nSmokeSparks )
. EndObject ( ) ;
}
2020-11-29 23:49:25 +00:00
}
2019-08-26 03:59:14 +00:00
// done
void InitObjects ( )
{
2020-11-29 23:49:25 +00:00
sTrap . Clear ( ) ;
sBob . Clear ( ) ;
sTrail . Clear ( ) ;
sTrailPoint . Clear ( ) ;
ObjectList . Clear ( ) ;
sMoveSect . Clear ( ) ;
sDrip . Clear ( ) ;
2021-10-21 13:02:18 +00:00
EnergyBlocks . Clear ( ) ;
2019-08-31 07:47:15 +00:00
nDronePitch = 0 ;
nFinaleStage = 0 ;
lFinaleStart = 0 ;
nSmokeSparks = 0 ;
2019-08-26 03:59:14 +00:00
}
// done
void InitElev ( )
{
2020-11-29 23:49:25 +00:00
Elevator . Clear ( ) ;
2019-08-26 03:59:14 +00:00
}
// done
2021-10-20 20:16:50 +00:00
DExhumedActor * BuildWallSprite ( int nSector )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
int nWall = sector [ nSector ] . wallptr ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int x = wall [ nWall ] . x ;
int y = wall [ nWall ] . y ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int x2 = wall [ nWall + 1 ] . x ;
int y2 = wall [ nWall + 1 ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-20 20:16:50 +00:00
auto pActor = insertActor ( nSector , 401 ) ;
auto pSprite = & pActor - > s ( ) ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > x = ( x + x2 ) / 2 ;
pSprite - > y = ( y + y2 ) / 2 ;
pSprite - > z = ( sector [ nSector ] . floorz + sector [ nSector ] . ceilingz ) / 2 ;
pSprite - > cstat = 0x8000 ;
2019-08-26 03:59:14 +00:00
2021-10-20 20:16:50 +00:00
return pActor ;
}
2019-08-26 03:59:14 +00:00
// done
short FindWallSprites ( short nSector )
{
2019-08-31 07:47:15 +00:00
int var_24 = 0x7FFFFFFF ;
2021-10-15 20:13:05 +00:00
int ecx = 0x7FFFFFFF ;
2019-08-31 07:47:15 +00:00
int nWall = sector [ nSector ] . wallptr ;
int nWallCount = sector [ nSector ] . wallnum ;
int esi = 0x80000002 ;
int edi = 0x80000002 ;
int i ;
for ( i = 0 ; i < nWallCount ; i + + )
{
if ( wall [ nWall ] . x < var_24 ) {
var_24 = wall [ nWall ] . x ;
}
if ( esi < wall [ nWall ] . x ) {
esi = wall [ nWall ] . x ;
}
if ( ecx > wall [ nWall ] . y ) {
ecx = wall [ nWall ] . y ;
}
if ( edi < wall [ nWall ] . y ) {
edi = wall [ nWall ] . y ;
}
nWall + + ;
}
ecx - = 5 ;
esi + = 5 ;
edi + = 5 ;
var_24 - = 5 ;
2021-10-20 20:16:50 +00:00
DExhumedActor * pAct = nullptr ;
2019-08-31 07:47:15 +00:00
2021-10-20 20:16:50 +00:00
ExhumedSpriteIterator it ;
while ( auto actor = it . Next ( ) )
2019-08-31 07:47:15 +00:00
{
2021-10-20 20:16:50 +00:00
auto spr = & actor - > s ( ) ;
if ( spr - > lotag = = 0 )
2019-08-31 07:47:15 +00:00
{
2021-10-20 20:16:50 +00:00
if ( ( spr - > cstat & 0x50 ) = = 80 )
2019-08-31 07:47:15 +00:00
{
2021-10-20 20:16:50 +00:00
int var_28 = spr - > x ;
int ebx = spr - > y ;
2019-08-31 07:47:15 +00:00
if ( ( var_28 > = var_24 ) & & ( esi > = var_28 ) & & ( ebx > = ecx ) & & ( ebx < = edi ) )
{
2021-10-20 20:16:50 +00:00
actor - > pTarget = pAct ;
pAct = actor ;
2019-08-31 07:47:15 +00:00
}
}
}
}
2021-10-20 20:16:50 +00:00
if ( pAct = = nullptr )
2019-08-31 07:47:15 +00:00
{
2021-10-20 20:16:50 +00:00
pAct = insertActor ( nSector , 401 ) ;
auto pSprite = & pAct - > s ( ) ;
2019-08-31 07:47:15 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > x = ( var_24 + esi ) / 2 ;
pSprite - > y = ( ecx + edi ) / 2 ;
pSprite - > z = sector [ nSector ] . floorz ;
pSprite - > cstat = 0x8000 ;
pSprite - > owner = - 1 ;
pSprite - > lotag = 0 ;
pSprite - > hitag = 0 ;
2019-08-31 07:47:15 +00:00
}
2021-10-20 20:16:50 +00:00
return pAct - > GetSpriteIndex ( ) ;
2019-08-26 03:59:14 +00:00
}
2019-08-31 10:36:26 +00:00
int BuildElevF ( int nChannel , int nSector , int nWallSprite , int arg_4 , int arg_5 , int nCount , . . . )
2019-08-26 03:59:14 +00:00
{
2020-11-29 23:49:25 +00:00
auto ElevCount = Elevator . Reserve ( 1 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
Elevator [ ElevCount ] . field_0 = 2 ;
Elevator [ ElevCount ] . field_6 = arg_4 ;
Elevator [ ElevCount ] . field_32 = - 1 ;
Elevator [ ElevCount ] . field_A = arg_5 ;
Elevator [ ElevCount ] . nChannel = nChannel ;
Elevator [ ElevCount ] . nSector = nSector ;
Elevator [ ElevCount ] . nCountZOffsets = 0 ;
Elevator [ ElevCount ] . nCurZOffset = 0 ;
Elevator [ ElevCount ] . field_36 = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nWallSprite < 0 ) {
2021-10-20 20:16:50 +00:00
nWallSprite = BuildWallSprite ( nSector ) - > GetSpriteIndex ( ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
Elevator [ ElevCount ] . nSprite = nWallSprite ;
2019-11-20 16:21:32 +00:00
2019-08-31 10:36:26 +00:00
va_list zlist ;
va_start ( zlist , nCount ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
while ( 1 )
{
if ( Elevator [ ElevCount ] . nCountZOffsets > = nCount ) {
return ElevCount ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nVal = Elevator [ ElevCount ] . nCountZOffsets ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
Elevator [ ElevCount ] . nCountZOffsets + + ;
2019-08-26 03:59:14 +00:00
2019-08-31 10:36:26 +00:00
Elevator [ ElevCount ] . zOffsets [ nVal ] = va_arg ( zlist , int ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-31 10:36:26 +00:00
va_end ( zlist ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return ElevCount ;
2019-08-26 03:59:14 +00:00
}
2019-08-31 10:36:26 +00:00
int BuildElevC ( int arg1 , int nChannel , int nSector , int nWallSprite , int arg5 , int arg6 , int nCount , . . . )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
int edi = arg5 ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
auto ElevCount = Elevator . Reserve ( 1 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
Elevator [ ElevCount ] . field_0 = arg1 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( arg1 & 4 )
{
edi = arg5 / 2 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
Elevator [ ElevCount ] . field_6 = edi ;
Elevator [ ElevCount ] . nCountZOffsets = 0 ;
Elevator [ ElevCount ] . field_36 = 0 ;
Elevator [ ElevCount ] . nCurZOffset = 0 ;
Elevator [ ElevCount ] . field_A = arg6 ;
Elevator [ ElevCount ] . field_32 = - 1 ;
Elevator [ ElevCount ] . nChannel = nChannel ;
Elevator [ ElevCount ] . nSector = nSector ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nWallSprite < 0 ) {
2021-10-20 20:16:50 +00:00
nWallSprite = BuildWallSprite ( nSector ) - > GetSpriteIndex ( ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
Elevator [ ElevCount ] . nSprite = nWallSprite ;
2019-08-26 03:59:14 +00:00
2019-08-31 10:36:26 +00:00
va_list zlist ;
va_start ( zlist , nCount ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
while ( 1 )
{
if ( Elevator [ ElevCount ] . nCountZOffsets > = nCount ) {
return ElevCount ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nVal = Elevator [ ElevCount ] . nCountZOffsets ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
Elevator [ ElevCount ] . nCountZOffsets + + ;
2019-08-26 03:59:14 +00:00
2019-08-31 10:36:26 +00:00
Elevator [ ElevCount ] . zOffsets [ nVal ] = va_arg ( zlist , int ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-31 10:36:26 +00:00
va_end ( zlist ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return ElevCount ;
2019-08-26 03:59:14 +00:00
}
// TODO - tidy me up
// RENAME param A - not always Z
// Confirmed 100% correct with original .exe
2021-10-15 20:13:05 +00:00
int LongSeek ( int * pZVal , int a2 , int a3 , int a4 )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
int v4 ; // edx@1
int v5 ; // ebx@2
v4 = a2 - * pZVal ;
if ( v4 < 0 )
{
v5 = - a3 ;
if ( v5 > v4 )
v4 = v5 ;
( * pZVal ) + = v4 ;
}
if ( v4 > 0 )
{
if ( a4 < v4 )
v4 = a4 ;
( * pZVal ) + = v4 ;
}
return v4 ;
2019-08-26 03:59:14 +00:00
}
// done
int CheckSectorSprites ( short nSector , int nVal )
{
2019-08-31 07:47:15 +00:00
int b = 0 ;
if ( nVal )
{
int nZDiff = sector [ nSector ] . floorz - sector [ nSector ] . ceilingz ;
2021-10-20 20:27:16 +00:00
ExhumedSectIterator it ( nSector ) ;
while ( auto pActor = it . Next ( ) )
2019-08-31 07:47:15 +00:00
{
2021-10-20 20:27:16 +00:00
auto pSprite = & pActor - > s ( ) ;
if ( ( pSprite - > cstat & 0x101 ) & & ( nZDiff < GetActorHeight ( pActor ) ) )
2019-08-31 07:47:15 +00:00
{
if ( nVal ! = 1 ) {
return 1 ;
}
b = 1 ;
2021-10-20 20:27:16 +00:00
runlist_DamageEnemy ( pActor - > GetSpriteIndex ( ) , - 1 , 5 ) ;
2019-08-31 07:47:15 +00:00
2021-10-20 20:27:16 +00:00
if ( pSprite - > statnum = = 100 & & PlayerList [ GetPlayerFromActor ( pActor ) ] . nHealth < = 0 )
2019-08-31 07:47:15 +00:00
{
PlayFXAtXYZ ( StaticSound [ kSoundJonFDie ] ,
2021-09-06 06:33:02 +00:00
pSprite - > x ,
pSprite - > y ,
pSprite - > z ,
2021-10-20 20:27:16 +00:00
pSprite - > sectnum , CHANF_NONE , 0x4000 ) ;
2019-08-31 07:47:15 +00:00
}
}
}
}
else
{
2021-10-20 20:27:16 +00:00
ExhumedSectIterator it ( nSector ) ;
while ( auto pActor = it . Next ( ) )
2019-08-31 07:47:15 +00:00
{
2021-10-20 20:27:16 +00:00
if ( pActor - > s ( ) . cstat & 0x101 ) {
2019-08-31 07:47:15 +00:00
return 1 ;
}
}
b = 0 ;
}
return b ;
2019-08-26 03:59:14 +00:00
}
// done
void MoveSectorSprites ( int nSector , int z )
{
2021-01-12 19:57:28 +00:00
int newz = sector [ nSector ] . floorz ;
int oldz = newz - z ;
int minz = std : : min ( newz , oldz ) ;
int maxz = std : : max ( newz , oldz ) ;
2021-10-20 20:27:16 +00:00
ExhumedSectIterator it ( nSector ) ;
while ( auto pActor = it . Next ( ) )
2019-08-31 07:47:15 +00:00
{
2021-10-20 20:27:16 +00:00
auto pSprite = & pActor - > s ( ) ;
2021-09-06 06:33:02 +00:00
int z = pSprite - > z ;
if ( ( pSprite - > statnum ! = 200 & & z > = minz & & z < = maxz ) | | pSprite - > statnum > = 900 )
2021-01-12 19:57:28 +00:00
{
2021-09-06 06:33:02 +00:00
pSprite - > z = newz ;
2019-08-31 07:47:15 +00:00
}
}
2019-08-26 03:59:14 +00:00
}
void StartElevSound ( short nSprite , int nVal )
{
2019-08-31 07:47:15 +00:00
short nSound ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nVal & 2 ) {
nSound = nElevSound ;
}
else {
nSound = nStoneSound ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
D3PlayFX ( StaticSound [ nSound ] , nSprite ) ;
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void AIElev : : ProcessChannel ( RunListEvent * ev )
2019-08-26 03:59:14 +00:00
{
2021-10-15 20:13:05 +00:00
int nRun = ev - > nRun ;
2021-10-17 14:22:25 +00:00
short nElev = RunData [ nRun ] . nObjIndex ;
2020-11-29 23:49:25 +00:00
assert ( nElev > = 0 & & nElev < ( int ) Elevator . Size ( ) ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short nChannel = Elevator [ nElev ] . nChannel ;
short var_18 = Elevator [ nElev ] . field_0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
assert ( nChannel > = 0 & & nChannel < kMaxChannels ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// short ax = var_18 & 8;
short dx = sRunChannels [ nChannel ] . c ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
int edi = 999 ; // FIXME CHECKME - this isn't default set to anything in the ASM that I can see - if ax is 0 and var_24 is 0, this will never be set to a known value otherwise!
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( var_18 & 0x8 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
if ( dx ) {
edi = 1 ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
else {
edi = 0 ;
}
}
else
{
// loc_20D48:
if ( var_18 & 0x10 ) // was var_24
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
if ( Elevator [ nElev ] . field_32 < 0 )
2019-08-31 07:47:15 +00:00
{
2021-10-17 14:22:25 +00:00
Elevator [ nElev ] . field_32 = runlist_AddRunRec ( NewRun , & RunData [ nRun ] ) ;
2021-10-15 20:13:05 +00:00
StartElevSound ( Elevator [ nElev ] . nSprite , var_18 ) ;
edi = 1 ;
}
}
else
{
if ( dx < 0 ) {
edi = 0 ;
2019-08-31 07:47:15 +00:00
}
else
{
2021-10-15 20:13:05 +00:00
if ( dx = = Elevator [ nElev ] . nCurZOffset | | dx > = Elevator [ nElev ] . nCountZOffsets )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
Elevator [ nElev ] . field_36 = dx ;
edi = 1 ;
2019-08-31 07:47:15 +00:00
}
else
{
2021-10-15 20:13:05 +00:00
Elevator [ nElev ] . nCurZOffset = sRunChannels [ nChannel ] . c ;
edi = 1 ;
2019-08-31 07:47:15 +00:00
}
}
2021-10-15 20:13:05 +00:00
}
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
assert ( edi ! = 999 ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
// loc_20DF9:
if ( edi )
{
if ( Elevator [ nElev ] . field_32 < 0 )
{
2021-10-17 14:22:25 +00:00
Elevator [ nElev ] . field_32 = runlist_AddRunRec ( NewRun , & RunData [ nRun ] ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
StartElevSound ( Elevator [ nElev ] . nSprite , var_18 ) ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
}
else
{
//loc_20E4E:
if ( Elevator [ nElev ] . field_32 > = 0 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
runlist_SubRunRec ( Elevator [ nElev ] . field_32 ) ;
Elevator [ nElev ] . field_32 = - 1 ;
}
}
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
void AIElev : : Tick ( RunListEvent * ev )
{
int nRun = ev - > nRun ;
2021-10-17 14:22:25 +00:00
short nElev = RunData [ nRun ] . nObjIndex ;
2021-10-15 20:13:05 +00:00
assert ( nElev > = 0 & & nElev < ( int ) Elevator . Size ( ) ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
short nChannel = Elevator [ nElev ] . nChannel ;
short var_18 = Elevator [ nElev ] . field_0 ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
assert ( nChannel > = 0 & & nChannel < kMaxChannels ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
short nSector = Elevator [ nElev ] . nSector ;
2021-10-20 20:16:50 +00:00
auto pElevSpr = & exhumedActors [ Elevator [ nElev ] . nSprite ] ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
int ebp = 0 ; // initialise to *something*
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( var_18 & 0x2 )
{
int nZOffset = Elevator [ nElev ] . nCurZOffset ;
int nZVal = Elevator [ nElev ] . zOffsets [ nZOffset ] ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
short nSectorB = nSector ;
StartInterpolation ( nSector , Interp_Sect_Floorz ) ;
int nVal = LongSeek ( ( int * ) & sector [ nSector ] . floorz , nZVal , Elevator [ nElev ] . field_6 , Elevator [ nElev ] . field_A ) ;
ebp = nVal ;
if ( ! nVal )
{
if ( var_18 & 0x10 )
{
Elevator [ nElev ] . nCurZOffset ^ = 1 ;
2021-10-20 20:16:50 +00:00
StartElevSound ( pElevSpr - > GetSpriteIndex ( ) , var_18 ) ;
2019-08-31 07:47:15 +00:00
}
else
{
2021-10-20 20:16:50 +00:00
StopActorSound ( pElevSpr ) ;
2021-10-15 20:13:05 +00:00
runlist_SubRunRec ( nRun ) ;
Elevator [ nElev ] . field_32 = - 1 ;
runlist_ReadyChannel ( nChannel ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
D3PlayFX ( StaticSound [ nStopSound ] , Elevator [ nElev ] . nSprite ) ;
}
}
else
{
assert ( nSector = = nSectorB ) ;
MoveSectorSprites ( nSector , nVal ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( nVal < 0 & & CheckSectorSprites ( nSector , 2 ) )
{
runlist_ChangeChannel ( nChannel , sRunChannels [ nChannel ] . c = = 0 ) ;
return ;
}
}
}
else
{
// loc_20FC3:
int ceilZ = sector [ nSector ] . ceilingz ;
sectortype * cursect = & sector [ nSector ] ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
int nZOffset = Elevator [ nElev ] . nCurZOffset ;
int zVal = Elevator [ nElev ] . zOffsets [ nZOffset ] ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
StartInterpolation ( nSector , Interp_Sect_Ceilingz ) ;
int nVal = LongSeek ( & ceilZ , zVal , Elevator [ nElev ] . field_6 , Elevator [ nElev ] . field_A ) ;
ebp = nVal ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( ! nVal )
{
if ( var_18 & 0x10 )
{
Elevator [ nElev ] . nCurZOffset ^ = 1 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
StartElevSound ( Elevator [ nElev ] . nSprite , var_18 ) ;
}
else
{
runlist_SubRunRec ( nRun ) ;
Elevator [ nElev ] . field_32 = - 1 ;
StopSpriteSound ( Elevator [ nElev ] . nSprite ) ;
D3PlayFX ( StaticSound [ nStopSound ] , Elevator [ nElev ] . nSprite ) ;
runlist_ReadyChannel ( nChannel ) ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
return ;
}
else if ( nVal > 0 )
{
if ( ceilZ = = zVal )
{
if ( var_18 & 0x4 ) {
2021-10-20 20:16:50 +00:00
SetQuake ( pElevSpr , 30 ) ;
2019-08-31 07:47:15 +00:00
}
2021-10-20 20:16:50 +00:00
auto sp = & pElevSpr - > s ( ) ;
PlayFXAtXYZ ( StaticSound [ kSound26 ] , sp - > x , sp - > y , sp - > z , sp - > sectnum ) ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
if ( var_18 & 0x4 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
if ( CheckSectorSprites ( nSector , 1 ) ) {
return ;
}
}
else
{
if ( CheckSectorSprites ( nSector , 0 ) )
{
runlist_ChangeChannel ( nChannel , sRunChannels [ nChannel ] . c = = 0 ) ;
return ;
}
2019-08-31 07:47:15 +00:00
}
}
2021-10-15 20:13:05 +00:00
StartInterpolation ( nSector , Interp_Sect_Ceilingz ) ;
cursect - > ceilingz = ceilZ ;
}
// maybe this doesn't go here?
2021-10-20 20:16:50 +00:00
while ( pElevSpr )
2021-10-15 20:13:05 +00:00
{
2021-10-20 20:16:50 +00:00
pElevSpr - > s ( ) . z + = ebp ;
pElevSpr = pElevSpr - > pTarget ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void FuncElev ( int nObject , int nMessage , int nDamage , int nRun )
{
AIElev ai ;
runlist_DispatchEvent ( & ai , nObject , nMessage , nDamage , nRun ) ;
}
2019-08-26 03:59:14 +00:00
// done
void InitWallFace ( )
{
2020-11-29 23:49:25 +00:00
WallFace . Clear ( ) ;
2019-08-26 03:59:14 +00:00
}
2020-01-07 00:11:19 +00:00
int BuildWallFace ( short nChannel , short nWall , int nCount , . . . )
2019-08-26 03:59:14 +00:00
{
2020-11-29 23:49:25 +00:00
auto WallFaceCount = WallFace . Reserve ( 1 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
WallFace [ WallFaceCount ] . field_4 = 0 ;
WallFace [ WallFaceCount ] . nWall = nWall ;
WallFace [ WallFaceCount ] . nChannel = nChannel ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nCount > 8 ) {
nCount = 8 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 10:36:26 +00:00
va_list piclist ;
va_start ( piclist , nCount ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
while ( WallFace [ WallFaceCount ] . field_4 < nCount )
{
int i = WallFace [ WallFaceCount ] . field_4 ;
WallFace [ WallFaceCount ] . field_4 + + ;
2019-08-26 03:59:14 +00:00
2019-11-13 22:13:11 +00:00
WallFace [ WallFaceCount ] . field_6 [ i ] = ( short ) va_arg ( piclist , int ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-31 10:36:26 +00:00
va_end ( piclist ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 16:37:39 +00:00
return WallFaceCount ;
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void AIWallFace : : ProcessChannel ( RunListEvent * ev )
2019-08-26 03:59:14 +00:00
{
2021-10-17 14:22:25 +00:00
int nWallFace = RunData [ ev - > nRun ] . nObjIndex ;
2020-11-29 23:49:25 +00:00
assert ( nWallFace > = 0 & & nWallFace < ( int ) WallFace . Size ( ) ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short nChannel = WallFace [ nWallFace ] . nChannel ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short si = sRunChannels [ nChannel ] . c ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ( si < = WallFace [ nWallFace ] . field_4 ) & & ( si > = 0 ) )
{
wall [ WallFace [ nWallFace ] . nWall ] . picnum = WallFace [ nWallFace ] . field_6 [ si ] ;
}
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void FuncWallFace ( int nObject , int nMessage , int nDamage , int nRun )
{
AIWallFace ai ;
runlist_DispatchEvent ( & ai , nObject , nMessage , nDamage , nRun ) ;
}
2019-08-26 03:59:14 +00:00
// done
void InitPoint ( )
{
2020-11-29 23:49:25 +00:00
PointList . Clear ( ) ;
2019-08-26 03:59:14 +00:00
}
// done
int GrabPoint ( )
{
2020-11-29 23:49:25 +00:00
return PointList . Reserve ( 1 ) ;
2019-08-26 03:59:14 +00:00
}
// done
void InitSlide ( )
{
2020-11-29 23:49:25 +00:00
SlideData . Clear ( ) ;
2019-08-26 03:59:14 +00:00
}
int IdentifySector ( int nVal )
{
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < numsectors ; i + + )
{
for ( int j = 0 ; ; j + + )
{
if ( j < sector [ i ] . wallnum )
{
int nWall = sector [ i ] . wallptr ;
if ( nWall + j = = nVal )
return i ;
}
else {
break ;
}
}
}
return - 1 ;
2019-08-26 03:59:14 +00:00
}
2021-01-04 19:34:27 +00:00
int BuildSlide ( int nChannel , int nStartWall , int nWall1 , int ecx , int nWall2 , int nWall3 , int nWall4 )
2019-08-26 03:59:14 +00:00
{
2020-11-29 23:49:25 +00:00
auto nSlide = SlideData . Reserve ( 1 ) ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
short nSector = IdentifySector ( nStartWall ) ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
SlideData [ nSlide ] . field_4a = - 1 ;
SlideData [ nSlide ] . nChannel = nChannel ;
2021-10-21 10:08:22 +00:00
SlideData [ nSlide ] . nStart = - 1 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nPoint = GrabPoint ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
SlideData [ nSlide ] . nStart = nPoint ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
PointList [ nPoint ] . nNext = - 1 ;
PointList [ nPoint ] . nSector = nSector ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short startwall = sector [ nSector ] . wallptr ;
short endwall = startwall + sector [ nSector ] . wallnum ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( int nWall = startwall ; nWall < endwall ; nWall + + )
{
2021-10-21 10:08:22 +00:00
short ax = SlideData [ nSlide ] . nStart ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ax > = 0 )
{
while ( ax > = 0 )
{
2021-10-21 10:08:22 +00:00
if ( wall [ nWall ] . nextsector = = PointList [ ax ] . nSector ) {
2019-08-31 07:47:15 +00:00
break ;
}
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
ax = PointList [ ax ] . nNext ;
2019-08-31 07:47:15 +00:00
}
}
else
{
if ( wall [ nWall ] . nextsector > = 0 )
{
nPoint = GrabPoint ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
PointList [ nPoint ] . nNext = SlideData [ nSlide ] . nStart ;
PointList [ nPoint ] . nSector = wall [ nWall ] . nextsector ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
SlideData [ nSlide ] . nStart = nPoint ;
2019-08-31 07:47:15 +00:00
}
}
}
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
SlideData [ nSlide ] . field_0 = nStartWall ;
2021-01-04 19:34:27 +00:00
SlideData [ nSlide ] . field_4 = nWall1 ;
2020-02-04 21:45:10 +00:00
SlideData [ nSlide ] . field_8 = nWall2 ;
SlideData [ nSlide ] . field_C = nWall3 ;
SlideData [ nSlide ] . x1 = wall [ nStartWall ] . x ;
SlideData [ nSlide ] . y1 = wall [ nStartWall ] . y ;
SlideData [ nSlide ] . x2 = wall [ nWall2 ] . x ;
SlideData [ nSlide ] . y2 = wall [ nWall2 ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
SlideData [ nSlide ] . x3 = wall [ nWall1 ] . x ;
SlideData [ nSlide ] . y3 = wall [ nWall1 ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
SlideData [ nSlide ] . x4 = wall [ nWall3 ] . x ;
SlideData [ nSlide ] . y4 = wall [ nWall3 ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
SlideData [ nSlide ] . x5 = wall [ ecx ] . x ;
SlideData [ nSlide ] . y5 = wall [ ecx ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
SlideData [ nSlide ] . x6 = wall [ nWall4 ] . x ;
SlideData [ nSlide ] . y6 = wall [ nWall4 ] . y ;
2019-08-26 03:59:14 +00:00
2021-01-04 19:34:27 +00:00
StartInterpolation ( nStartWall , Interp_Wall_X ) ;
StartInterpolation ( nStartWall , Interp_Wall_Y ) ;
StartInterpolation ( nWall1 , Interp_Wall_X ) ;
StartInterpolation ( nWall1 , Interp_Wall_Y ) ;
StartInterpolation ( nWall2 , Interp_Wall_X ) ;
StartInterpolation ( nWall2 , Interp_Wall_Y ) ;
StartInterpolation ( nWall3 , Interp_Wall_X ) ;
StartInterpolation ( nWall3 , Interp_Wall_Y ) ;
2021-10-21 10:08:22 +00:00
auto pActor = insertActor ( nSector , 899 ) ;
auto pSprite = & pActor - > s ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
SlideData [ nSlide ] . pActor = pActor ;
2021-09-06 06:33:02 +00:00
pSprite - > cstat = 0x8000 ;
pSprite - > x = wall [ nStartWall ] . x ;
pSprite - > y = wall [ nStartWall ] . y ;
pSprite - > z = sector [ nSector ] . floorz ;
pSprite - > backuppos ( ) ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
SlideData [ nSlide ] . field_8a = 0 ;
2019-08-26 03:59:14 +00:00
2021-10-15 16:37:39 +00:00
return nSlide ;
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void AISlide : : ProcessChannel ( RunListEvent * ev )
2019-08-26 03:59:14 +00:00
{
2021-10-15 20:13:05 +00:00
int nRun = ev - > nRun ;
2021-10-17 14:22:25 +00:00
int nSlide = RunData [ nRun ] . nObjIndex ;
2020-11-29 23:49:25 +00:00
assert ( nSlide > = 0 & & nSlide < ( int ) SlideData . Size ( ) ) ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
short nChannel = SlideData [ nSlide ] . nChannel ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( SlideData [ nSlide ] . field_4a > = 0 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
runlist_SubRunRec ( SlideData [ nSlide ] . field_4a ) ;
SlideData [ nSlide ] . field_4a = - 1 ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( sRunChannels [ nChannel ] . c & & sRunChannels [ nChannel ] . c ! = 1 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2021-10-17 14:22:25 +00:00
SlideData [ nSlide ] . field_4a = runlist_AddRunRec ( NewRun , & RunData [ nRun ] ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( SlideData [ nSlide ] . field_8a ! = sRunChannels [ nChannel ] . c )
{
2021-10-21 10:08:22 +00:00
D3PlayFX ( StaticSound [ kSound23 ] , SlideData [ nSlide ] . pActor ) ;
2021-10-15 20:13:05 +00:00
SlideData [ nSlide ] . field_8a = sRunChannels [ nChannel ] . c ;
}
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
void AISlide : : Tick ( RunListEvent * ev )
{
int nRun = ev - > nRun ;
2021-10-17 14:22:25 +00:00
int nSlide = RunData [ nRun ] . nObjIndex ;
2021-10-15 20:13:05 +00:00
assert ( nSlide > = 0 & & nSlide < ( int ) SlideData . Size ( ) ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
short nChannel = SlideData [ nSlide ] . nChannel ;
int ebp = 0 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
short cx = sRunChannels [ nChannel ] . c ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
int clipmask = ebp + 1 ; // RENAME
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( cx = = 1 )
{
short nWall = SlideData [ nSlide ] . field_4 ;
int x = wall [ nWall ] . x ;
int y = wall [ nWall ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
int nSeekA = LongSeek ( & x , SlideData [ nSlide ] . x5 , 20 , 20 ) ;
2021-10-15 20:13:05 +00:00
int var_34 = nSeekA ;
int var_20 = nSeekA ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
int nSeekB = LongSeek ( & y , SlideData [ nSlide ] . y5 , 20 , 20 ) ;
2021-10-15 20:13:05 +00:00
int var_2C = nSeekB ;
int var_24 = nSeekB ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
dragpoint ( SlideData [ nSlide ] . field_4 , x , y , 0 ) ;
2021-10-21 10:08:22 +00:00
movesprite ( SlideData [ nSlide ] . pActor , var_34 < < 14 , var_2C < < 14 , 0 , 0 , 0 , CLIPMASK1 ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( var_34 = = 0 )
{
if ( var_2C = = 0 )
{
ebp = clipmask ;
}
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
nWall = SlideData [ nSlide ] . field_0 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
y = wall [ nWall ] . y + var_24 ;
x = wall [ nWall ] . x + var_20 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
dragpoint ( SlideData [ nSlide ] . field_0 , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
nWall = SlideData [ nSlide ] . field_C ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
x = wall [ nWall ] . x ;
y = wall [ nWall ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
int nSeekC = LongSeek ( & x , SlideData [ nSlide ] . x6 , 20 , 20 ) ;
2021-10-15 20:13:05 +00:00
int var_30 = nSeekC ;
var_20 = nSeekC ;
2019-08-26 03:59:14 +00:00
2021-10-21 10:08:22 +00:00
int nSeekD = LongSeek ( & y , SlideData [ nSlide ] . y6 , 20 , 20 ) ;
2021-10-15 20:13:05 +00:00
int edi = nSeekD ;
var_24 = nSeekD ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
dragpoint ( SlideData [ nSlide ] . field_C , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( var_30 = = 0 & & edi = = 0 ) {
ebp + + ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
nWall = SlideData [ nSlide ] . field_8 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
x = wall [ nWall ] . x + var_20 ;
y = wall [ nWall ] . y + var_24 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
dragpoint ( SlideData [ nSlide ] . field_8 , x , y , 0 ) ;
}
else if ( cx = = 0 ) // right branch
{
short nWall = SlideData [ nSlide ] . field_0 ;
int x = wall [ nWall ] . x ;
int y = wall [ nWall ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
int nSeekA = LongSeek ( & x , SlideData [ nSlide ] . x1 , 20 , 20 ) ;
int edi = nSeekA ;
int var_1C = nSeekA ;
2019-11-20 16:21:32 +00:00
2021-10-15 20:13:05 +00:00
int nSeekB = LongSeek ( & y , SlideData [ nSlide ] . y1 , 20 , 20 ) ;
int ecx = nSeekB ;
int var_28 = nSeekB ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
dragpoint ( SlideData [ nSlide ] . field_0 , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( edi = = 0 & & ecx = = 0 ) {
ebp = clipmask ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
nWall = SlideData [ nSlide ] . field_4 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
y = wall [ nWall ] . y + var_28 ;
x = wall [ nWall ] . x + var_1C ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
dragpoint ( SlideData [ nSlide ] . field_4 , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
nWall = SlideData [ nSlide ] . field_8 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
x = wall [ nWall ] . x ;
y = wall [ nWall ] . y ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
int nSeekC = LongSeek ( & x , SlideData [ nSlide ] . x2 , 20 , 20 ) ;
edi = nSeekC ;
var_1C = nSeekC ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
int nSeekD = LongSeek ( & y , SlideData [ nSlide ] . y2 , 20 , 20 ) ;
ecx = nSeekD ;
var_28 = nSeekD ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
dragpoint ( SlideData [ nSlide ] . field_8 , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( edi = = 0 & & ecx = = 0 ) {
ebp + + ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
nWall = SlideData [ nSlide ] . field_C ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
y = wall [ nWall ] . y + var_28 ;
x = wall [ nWall ] . x + var_1C ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
dragpoint ( SlideData [ nSlide ] . field_C , x , y , 0 ) ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// loc_21A51:
if ( ebp > = 2 )
{
runlist_SubRunRec ( SlideData [ nSlide ] . field_4a ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
SlideData [ nSlide ] . field_4a = - 1 ;
2021-10-21 10:08:22 +00:00
D3PlayFX ( StaticSound [ nStopSound ] , SlideData [ nSlide ] . pActor ) ;
2021-10-15 20:13:05 +00:00
runlist_ReadyChannel ( nChannel ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void FuncSlide ( int nObject , int nMessage , int nDamage , int nRun )
{
AISlide ai ;
runlist_DispatchEvent ( & ai , nObject , nMessage , nDamage , nRun ) ;
}
2021-10-21 11:09:29 +00:00
int BuildTrap ( DExhumedActor * pActor , int edx , int ebx , int ecx )
2019-08-26 03:59:14 +00:00
{
2021-10-21 11:09:29 +00:00
auto pSprite = & pActor - > s ( ) ;
2019-08-31 07:47:15 +00:00
int var_14 = edx ;
int var_18 = ebx ;
int var_10 = ecx ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
int nTrap = sTrap . Reserve ( 1 ) ;
2019-08-26 03:59:14 +00:00
2021-10-21 11:09:29 +00:00
ChangeActorStat ( pActor , 0 ) ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > cstat = 0x8000 ;
pSprite - > xvel = 0 ;
pSprite - > yvel = 0 ;
pSprite - > zvel = 0 ;
pSprite - > extra = - 1 ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > lotag = runlist_HeadRun ( ) + 1 ;
2021-10-15 16:37:39 +00:00
pSprite - > hitag = runlist_AddRunRec ( NewRun , nTrap , 0x1F0000 ) ;
pSprite - > owner = runlist_AddRunRec ( pSprite - > lotag - 1 , nTrap , 0x1F0000 ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// GrabTimeSlot(3);
2019-08-26 03:59:14 +00:00
2021-10-21 11:09:29 +00:00
sTrap [ nTrap ] . pActor = pActor ;
2019-08-31 07:47:15 +00:00
sTrap [ nTrap ] . nType = ( var_14 = = 0 ) + 14 ;
sTrap [ nTrap ] . field_0 = - 1 ;
2020-11-29 23:49:25 +00:00
sTrap [ nTrap ] . nTrapInterval = 64 - ( 2 * var_10 ) ;
if ( sTrap [ nTrap ] . nTrapInterval < 5 ) {
sTrap [ nTrap ] . nTrapInterval = 5 ;
2019-08-31 07:47:15 +00:00
}
sTrap [ nTrap ] . field_C = 0 ;
sTrap [ nTrap ] . field_A = 0 ;
if ( var_18 = = - 1 ) {
2021-10-22 06:06:24 +00:00
return nTrap ;
2019-08-31 07:47:15 +00:00
}
sTrap [ nTrap ] . field_6 = - 1 ;
sTrap [ nTrap ] . field_8 = - 1 ;
2021-09-06 06:33:02 +00:00
short nSector = pSprite - > sectnum ;
2019-08-31 07:47:15 +00:00
short nWall = sector [ nSector ] . wallptr ;
int i = 0 ;
while ( 1 )
{
if ( sector [ nSector ] . wallnum > = i ) {
2021-10-21 11:09:29 +00:00
break ;
2019-08-31 07:47:15 +00:00
}
if ( var_18 = = wall [ nWall ] . hitag )
{
if ( sTrap [ nTrap ] . field_6 ! = - 1 )
{
sTrap [ nTrap ] . field_8 = nWall ;
sTrap [ nTrap ] . field_C = wall [ nWall ] . picnum ;
2021-10-21 11:09:29 +00:00
break ;
2019-08-31 07:47:15 +00:00
}
else
{
sTrap [ nTrap ] . field_6 = nWall ;
sTrap [ nTrap ] . field_A = wall [ nWall ] . picnum ;
}
}
ecx + + ;
nWall + + ;
}
2021-09-06 06:33:02 +00:00
pSprite - > backuppos ( ) ;
2021-10-21 11:09:29 +00:00
return nTrap ;
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void AITrap : : ProcessChannel ( RunListEvent * ev )
2019-08-26 03:59:14 +00:00
{
2021-10-17 14:22:25 +00:00
short nChannel = ev - > nParam & 0x3FFF ;
short nTrap = RunData [ ev - > nRun ] . nObjIndex ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( sRunChannels [ nChannel ] . c > 0 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
sTrap [ nTrap ] . field_0 = 12 ;
}
else
{
sTrap [ nTrap ] . field_0 = - 1 ;
}
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
void AITrap : : Tick ( RunListEvent * ev )
{
2021-10-17 14:22:25 +00:00
short nTrap = RunData [ ev - > nRun ] . nObjIndex ;
2021-10-21 11:09:29 +00:00
auto pActor = sTrap [ nTrap ] . pActor ;
auto pSprite = & pActor - > s ( ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( sTrap [ nTrap ] . field_0 > = 0 )
{
sTrap [ nTrap ] . field_0 - - ;
if ( sTrap [ nTrap ] . field_0 > 10 ) {
2019-08-31 07:47:15 +00:00
return ;
}
2021-10-15 20:13:05 +00:00
short nType = sTrap [ nTrap ] . nType ;
if ( sTrap [ nTrap ] . field_0 = = 0 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
sTrap [ nTrap ] . field_0 = sTrap [ nTrap ] . nTrapInterval ;
if ( nType = = 14 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
short nWall = sTrap [ nTrap ] . field_6 ;
if ( nWall > - 1 )
{
wall [ nWall ] . picnum = sTrap [ nTrap ] . field_A ;
2019-08-31 07:47:15 +00:00
}
2019-11-20 16:21:32 +00:00
2021-10-15 20:13:05 +00:00
nWall = sTrap [ nTrap ] . field_8 ;
if ( nWall > - 1 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
wall [ nWall ] . picnum = sTrap [ nTrap ] . field_C ;
}
}
}
else
{
// loc_21D92:
if ( sTrap [ nTrap ] . field_0 ! = 5 ) {
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-21 11:09:29 +00:00
auto pBullet = BuildBullet ( pActor , nType , 0 , pSprite - > ang , nullptr , 1 ) ;
2021-10-19 22:26:26 +00:00
if ( pBullet )
2021-10-15 20:13:05 +00:00
{
if ( nType = = 15 )
{
2021-10-19 22:26:26 +00:00
pBullet - > s ( ) . ang = ( pBullet - > s ( ) . ang - 512 ) & kAngleMask ;
D3PlayFX ( StaticSound [ kSound32 ] , pBullet ) ;
2019-08-31 07:47:15 +00:00
}
else
{
2021-10-19 22:26:26 +00:00
pBullet - > s ( ) . clipdist = 50 ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
short nWall = sTrap [ nTrap ] . field_6 ;
if ( nWall > - 1 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
wall [ nWall ] . picnum = sTrap [ nTrap ] . field_A + 1 ;
}
2019-11-22 00:10:56 +00:00
2021-10-15 20:13:05 +00:00
nWall = sTrap [ nTrap ] . field_8 ;
if ( nWall > - 1 )
{
wall [ nWall ] . picnum = sTrap [ nTrap ] . field_C + 1 ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
2021-10-19 22:26:26 +00:00
D3PlayFX ( StaticSound [ kSound36 ] , pBullet ) ;
2019-08-31 07:47:15 +00:00
}
}
}
}
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void FuncTrap ( int nObject , int nMessage , int nDamage , int nRun )
{
AITrap ai ;
runlist_DispatchEvent ( & ai , nObject , nMessage , nDamage , nRun ) ;
}
2021-10-21 11:09:29 +00:00
int BuildArrow ( DExhumedActor * nSprite , int nVal )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
return BuildTrap ( nSprite , 0 , - 1 , nVal ) ;
2019-08-26 03:59:14 +00:00
}
2021-10-21 11:09:29 +00:00
int BuildFireBall ( DExhumedActor * nSprite , int a , int b )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
return BuildTrap ( nSprite , 1 , a , b ) ;
2019-08-26 03:59:14 +00:00
}
2021-10-21 11:15:47 +00:00
DExhumedActor * BuildSpark ( DExhumedActor * pActor , int nVal )
2019-08-26 03:59:14 +00:00
{
2021-10-21 11:15:47 +00:00
auto pSprite = & pActor - > s ( ) ;
auto pSpark = insertActor ( pSprite - > sectnum , 0 ) ;
2019-08-31 07:47:15 +00:00
2021-10-21 11:15:47 +00:00
auto spr = & pSpark - > s ( ) ;
2019-08-31 07:47:15 +00:00
2021-09-06 06:33:02 +00:00
spr - > x = pSprite - > x ;
spr - > y = pSprite - > y ;
2020-10-14 22:10:37 +00:00
spr - > cstat = 0 ;
spr - > shade = - 127 ;
spr - > pal = 1 ;
spr - > xoffset = 0 ;
spr - > yoffset = 0 ;
spr - > xrepeat = 50 ;
spr - > yrepeat = 50 ;
2019-08-31 07:47:15 +00:00
if ( nVal > = 2 )
{
2020-10-14 22:10:37 +00:00
spr - > picnum = kEnergy2 ;
2019-08-31 07:47:15 +00:00
nSmokeSparks + + ;
if ( nVal = = 3 )
{
2020-10-14 22:10:37 +00:00
spr - > xrepeat = 120 ;
spr - > yrepeat = 120 ;
2019-08-31 07:47:15 +00:00
}
else
{
2021-09-06 06:33:02 +00:00
spr - > xrepeat = pSprite - > xrepeat + 15 ;
spr - > yrepeat = pSprite - > xrepeat + 15 ;
2019-08-31 07:47:15 +00:00
}
}
else
{
2021-09-06 06:33:02 +00:00
int nAngle = ( pSprite - > ang + 256 ) - RandomSize ( 9 ) ;
2019-08-31 07:47:15 +00:00
if ( nVal )
{
2020-11-14 08:45:08 +00:00
spr - > xvel = bcos ( nAngle , - 5 ) ;
spr - > yvel = bsin ( nAngle , - 5 ) ;
2019-08-31 07:47:15 +00:00
}
else
{
2020-11-14 08:45:08 +00:00
spr - > xvel = bcos ( nAngle , - 6 ) ;
spr - > yvel = bsin ( nAngle , - 6 ) ;
2019-08-31 07:47:15 +00:00
}
2020-10-14 22:10:37 +00:00
spr - > zvel = - ( RandomSize ( 4 ) < < 7 ) ;
spr - > picnum = kTile985 + nVal ;
2019-08-31 07:47:15 +00:00
}
2021-09-06 06:33:02 +00:00
spr - > z = pSprite - > z ;
2020-10-14 22:10:37 +00:00
spr - > lotag = runlist_HeadRun ( ) + 1 ;
spr - > clipdist = 1 ;
spr - > hitag = 0 ;
2021-02-26 23:16:03 +00:00
spr - > backuppos ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// GrabTimeSlot(3);
2019-08-26 03:59:14 +00:00
2020-10-14 22:10:37 +00:00
spr - > extra = - 1 ;
2021-10-21 11:15:47 +00:00
spr - > owner = runlist_AddRunRec ( spr - > lotag - 1 , pSpark , 0x260000 ) ;
spr - > hitag = runlist_AddRunRec ( NewRun , pSpark , 0x260000 ) ;
2019-08-26 03:59:14 +00:00
2021-10-21 11:15:47 +00:00
return pSpark ;
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void AISpark : : Tick ( RunListEvent * ev )
2019-08-26 03:59:14 +00:00
{
2021-10-21 11:15:47 +00:00
auto pActor = ev - > pObjActor ;
if ( ! pActor ) return ;
auto pSprite = & pActor - > s ( ) ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > shade + = 3 ;
pSprite - > xrepeat - = 2 ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
if ( pSprite - > xrepeat > = 4 & & pSprite - > shade < = 100 )
2019-08-31 07:47:15 +00:00
{
2021-09-06 06:33:02 +00:00
pSprite - > yrepeat - = 2 ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
// calling BuildSpark() with 2nd parameter as '1' will set kTile986
2021-09-06 06:33:02 +00:00
if ( pSprite - > picnum = = kTile986 & & ( pSprite - > xrepeat & 2 ) )
2019-08-31 07:47:15 +00:00
{
2021-10-21 11:15:47 +00:00
BuildSpark ( pActor , 2 ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
if ( pSprite - > picnum > = kTile3000 ) {
2019-08-31 07:47:15 +00:00
return ;
}
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > zvel + = 128 ;
2019-08-26 03:59:14 +00:00
2021-10-21 11:15:47 +00:00
auto nMov = movesprite ( pActor , pSprite - > xvel < < 12 , pSprite - > yvel < < 12 , pSprite - > zvel , 2560 , - 2560 , CLIPMASK1 ) ;
if ( ! nMov . type & & ! nMov . exbits ) {
2019-08-31 07:47:15 +00:00
return ;
}
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
if ( pSprite - > zvel < = 0 ) {
2019-08-31 07:47:15 +00:00
return ;
}
}
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > xvel = 0 ;
pSprite - > yvel = 0 ;
pSprite - > zvel = 0 ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
if ( pSprite - > picnum > kTile3000 ) {
2019-08-31 07:47:15 +00:00
nSmokeSparks - - ;
}
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
runlist_DoSubRunRec ( pSprite - > owner ) ;
runlist_FreeRun ( pSprite - > lotag - 1 ) ;
runlist_SubRunRec ( pSprite - > hitag ) ;
2021-10-21 11:15:47 +00:00
DeleteActor ( pActor ) ;
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void FuncSpark ( int nObject , int nMessage , int nDamage , int nRun )
{
AISpark ai ;
runlist_DispatchEvent ( & ai , nObject , nMessage , nDamage , nRun ) ;
}
2019-08-26 03:59:14 +00:00
void DimLights ( )
{
2019-08-31 07:47:15 +00:00
static short word_96786 = 0 ;
word_96786 = word_96786 = = 0 ;
if ( word_96786 = = 0 )
return ;
for ( int i = 0 ; i < numsectors ; i + + )
{
if ( sector [ i ] . ceilingshade < 100 )
sector [ i ] . ceilingshade + + ;
if ( sector [ i ] . floorshade < 100 )
sector [ i ] . floorshade + + ;
2019-11-29 21:24:11 +00:00
short startwall = sector [ i ] . wallptr ;
short endwall = startwall + sector [ i ] . wallnum ;
2019-11-20 16:21:32 +00:00
2019-11-29 21:24:11 +00:00
for ( int nWall = startwall ; nWall < endwall ; nWall + + )
2019-08-31 07:47:15 +00:00
{
if ( wall [ nWall ] . shade < 100 )
wall [ nWall ] . shade + + ;
}
}
2019-08-26 03:59:14 +00:00
}
void DoFinale ( )
{
2019-08-31 07:47:15 +00:00
static int dword_96788 = 0 ;
2020-09-02 20:55:57 +00:00
static int nextstage = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ! lFinaleStart )
return ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
dword_96788 + + ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( dword_96788 < 90 )
{
if ( ! ( dword_96788 & 2 ) )
{
int nAng = RandomSize ( 11 ) ;
2021-10-21 11:20:00 +00:00
pFinaleSpr - > s ( ) . ang = nAng ;
BuildSpark ( pFinaleSpr , 1 ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ! RandomSize ( 2 ) )
{
2021-10-21 11:20:00 +00:00
PlayFX2 ( StaticSound [ kSound78 ] | 0x2000 , pFinaleSpr ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < nTotalPlayers ; i + + ) {
nQuake [ i ] = 1280 ;
}
}
}
else
{
DimLights ( ) ;
if ( nDronePitch < = - 2400 )
{
if ( nFinaleStage < 2 )
{
if ( nFinaleStage = = 1 )
{
StopLocalSound ( ) ;
PlayLocalSound ( StaticSound [ kSound76 ] , 0 ) ;
2021-02-18 10:46:36 +00:00
nextstage = PlayClock + 120 ;
2020-02-04 21:45:10 +00:00
nFinaleStage + + ;
2019-08-31 07:47:15 +00:00
}
}
else if ( nFinaleStage < = 2 )
{
2021-02-18 10:46:36 +00:00
if ( PlayClock > = nextstage )
2019-08-31 07:47:15 +00:00
{
PlayLocalSound ( StaticSound [ kSound77 ] , 0 ) ;
nFinaleStage + + ;
2021-02-18 10:46:36 +00:00
nextstage = PlayClock + 360 ;
2019-08-31 07:47:15 +00:00
}
}
2021-02-18 10:46:36 +00:00
else if ( nFinaleStage = = 3 & & PlayClock > = nextstage )
2019-08-31 07:47:15 +00:00
{
2020-09-11 18:56:46 +00:00
LevelFinished ( ) ;
2019-08-31 07:47:15 +00:00
}
}
else
{
nDronePitch - = 128 ;
BendAmbientSound ( ) ;
nFinaleStage = 1 ;
}
}
2019-08-26 03:59:14 +00:00
}
2021-10-21 13:02:18 +00:00
DExhumedActor * BuildEnergyBlock ( short nSector )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
short startwall = sector [ nSector ] . wallptr ;
2020-01-09 19:13:09 +00:00
short nWalls = sector [ nSector ] . wallnum ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int x = 0 ;
int y = 0 ;
2019-08-26 03:59:14 +00:00
2020-01-09 19:13:09 +00:00
for ( int i = 0 ; i < nWalls ; i + + )
2019-08-31 07:47:15 +00:00
{
x + = wall [ startwall + i ] . x ;
y + = wall [ startwall + i ] . y ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
wall [ startwall + i ] . picnum = kClockSymbol16 ;
2019-08-31 07:47:15 +00:00
wall [ startwall + i ] . pal = 0 ;
wall [ startwall + i ] . shade = 50 ;
}
2019-08-26 03:59:14 +00:00
2020-01-09 19:13:09 +00:00
int xAvg = x / nWalls ;
int yAvg = y / nWalls ;
2019-08-26 03:59:14 +00:00
2021-10-21 13:02:18 +00:00
auto pActor = insertActor ( nSector , 406 ) ;
auto spr = & pActor - > s ( ) ;
2020-10-14 22:10:37 +00:00
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short nextsector = wall [ startwall ] . nextsector ;
2019-08-26 03:59:14 +00:00
2020-10-14 22:10:37 +00:00
spr - > x = xAvg ;
spr - > y = yAvg ;
2019-08-26 03:59:14 +00:00
2021-10-21 13:02:18 +00:00
sector [ nSector ] . extra = ( int16_t ) EnergyBlocks . Push ( pActor ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// GrabTimeSlot(3);
2019-08-26 03:59:14 +00:00
2020-10-14 22:10:37 +00:00
spr - > z = sector [ nextsector ] . floorz ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// CHECKME - name of this variable?
2020-10-14 22:10:37 +00:00
int nRepeat = ( spr - > z - sector [ nSector ] . floorz ) > > 8 ;
2019-08-31 07:47:15 +00:00
if ( nRepeat > 255 ) {
nRepeat = 255 ;
}
2019-08-26 03:59:14 +00:00
2020-10-14 22:10:37 +00:00
spr - > xrepeat = nRepeat ;
spr - > cstat = 0x8000 ;
spr - > xvel = 0 ;
spr - > yvel = 0 ;
spr - > zvel = 0 ;
spr - > extra = - 1 ;
spr - > lotag = runlist_HeadRun ( ) + 1 ;
spr - > hitag = 0 ;
2021-10-21 13:02:18 +00:00
spr - > owner = runlist_AddRunRec ( spr - > lotag - 1 , pActor , 0x250000 ) ;
2021-02-26 23:16:03 +00:00
spr - > backuppos ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-21 13:02:18 +00:00
return pActor ;
2019-08-26 03:59:14 +00:00
}
// TODO - tidy
void KillCreatures ( )
{
2019-08-31 07:47:15 +00:00
signed int v0 ;
signed int v1 ;
v0 = 99 ;
v1 = 99 ;
while ( 1 )
{
if ( v0 ! = 100 )
{
2021-10-20 20:27:16 +00:00
ExhumedStatIterator it ( v1 ) ;
while ( auto i = it . Next ( ) )
2019-08-31 07:47:15 +00:00
{
2021-10-21 13:02:18 +00:00
runlist_DamageEnemy ( i , nullptr , 1600 ) ;
2019-08-31 07:47:15 +00:00
}
}
+ + v0 ;
+ + v1 ;
if ( v0 > 107 ) {
return ;
}
}
2019-08-26 03:59:14 +00:00
}
2021-10-21 13:02:18 +00:00
void ExplodeEnergyBlock ( DExhumedActor * pActor )
2019-08-26 03:59:14 +00:00
{
2021-10-21 13:02:18 +00:00
auto pSprite = & pActor - > s ( ) ;
2021-09-06 06:33:02 +00:00
short nSector = pSprite - > sectnum ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short startwall = sector [ nSector ] . wallptr ;
short nWalls = sector [ nSector ] . wallnum ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int i ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( i = 0 ; i < nWalls ; i + + )
{
short nextwall = wall [ startwall + i ] . nextwall ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( wall [ nextwall ] . pal > = 4 ) {
wall [ nextwall ] . pal = 7 ;
}
else {
wall [ nextwall ] . pal = 0 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
wall [ nextwall ] . shade = 50 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( sector [ nSector ] . floorpal > = 4 ) {
sector [ nSector ] . floorpal = 7 ;
}
else {
sector [ nSector ] . floorpal = 0 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sector [ nSector ] . floorshade = 50 ;
sector [ nSector ] . extra = - 1 ;
2021-09-06 06:33:02 +00:00
sector [ nSector ] . floorz = pSprite - > z ;
2019-11-20 16:21:32 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > z = ( pSprite - > z + sector [ nSector ] . floorz ) / 2 ;
2019-08-26 03:59:14 +00:00
2021-10-21 11:15:47 +00:00
BuildSpark ( pActor , 3 ) ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > cstat = 0 ;
pSprite - > xrepeat = 100 ;
2019-08-26 03:59:14 +00:00
2021-10-21 13:02:18 +00:00
PlayFX2 ( StaticSound [ kSound78 ] , pActor ) ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > xrepeat = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nEnergyTowers - - ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( i = 0 ; i < 20 ; i + + )
{
2021-09-06 06:33:02 +00:00
pSprite - > ang = RandomSize ( 11 ) ;
2021-10-21 11:15:47 +00:00
BuildSpark ( pActor , 1 ) ; // shoot out blue orbs
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-10-12 21:09:55 +00:00
TintPalette ( 64 , 64 , 64 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nEnergyTowers = = 1 )
{
runlist_ChangeChannel ( nEnergyChan , nEnergyTowers ) ;
StatusMessage ( 1000 , " TAKE OUT THE CONTROL CENTER! " ) ;
}
else if ( nEnergyTowers ! = 0 )
{
StatusMessage ( 500 , " %d TOWERS REMAINING " , nEnergyTowers ) ;
}
else
{
2021-10-21 13:02:18 +00:00
pFinaleSpr = pActor ;
2021-02-18 10:46:36 +00:00
lFinaleStart = PlayClock ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ! lFinaleStart ) {
lFinaleStart = lFinaleStart + 1 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( i = 0 ; i < numsectors ; i + + )
{
if ( sector [ i ] . ceilingpal = = 1 ) {
sector [ i ] . ceilingpal = 0 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( sector [ i ] . floorpal = = 1 ) {
sector [ i ] . floorpal = 0 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short startwall = sector [ i ] . wallptr ;
short endwall = startwall + sector [ i ] . wallnum ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( int nWall = startwall ; nWall < endwall ; nWall + + )
{
if ( wall [ nWall ] . pal = = 1 ) {
wall [ nWall ] . pal = 0 ;
}
}
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
KillCreatures ( ) ;
}
2019-08-26 03:59:14 +00:00
2021-10-21 13:02:18 +00:00
ChangeActorStat ( pActor , 0 ) ;
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void AIEnergyBlock : : Damage ( RunListEvent * ev )
2019-08-26 03:59:14 +00:00
{
2021-10-21 13:02:18 +00:00
auto pActor = ev - > pObjActor ;
if ( ! pActor ) return ;
auto spr = & pActor - > s ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
ev - > nDamage > > = 2 ;
if ( ev - > nDamage < = 0 ) {
return ;
}
if ( ev - > nDamage < spr - > xrepeat )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
spr - > xrepeat - = ev - > nDamage ;
2019-08-26 03:59:14 +00:00
2021-10-21 11:15:47 +00:00
auto pActor2 = insertActor ( lasthitsect , 0 ) ;
auto pSprite2 = & pActor2 - > s ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-17 14:22:25 +00:00
pSprite2 - > ang = ev - > nParam ;
2021-10-15 20:13:05 +00:00
pSprite2 - > x = lasthitx ;
pSprite2 - > y = lasthity ;
pSprite2 - > z = lasthitz ;
2019-08-26 03:59:14 +00:00
2021-10-21 11:15:47 +00:00
BuildSpark ( pActor2 , 0 ) ; // shoot out blue orb when damaged
DeleteActor ( pActor2 ) ;
2021-10-15 20:13:05 +00:00
}
else
{
spr - > xrepeat = 0 ; // using xrepeat to store health
2021-10-21 13:02:18 +00:00
ExplodeEnergyBlock ( pActor ) ;
2021-10-15 20:13:05 +00:00
}
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
void AIEnergyBlock : : RadialDamage ( RunListEvent * ev )
{
2021-10-21 13:02:18 +00:00
auto pActor = ev - > pObjActor ;
if ( ! pActor ) return ;
auto spr = & pActor - > s ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
short nSector = spr - > sectnum ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( sector [ nSector ] . extra = = - 1 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
int nFloorZ = sector [ nSector ] . floorz ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
sector [ nSector ] . floorz = spr - > z ;
spr - > z - = 256 ;
2019-08-26 03:59:14 +00:00
2021-10-21 13:02:18 +00:00
ev - > nDamage = runlist_CheckRadialDamage ( pActor ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// restore previous values
sector [ nSector ] . floorz = nFloorZ ;
spr - > z + = 256 ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
if ( ev - > nDamage < = 0 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// fall through to case 0x80000
Damage ( ev ) ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
void FuncEnergyBlock ( int nObject , int nMessage , int nDamage , int nRun )
{
AIEnergyBlock ai ;
runlist_DispatchEvent ( & ai , nObject , nMessage , nDamage , nRun ) ;
2019-08-26 03:59:14 +00:00
}
2021-10-21 15:24:52 +00:00
DExhumedActor * BuildObject ( DExhumedActor * pActor , int nOjectType , int nHitag )
2019-08-26 03:59:14 +00:00
{
2021-10-21 13:33:41 +00:00
auto spr = & pActor - > s ( ) ;
2019-08-26 03:59:14 +00:00
2021-10-21 13:33:41 +00:00
ChangeActorStat ( pActor , ObjectStatnum [ nOjectType ] ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// 0x7FFD to ensure set as blocking ('B' and 'H') sprite and also disable translucency and set not invisible
2020-10-14 22:10:37 +00:00
spr - > cstat = ( spr - > cstat | 0x101 ) & 0x7FFD ;
spr - > xvel = 0 ;
spr - > yvel = 0 ;
spr - > zvel = 0 ;
spr - > extra = - 1 ;
spr - > lotag = runlist_HeadRun ( ) + 1 ;
spr - > hitag = 0 ;
2021-10-21 15:24:52 +00:00
spr - > owner = runlist_AddRunRec ( spr - > lotag - 1 , pActor , 0x170000 ) ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// GrabTimeSlot(3);
2021-10-21 15:24:52 +00:00
pActor - > nPhase = ObjectList . Push ( pActor ) ;
2020-10-14 22:10:37 +00:00
if ( spr - > statnum = = kStatDestructibleSprite ) {
2021-10-21 15:24:52 +00:00
pActor - > nHealth = 4 ;
2019-08-31 07:47:15 +00:00
}
else {
2021-10-21 15:24:52 +00:00
pActor - > nHealth = 120 ;
2019-08-31 07:47:15 +00:00
}
2021-10-21 15:24:52 +00:00
pActor - > nRun = runlist_AddRunRec ( NewRun , pActor , 0x170000 ) ;
2019-08-31 07:47:15 +00:00
short nSeq = ObjectSeq [ nOjectType ] ;
2019-12-02 21:19:27 +00:00
if ( nSeq > - 1 )
2019-08-31 07:47:15 +00:00
{
2021-10-21 15:24:52 +00:00
pActor - > nIndex = SeqOffsets [ nSeq ] ;
2019-08-31 07:47:15 +00:00
if ( ! nOjectType ) // if not Explosion Trigger (e.g. Exploding Fire Cauldron)
{
2021-10-21 15:24:52 +00:00
pActor - > nFrame = RandomSize ( 4 ) % ( SeqSize [ pActor - > nIndex ] - 1 ) ;
2019-08-31 07:47:15 +00:00
}
2021-10-21 15:24:52 +00:00
auto pActor2 = insertActor ( spr - > sectnum , 0 ) ;
auto pSprite2 = & pActor2 - > s ( ) ;
pActor - > pTarget = pActor2 ;
pActor - > nIndex2 = - 1 ;
2019-08-31 07:47:15 +00:00
2021-09-06 06:33:02 +00:00
pSprite2 - > cstat = 0x8000 ;
pSprite2 - > x = spr - > x ;
pSprite2 - > y = spr - > y ;
pSprite2 - > z = spr - > z ;
2019-08-31 07:47:15 +00:00
}
2019-12-02 21:19:27 +00:00
else
{
2021-10-21 15:24:52 +00:00
pActor - > nFrame = 0 ;
pActor - > nIndex = - 1 ;
2019-12-02 21:19:27 +00:00
2020-10-14 22:10:37 +00:00
if ( spr - > statnum = = kStatDestructibleSprite ) {
2021-10-21 15:24:52 +00:00
pActor - > nIndex2 = - 1 ;
2019-12-02 21:19:27 +00:00
}
else {
2021-10-21 15:24:52 +00:00
pActor - > nIndex2 = - nHitag ;
2019-12-02 21:19:27 +00:00
}
}
2021-02-26 23:16:03 +00:00
spr - > backuppos ( ) ;
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
return pActor ;
2019-08-26 03:59:14 +00:00
}
2020-02-04 21:45:10 +00:00
// in-game destructable wall mounted screen
2021-10-21 15:24:52 +00:00
void ExplodeScreen ( DExhumedActor * pActor )
2019-08-26 03:59:14 +00:00
{
2021-10-21 15:24:52 +00:00
auto pSprite = & pActor - > s ( ) ;
pSprite - > z - = GetActorHeight ( pActor ) / 2 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < 30 ; i + + ) {
2021-10-21 15:24:52 +00:00
BuildSpark ( pActor , 0 ) ; // shoot out blue orbs
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
pSprite - > cstat = 0x8000 ;
2021-10-21 15:24:52 +00:00
PlayFX2 ( StaticSound [ kSound78 ] , pActor ) ;
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void AIObject : : Tick ( RunListEvent * ev )
2019-08-26 03:59:14 +00:00
{
2021-10-21 15:24:52 +00:00
auto pActor = ev - > pObjActor ;
if ( ! pActor ) return ;
auto pSprite = & pActor - > s ( ) ;
2021-09-06 06:33:02 +00:00
short nStat = pSprite - > statnum ;
2021-10-21 15:24:52 +00:00
short bx = pActor - > nIndex ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( nStat = = 97 | | ( ! ( pSprite - > cstat & 0x101 ) ) ) {
return ;
}
if ( nStat ! = kStatExplodeTarget ) {
2021-10-20 22:00:26 +00:00
Gravity ( pActor ) ;
2021-10-15 20:13:05 +00:00
}
// do animation
if ( bx ! = - 1 )
2019-08-31 07:47:15 +00:00
{
2021-10-21 15:24:52 +00:00
pActor - > nFrame + + ;
if ( pActor - > nFrame > = SeqSize [ bx ] ) {
pActor - > nFrame = 0 ;
2019-08-31 07:47:15 +00:00
}
2021-10-21 15:24:52 +00:00
pSprite - > picnum = seq_GetSeqPicnum2 ( bx , pActor - > nFrame ) ;
2021-10-15 20:13:05 +00:00
}
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
if ( pActor - > nHealth > = 0 ) {
2021-10-15 20:13:05 +00:00
goto FUNCOBJECT_GOTO ;
}
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
pActor - > nHealth + + ;
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
if ( pActor - > nHealth )
2021-10-15 20:13:05 +00:00
{
FUNCOBJECT_GOTO :
if ( nStat ! = kStatExplodeTarget )
{
2021-10-21 15:24:52 +00:00
auto nMov = movesprite ( pActor , pSprite - > xvel < < 6 , pSprite - > yvel < < 6 , pSprite - > zvel , 0 , 0 , CLIPMASK0 ) ;
2021-10-15 20:13:05 +00:00
if ( pSprite - > statnum = = kStatExplodeTrigger ) {
pSprite - > pal = 1 ;
2019-08-31 07:47:15 +00:00
}
2021-10-21 15:24:52 +00:00
if ( nMov . exbits & kHitAux2 )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
pSprite - > xvel - = pSprite - > xvel > > 3 ;
pSprite - > yvel - = pSprite - > yvel > > 3 ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
2021-10-21 15:24:52 +00:00
if ( nMov . type = = kHitSprite )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
pSprite - > yvel = 0 ;
pSprite - > xvel = 0 ;
2019-08-31 07:47:15 +00:00
}
}
2021-10-15 20:13:05 +00:00
return ;
}
else
{
int var_18 ;
// red branch
if ( ( nStat = = kStatExplodeTarget ) | | ( pSprite - > z < sector [ pSprite - > sectnum ] . floorz ) )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
var_18 = 36 ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
else
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
var_18 = 34 ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
AddFlash ( pSprite - > sectnum , pSprite - > x , pSprite - > y , pSprite - > z , 128 ) ;
2021-10-24 17:11:04 +00:00
BuildAnim ( nullptr , var_18 , 0 , pSprite - > x , pSprite - > y , sector [ pSprite - > sectnum ] . floorz , pSprite - > sectnum , 240 , 4 ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
// int edi = nSprite | 0x4000;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( nStat = = kStatExplodeTrigger )
{
for ( int i = 4 ; i < 8 ; i + + ) {
2021-10-21 15:24:52 +00:00
BuildCreatureChunk ( pActor , seq_GetSeqPicnum ( kSeqFirePot , ( i > > 2 ) + 1 , 0 ) , true ) ;
2019-08-31 07:47:15 +00:00
}
2021-10-21 15:24:52 +00:00
runlist_RadialDamageEnemy ( pActor , 200 , 20 ) ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
else if ( nStat = = kStatExplodeTarget )
2019-08-31 07:47:15 +00:00
{
2021-10-15 20:13:05 +00:00
for ( int i = 0 ; i < 8 ; i + + ) {
2021-10-21 15:24:52 +00:00
BuildCreatureChunk ( pActor , seq_GetSeqPicnum ( kSeqFirePot , ( i > > 1 ) + 3 , 0 ) , true ) ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( ! ( currentLevel - > gameflags & LEVEL_EX_MULTI ) | | nStat ! = kStatExplodeTrigger )
{
runlist_SubRunRec ( pSprite - > owner ) ;
2021-10-21 15:24:52 +00:00
runlist_SubRunRec ( pActor - > nRun ) ;
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
DeleteActor ( pActor ) ;
2021-10-15 20:13:05 +00:00
return ;
}
else
{
2021-10-21 08:20:08 +00:00
StartRegenerate ( pActor ) ;
2021-10-21 15:24:52 +00:00
pActor - > nHealth = 120 ;
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
auto pTargSpr = & pActor - > pTarget - > s ( ) ;
pSprite - > x = pTargSpr - > x ;
pSprite - > y = pTargSpr - > y ;
pSprite - > z = pTargSpr - > z ;
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
ChangeActorSect ( pActor , pTargSpr - > sectnum ) ;
2021-10-15 20:13:05 +00:00
return ;
}
}
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
void AIObject : : Damage ( RunListEvent * ev )
{
2021-10-21 15:24:52 +00:00
auto pActor = ev - > pObjActor ;
if ( ! pActor ) return ;
auto pSprite = & pActor - > s ( ) ;
2021-10-15 20:13:05 +00:00
short nStat = pSprite - > statnum ;
2021-10-21 15:24:52 +00:00
short bx = pActor - > nIndex ;
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
if ( nStat > = 150 | | pActor - > nHealth < = 0 ) {
2021-10-15 20:13:05 +00:00
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( nStat = = 98 )
{
2021-10-21 15:24:52 +00:00
D3PlayFX ( ( StaticSound [ kSound47 ] | 0x2000 ) | ( RandomSize ( 2 ) < < 9 ) , pActor ) ;
2021-10-15 20:13:05 +00:00
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
pActor - > nHealth - = ( short ) ev - > nDamage ;
if ( pActor - > nHealth > 0 ) {
2021-10-15 20:13:05 +00:00
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( nStat = = kStatDestructibleSprite )
{
2021-10-21 15:24:52 +00:00
ExplodeScreen ( pActor ) ;
2021-10-15 20:13:05 +00:00
}
else
{
2021-10-21 15:24:52 +00:00
pActor - > nHealth = - ( RandomSize ( 3 ) + 1 ) ;
2021-10-15 20:13:05 +00:00
}
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
void AIObject : : Draw ( RunListEvent * ev )
{
2021-10-21 15:24:52 +00:00
auto pActor = ev - > pObjActor ;
if ( ! pActor ) return ;
short bx = pActor - > nIndex ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( bx > - 1 )
{
2021-10-21 15:24:52 +00:00
seq_PlotSequence ( ev - > nParam , bx , pActor - > nFrame , 1 ) ;
2021-10-15 20:13:05 +00:00
}
return ;
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
void AIObject : : RadialDamage ( RunListEvent * ev )
{
2021-10-21 15:24:52 +00:00
auto pActor = ev - > pObjActor ;
if ( ! pActor ) return ;
2019-08-26 03:59:14 +00:00
2021-10-21 15:24:52 +00:00
auto pSprite = & pActor - > s ( ) ;
2021-10-15 20:13:05 +00:00
short nStat = pSprite - > statnum ;
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
if ( pActor - > nHealth > 0 & & pSprite - > cstat & 0x101
2021-10-15 20:13:05 +00:00
& & ( nStat ! = kStatExplodeTarget
2021-10-21 16:22:14 +00:00
| | ev - > pRadialActor - > s ( ) . statnum = = 201
2021-10-15 20:13:05 +00:00
| | ( nRadialBullet ! = 3 & & nRadialBullet > - 1 )
2021-10-21 16:22:14 +00:00
| | ev - > pRadialActor - > s ( ) . statnum = = kStatExplodeTrigger ) )
2021-10-15 20:13:05 +00:00
{
2021-10-21 15:24:52 +00:00
int nDamage = runlist_CheckRadialDamage ( pActor ) ;
2021-10-15 20:13:05 +00:00
if ( nDamage < = 0 ) {
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( pSprite - > statnum ! = kStatAnubisDrum ) {
2021-10-21 15:24:52 +00:00
pActor - > nHealth - = nDamage ;
2021-10-15 20:13:05 +00:00
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( pSprite - > statnum = = kStatExplodeTarget )
{
pSprite - > xvel = 0 ;
pSprite - > yvel = 0 ;
pSprite - > zvel = 0 ;
}
else if ( pSprite - > statnum ! = kStatAnubisDrum )
{
pSprite - > xvel > > = 1 ;
pSprite - > yvel > > = 1 ;
pSprite - > zvel > > = 1 ;
}
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
if ( pActor - > nHealth > 0 ) {
2021-10-15 20:13:05 +00:00
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( pSprite - > statnum = = kStatExplodeTarget )
{
2021-10-21 15:24:52 +00:00
pActor - > nHealth = - 1 ;
short ax = pActor - > nIndex2 ;
2021-10-15 20:13:05 +00:00
2021-10-21 15:24:52 +00:00
if ( ax < 0 | | ObjectList [ ax ] - > nHealth < = 0 ) {
2021-10-15 20:13:05 +00:00
return ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
2021-10-21 15:24:52 +00:00
ObjectList [ ax ] - > nHealth = - 1 ;
2021-10-15 20:13:05 +00:00
}
else if ( pSprite - > statnum = = kStatDestructibleSprite )
{
2021-10-21 15:24:52 +00:00
pActor - > nHealth = 0 ;
2021-10-15 20:13:05 +00:00
2021-10-21 15:24:52 +00:00
ExplodeScreen ( pActor ) ;
2021-10-15 20:13:05 +00:00
}
else
{
2021-10-21 15:24:52 +00:00
pActor - > nHealth = - ( RandomSize ( 4 ) + 1 ) ;
2019-08-31 07:47:15 +00:00
}
}
2019-08-26 03:59:14 +00:00
}
2021-10-15 20:13:05 +00:00
void FuncObject ( int nObject , int nMessage , int nDamage , int nRun )
{
AIObject ai ;
runlist_DispatchEvent ( & ai , nObject , nMessage , nDamage , nRun ) ;
}
2019-08-26 03:59:14 +00:00
void BuildDrip ( int nSprite )
{
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2020-11-29 23:49:25 +00:00
auto nDrips = sDrip . Reserve ( 1 ) ;
2019-08-31 07:47:15 +00:00
sDrip [ nDrips ] . nSprite = nSprite ;
sDrip [ nDrips ] . field_2 = RandomSize ( 8 ) + 90 ;
2021-09-06 06:33:02 +00:00
pSprite - > cstat = 0x8000u ;
2019-08-26 03:59:14 +00:00
}
void DoDrips ( )
{
2020-11-29 23:49:25 +00:00
for ( unsigned i = 0 ; i < sDrip . Size ( ) ; i + + )
2019-08-31 07:47:15 +00:00
{
sDrip [ i ] . field_2 - - ;
if ( sDrip [ i ] . field_2 < = 0 )
{
short nSprite = sDrip [ i ] . nSprite ;
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2019-08-31 07:47:15 +00:00
short nSeqOffset = SeqOffsets [ kSeqDrips ] ;
2021-09-06 06:33:02 +00:00
if ( ! ( SectFlag [ pSprite - > sectnum ] & kSectLava ) ) {
2019-08-31 07:47:15 +00:00
nSeqOffset + + ;
}
seq_MoveSequence ( nSprite , nSeqOffset , RandomSize ( 2 ) % SeqSize [ nSeqOffset ] ) ;
sDrip [ i ] . field_2 = RandomSize ( 8 ) + 90 ;
}
}
2020-11-29 23:49:25 +00:00
for ( unsigned i = 0 ; i < sBob . Size ( ) ; i + + )
2019-08-31 07:47:15 +00:00
{
sBob [ i ] . field_2 + = 4 ;
2020-11-14 08:45:08 +00:00
int edx = bsin ( sBob [ i ] . field_2 < < 3 , - 4 ) ;
2019-08-31 07:47:15 +00:00
short nSector = sBob [ i ] . nSector ;
if ( sBob [ i ] . field_3 )
{
sector [ nSector ] . ceilingz = edx + sBob [ i ] . z ;
}
else
{
int nFloorZ = sector [ nSector ] . floorz ;
sector [ nSector ] . floorz = edx + sBob [ i ] . z ;
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
MoveSectorSprites ( nSector , sector [ nSector ] . floorz - nFloorZ ) ;
}
}
2019-08-26 03:59:14 +00:00
}
void SnapBobs ( short nSectorA , short nSectorB )
{
2019-08-31 07:47:15 +00:00
int ecx = - 1 ;
int ebx = ecx ;
2021-10-15 20:13:05 +00:00
// int var_14 = nSector;
// int edi = edx;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
for ( unsigned i = 0 ; i < sBob . Size ( ) ; i + + )
2019-08-31 07:47:15 +00:00
{
int esi = sBob [ i ] . nSector ;
if ( esi ! = nSectorA )
{
if ( nSectorB ! = esi )
continue ;
esi = ebx ;
ecx = i ;
}
else
{
esi = ecx ;
ebx = i ;
}
if ( esi ! = - 1 ) {
break ;
}
}
if ( ecx < = - 1 ) {
return ;
}
if ( ebx < = - 1 ) {
return ;
}
sBob [ ecx ] . field_2 = sBob [ ebx ] . field_2 ;
2019-08-26 03:59:14 +00:00
}
void AddSectorBob ( int nSector , int nHitag , int bx )
{
2020-11-29 23:49:25 +00:00
auto nBobs = sBob . Reserve ( 1 ) ;
2019-08-31 07:47:15 +00:00
sBob [ nBobs ] . field_3 = bx ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int z ;
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
if ( bx = = 0 ) {
z = sector [ nSector ] . floorz ;
}
else {
z = sector [ nSector ] . ceilingz ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sBob [ nBobs ] . z = z ;
sBob [ nBobs ] . field_2 = nHitag < < 4 ;
2020-11-29 23:49:25 +00:00
sBob [ nBobs ] . sBobID = nHitag ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sBob [ nBobs ] . nSector = nSector ;
2021-10-15 20:13:05 +00:00
StartInterpolation ( nSector , bx = = 0 ? Interp_Sect_Floorz : Interp_Sect_Ceilingz ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SectFlag [ nSector ] | = 0x0010 ;
2019-08-26 03:59:14 +00:00
}
int FindTrail ( int nVal )
{
2020-11-29 23:49:25 +00:00
for ( unsigned i = 0 ; i < sTrail . Size ( ) ; i + + )
2019-08-31 07:47:15 +00:00
{
if ( sTrail [ i ] . field_2 = = nVal )
return i ;
}
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
auto nTrails = sTrail . Reserve ( 1 ) ;
2019-08-31 07:47:15 +00:00
sTrail [ nTrails ] . field_2 = nVal ;
sTrail [ nTrails ] . field_0 = - 1 ;
2020-11-29 23:49:25 +00:00
sTrail [ nTrails ] . field_4 = - 1 ;
return nTrails ;
2019-08-26 03:59:14 +00:00
}
// ok ?
void ProcessTrailSprite ( int nSprite , int nLotag , int nHitag )
{
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2020-11-29 23:49:25 +00:00
auto nPoint = sTrailPoint . Reserve ( 1 ) ;
2019-08-26 03:59:14 +00:00
2021-09-06 06:33:02 +00:00
sTrailPoint [ nPoint ] . x = pSprite - > x ;
sTrailPoint [ nPoint ] . y = pSprite - > y ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nTrail = FindTrail ( nHitag ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int var_14 = nLotag - 900 ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
sTrailPoint [ nPoint ] . nTrailPointVal = var_14 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int field0 = sTrail [ nTrail ] . field_0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( field0 = = - 1 )
{
sTrail [ nTrail ] . field_0 = nPoint ;
sTrail [ nTrail ] . field_4 = nPoint ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
sTrailPoint [ nPoint ] . nTrailPointNext = - 1 ;
sTrailPoint [ nPoint ] . nTrailPointPrev = - 1 ;
2019-08-31 07:47:15 +00:00
}
else
{
int ecx = - 1 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
while ( field0 ! = - 1 )
{
2020-11-29 23:49:25 +00:00
if ( sTrailPoint [ field0 ] . nTrailPointVal > var_14 )
2019-08-31 07:47:15 +00:00
{
2020-11-29 23:49:25 +00:00
sTrailPoint [ nPoint ] . nTrailPointPrev = sTrailPoint [ field0 ] . nTrailPointPrev ;
sTrailPoint [ field0 ] . nTrailPointPrev = nPoint ;
sTrailPoint [ nPoint ] . nTrailPointNext = field0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( field0 = = sTrail [ nTrail ] . field_0 ) {
sTrail [ nTrail ] . field_0 = nPoint ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
break ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
ecx = field0 ;
2020-11-29 23:49:25 +00:00
field0 = sTrailPoint [ field0 ] . nTrailPointNext ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( field0 = = - 1 )
{
2020-11-29 23:49:25 +00:00
sTrailPoint [ ecx ] . nTrailPointNext = nPoint ;
sTrailPoint [ nPoint ] . nTrailPointPrev = ecx ;
sTrailPoint [ nPoint ] . nTrailPointNext = - 1 ;
2019-08-31 07:47:15 +00:00
sTrail [ nTrail ] . field_4 = nPoint ;
}
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
mydeletesprite ( nSprite ) ;
2019-08-26 03:59:14 +00:00
}
// ok?
void AddMovingSector ( int nSector , int edx , int ebx , int ecx )
{
2019-08-31 07:47:15 +00:00
CreatePushBlock ( nSector ) ;
2021-01-04 19:34:27 +00:00
setsectinterpolate ( nSector ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short nTrail = FindTrail ( ebx ) ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
auto nMoveSects = sMoveSect . Reserve ( 1 ) ;
2021-10-15 20:13:05 +00:00
MoveSect * pMoveSect = & sMoveSect [ nMoveSects ] ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
pMoveSect - > sMoveDir = 1 ;
2019-08-31 07:47:15 +00:00
pMoveSect - > nTrail = nTrail ;
pMoveSect - > nTrailPoint = - 1 ;
pMoveSect - > field_8 = - 1 ;
pMoveSect - > field_6 = ecx ;
pMoveSect - > field_10 = ( edx / 1000 ) + 1 ;
pMoveSect - > nSector = nSector ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ecx & 8 )
{
pMoveSect - > field_14 = runlist_AllocChannel ( ebx % 1000 ) ;
}
else
{
pMoveSect - > field_14 = - 1 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sector [ nSector ] . floorstat | = 0x40 ;
2019-08-26 03:59:14 +00:00
}
void DoMovingSects ( )
{
2020-11-29 23:49:25 +00:00
for ( unsigned i = 0 ; i < sMoveSect . Size ( ) ; i + + )
2019-08-31 07:47:15 +00:00
{
if ( sMoveSect [ i ] . nSector = = - 1 ) {
continue ;
}
if ( sMoveSect [ i ] . field_14 ! = - 1 & & ! sRunChannels [ sMoveSect [ i ] . field_14 ] . c ) {
continue ;
}
short nSector = sMoveSect [ i ] . nSector ;
short nBlock = sector [ nSector ] . extra ;
2021-10-15 20:13:05 +00:00
BlockInfo * pBlockInfo = & sBlockInfo [ nBlock ] ;
2019-08-31 07:47:15 +00:00
if ( sMoveSect [ i ] . nTrailPoint = = - 1 )
{
if ( sMoveSect [ i ] . field_6 & 0x20 )
{
runlist_ChangeChannel ( sMoveSect [ i ] . field_14 , 0 ) ;
}
short ax ;
if ( sMoveSect [ i ] . field_6 & 0x10 )
{
2020-11-29 23:49:25 +00:00
sMoveSect [ i ] . sMoveDir = - sMoveSect [ i ] . sMoveDir ;
if ( sMoveSect [ i ] . sMoveDir > 0 )
2019-08-31 07:47:15 +00:00
{
ax = sTrail [ sMoveSect [ i ] . nTrail ] . field_0 ;
}
else
{
ax = sTrail [ sMoveSect [ i ] . nTrail ] . field_4 ;
}
}
else
{
ax = sTrail [ sMoveSect [ i ] . nTrail ] . field_0 ;
}
sMoveSect [ i ] . nTrailPoint = ax ;
}
short nTrail = sMoveSect [ i ] . nTrailPoint ;
2021-10-15 20:13:05 +00:00
// TrailPoint *pTrail = &sTrailPoint[nTrail];
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
// loc_23872:
2019-08-31 07:47:15 +00:00
int nAngle = GetMyAngle ( sTrailPoint [ nTrail ] . x - pBlockInfo - > x , sTrailPoint [ nTrail ] . y - pBlockInfo - > y ) ;
2020-11-14 08:45:08 +00:00
int nXVel = bcos ( nAngle , 4 ) * sMoveSect [ i ] . field_10 ;
int nYVel = bsin ( nAngle , 4 ) * sMoveSect [ i ] . field_10 ;
2019-08-31 07:47:15 +00:00
int ebx = ( sTrailPoint [ nTrail ] . x - pBlockInfo - > x ) < < 14 ;
int eax = nXVel ;
if ( eax < 0 ) {
eax = - eax ;
}
int edx = eax ;
eax = ebx ;
int ecx = ( sTrailPoint [ nTrail ] . y - pBlockInfo - > y ) < < 14 ;
if ( eax < 0 ) {
eax = - eax ;
}
// loc_238EC:
if ( edx < = eax )
{
eax = nYVel ;
if ( eax < 0 ) {
eax = - eax ;
}
edx = eax ;
eax = ecx ;
if ( eax < 0 ) {
eax = - eax ;
}
if ( edx > eax )
{
// loc_23908:
nYVel = ecx ;
nXVel = ebx ;
2020-11-29 23:49:25 +00:00
if ( sMoveSect [ i ] . sMoveDir > 0 )
2019-08-31 07:47:15 +00:00
{
2020-11-29 23:49:25 +00:00
sMoveSect [ i ] . nTrailPoint = sTrailPoint [ sMoveSect [ i ] . nTrailPoint ] . nTrailPointNext ;
2019-08-31 07:47:15 +00:00
}
else
{
2020-11-29 23:49:25 +00:00
sMoveSect [ i ] . nTrailPoint = sTrailPoint [ sMoveSect [ i ] . nTrailPoint ] . nTrailPointPrev ;
2019-08-31 07:47:15 +00:00
}
}
}
2019-11-20 16:21:32 +00:00
else
2019-08-31 07:47:15 +00:00
{
// repeat of code from loc_23908
nYVel = ecx ;
nXVel = ebx ;
2020-11-29 23:49:25 +00:00
if ( sMoveSect [ i ] . sMoveDir > 0 )
2019-08-31 07:47:15 +00:00
{
2020-11-29 23:49:25 +00:00
sMoveSect [ i ] . nTrailPoint = sTrailPoint [ sMoveSect [ i ] . nTrailPoint ] . nTrailPointNext ;
2019-08-31 07:47:15 +00:00
}
else
{
2020-11-29 23:49:25 +00:00
sMoveSect [ i ] . nTrailPoint = sTrailPoint [ sMoveSect [ i ] . nTrailPoint ] . nTrailPointPrev ;
2019-08-31 07:47:15 +00:00
}
}
// loc_2393A:
if ( sMoveSect [ i ] . field_8 ! = - 1 )
{
MoveSector ( sMoveSect [ i ] . field_8 , - 1 , & nXVel , & nYVel ) ;
}
int var_2C = nXVel ;
int var_30 = nYVel ;
MoveSector ( nSector , - 1 , & nXVel , & nYVel ) ;
if ( nXVel ! = var_2C | | nYVel ! = var_30 )
{
MoveSector ( sMoveSect [ i ] . field_8 , - 1 , & var_2C , & var_30 ) ;
MoveSector ( sMoveSect [ i ] . field_8 , - 1 , & nXVel , & nYVel ) ;
}
}
2019-08-26 03:59:14 +00:00
}
void PostProcess ( )
{
2021-10-15 20:13:05 +00:00
int i , j ;
2019-08-31 07:47:15 +00:00
2020-11-29 23:49:25 +00:00
for ( unsigned i = 0 ; i < sMoveSect . Size ( ) ; i + + )
2019-08-31 07:47:15 +00:00
{
int nTrail = sMoveSect [ i ] . nTrail ;
sMoveSect [ i ] . nTrailPoint = sTrail [ nTrail ] . field_0 ;
if ( sMoveSect [ i ] . field_6 & 0x40 ) {
runlist_ChangeChannel ( sMoveSect [ i ] . field_14 , 1 ) ;
}
short nSector = sMoveSect [ i ] . nSector ;
if ( SectFlag [ nSector ] & kSectUnderwater )
{
sector [ nSector ] . ceilingstat | = 0x40 ;
sector [ nSector ] . floorstat & = 0xBFFF ;
2020-11-29 23:49:25 +00:00
for ( unsigned j = 0 ; j < sMoveSect . Size ( ) ; j + + )
2019-08-31 07:47:15 +00:00
{
if ( j ! = i & & sMoveSect [ i ] . nTrail = = sMoveSect [ j ] . nTrail )
{
sMoveSect [ j ] . field_8 = sMoveSect [ i ] . nSector ;
SnapSectors ( sMoveSect [ j ] . nSector , sMoveSect [ i ] . nSector , 0 ) ;
sMoveSect [ i ] . nSector = - 1 ;
}
}
}
}
2020-11-29 23:49:25 +00:00
for ( unsigned i = 0 ; i < sBob . Size ( ) ; i + + )
2019-08-31 07:47:15 +00:00
{
if ( sBob [ i ] . field_3 = = 0 )
{
2020-11-29 23:49:25 +00:00
int bobID = sBob [ i ] . sBobID ;
2019-08-31 07:47:15 +00:00
2020-11-29 23:49:25 +00:00
for ( unsigned j = 0 ; j < sBob . Size ( ) ; j + + )
2019-08-31 07:47:15 +00:00
{
if ( j ! = i )
{
2020-11-29 23:49:25 +00:00
if ( sBob [ i ] . field_3 ! = 0 & & sBob [ j ] . sBobID = = bobID ) {
2019-08-31 07:47:15 +00:00
SnapSectors ( i , j , 0 ) ;
}
}
}
}
}
2021-05-02 13:54:19 +00:00
if ( ! ( currentLevel - > gameflags & LEVEL_EX_COUNTDOWN ) )
2019-08-31 07:47:15 +00:00
{
// esi is i
for ( i = 0 ; i < numsectors ; i + + )
{
int var_20 = 30000 ;
if ( SectSpeed [ i ] & & SectDepth [ i ] & & ! ( SectFlag [ i ] & kSectLava ) )
{
SectSoundSect [ i ] = i ;
2019-11-15 08:04:28 +00:00
SectSound [ i ] = StaticSound [ kSound43 ] ;
2019-08-31 07:47:15 +00:00
}
else
{
// ebp and ecx are j
for ( j = 0 ; j < numsectors ; j + + )
{
// loc_23CA6:
if ( i ! = j & & SectSpeed [ j ] & & ! ( SectFlag [ i ] & kSectLava ) )
{
int xVal = wall [ sector [ i ] . wallptr ] . x - wall [ sector [ j ] . wallptr ] . x ;
if ( xVal < 0 ) {
xVal = - xVal ;
}
int yVal = wall [ sector [ i ] . wallptr ] . x - wall [ sector [ j ] . wallptr ] . x ;
if ( yVal < 0 ) {
yVal = - yVal ;
}
if ( xVal < 15000 & & yVal < 15000 & & ( xVal + yVal < var_20 ) )
{
var_20 = xVal + yVal ;
SectSoundSect [ i ] = j ;
2019-11-15 08:04:28 +00:00
SectSound [ i ] = StaticSound [ kSound43 ] ;
2019-08-31 07:47:15 +00:00
}
}
}
}
}
}
else // nMap == kMap20)
{
// int var_24 = 0;
int ebp = 0 ;
for ( i = 0 ; i < numsectors ; i + + )
{
SectSoundSect [ i ] = i ;
SectSound [ i ] = StaticSound [ kSound62 ] ;
int startwall = sector [ ebp ] . wallptr ;
int endwall = sector [ ebp ] . wallptr + sector [ ebp ] . wallnum ;
int nWall = startwall ;
while ( nWall < endwall )
{
if ( wall [ nWall ] . picnum = = kTile3603 )
{
wall [ nWall ] . pal = 1 ;
int nSprite = insertsprite ( i , 407 ) ;
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2021-09-06 06:33:02 +00:00
pSprite - > cstat = 0x8000 ;
2019-08-31 07:47:15 +00:00
}
nWall + + ;
}
}
for ( i = 0 ; i < kMaxSprites ; i + + )
{
if ( sprite [ i ] . statnum < kMaxStatus & & sprite [ i ] . picnum = = kTile3603 )
{
changespritestat ( i , 407 ) ;
sprite [ i ] . pal = 1 ;
}
}
}
2020-11-29 23:49:25 +00:00
for ( unsigned i = 0 ; i < ObjectList . Size ( ) ; i + + )
2019-08-31 07:47:15 +00:00
{
2021-10-21 15:24:52 +00:00
auto pObjectActor = ObjectList [ i ] ;
2019-08-31 07:47:15 +00:00
2021-10-21 15:24:52 +00:00
if ( pObjectActor - > s ( ) . statnum = = kStatExplodeTarget )
2019-08-31 07:47:15 +00:00
{
2021-10-21 15:24:52 +00:00
if ( ! pObjectActor - > nIndex2 ) {
pObjectActor - > nIndex2 = - 1 ;
2019-08-31 07:47:15 +00:00
}
else
{
2021-10-21 15:24:52 +00:00
int edi = pObjectActor - > nIndex2 ;
pObjectActor - > nIndex2 = - 1 ;
2019-08-31 07:47:15 +00:00
2020-11-29 23:49:25 +00:00
for ( unsigned j = 0 ; j < ObjectList . Size ( ) ; j + + )
2019-08-31 07:47:15 +00:00
{
2021-10-21 15:24:52 +00:00
if ( i ! = j & & ObjectList [ j ] - > s ( ) . statnum = = kStatExplodeTarget & & edi = = ObjectList [ j ] - > nIndex2 )
2019-08-31 07:47:15 +00:00
{
2021-10-21 15:24:52 +00:00
pObjectActor - > nIndex2 = j ;
ObjectList [ j ] - > nIndex2 = i ;
2019-08-31 07:47:15 +00:00
}
}
}
}
}
2019-08-26 03:59:14 +00:00
}
2019-12-26 21:00:04 +00:00
2019-11-22 23:11:37 +00:00
END_PS_NS
2020-09-07 21:03:18 +00:00