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 Object
{
2019-08-31 07:47:15 +00:00
short field_0 ;
short nHealth ;
short field_4 ;
short nSprite ;
short field_8 ;
short field_10 ;
short field_12 ;
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
{
2019-08-31 07:47:15 +00:00
short nChannel ;
2020-11-29 23:49:25 +00:00
short field_2a ;
short field_4a ;
2021-09-07 19:28:47 +00:00
short nSprite ;
2020-11-29 23:49:25 +00:00
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 ;
2019-08-31 07:47:15 +00:00
int field_20 ;
int field_24 ;
int field_28 ;
int field_2C ;
int field_30 ;
int field_34 ;
int field_38 ;
int field_3C ;
2019-08-26 03:59:14 +00:00
} ;
struct Point
{
2019-08-31 07:47:15 +00:00
short field_0 ;
short field_2 ;
short field_4 ;
short field_6 ;
short field_8 ;
short field_A ;
short field_C ;
short field_E ;
2019-08-26 03:59:14 +00:00
} ;
struct Trap
{
2019-08-31 07:47:15 +00:00
short field_0 ;
short nSprite ;
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 ;
TArray < Object > ObjectList ;
TArray < MoveSect > sMoveSect ;
TArray < slideData > SlideData ;
TArray < wallFace > WallFace ;
TArray < Drip > sDrip ;
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 nEnergyBlocks ;
short nFinaleStage ;
short nFinaleSpr ;
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
}
FSerializer & Serialize ( FSerializer & arc , const char * keyname , Object & w , Object * def )
{
2021-10-15 20:13:05 +00:00
if ( arc . BeginObject ( keyname ) )
{
arc ( " at0 " , w . field_0 )
( " health " , w . nHealth )
( " at4 " , w . field_4 )
( " at8 " , w . field_8 )
( " sprite " , w . nSprite )
( " at8 " , w . field_8 )
( " at10 " , w . field_10 )
( " at12 " , w . field_12 )
. EndObject ( ) ;
}
return arc ;
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 )
( " at20 " , w . field_20 )
( " at24 " , w . field_24 )
( " at28 " , w . field_28 )
( " at2c " , w . field_2C )
( " at30 " , w . field_30 )
( " at34 " , w . field_34 )
( " at38 " , w . field_38 )
( " at3c " , w . field_3C )
( " channel " , w . nChannel )
( " at2a " , w . field_2a )
( " at4a " , w . field_4a )
( " at6a " , w . nSprite )
( " 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 ) )
{
arc ( " at0 " , w . field_0 )
( " at2 " , w . field_2 )
( " at4 " , w . field_4 )
( " at6 " , w . field_6 )
( " at8 " , w . field_8 )
( " ata " , w . field_A )
( " atc " , w . field_C )
( " ate " , w . field_E )
. 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 )
( " sprite " , w . nSprite )
( " 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 )
( " energyblocks " , nEnergyBlocks )
( " finalestage " , nFinaleStage )
( " finalespr " , nFinaleSpr )
( " 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 ( ) ;
2019-08-31 07:47:15 +00:00
nEnergyBlocks = 0 ;
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 ;
SlideData [ nSlide ] . field_2a = - 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
2020-11-29 23:49:25 +00:00
SlideData [ nSlide ] . field_2a = nPoint ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
PointList [ nPoint ] . field_E = - 1 ;
PointList [ nPoint ] . field_0 = 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 + + )
{
2020-11-29 23:49:25 +00:00
short ax = SlideData [ nSlide ] . field_2a ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ax > = 0 )
{
while ( ax > = 0 )
{
if ( wall [ nWall ] . nextsector = = PointList [ ax ] . field_0 ) {
break ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
ax = PointList [ ax ] . field_E ;
}
}
else
{
if ( wall [ nWall ] . nextsector > = 0 )
{
nPoint = GrabPoint ( ) ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
PointList [ nPoint ] . field_E = SlideData [ nSlide ] . field_2a ;
2019-08-31 07:47:15 +00:00
PointList [ nPoint ] . field_0 = wall [ nWall ] . nextsector ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
SlideData [ nSlide ] . field_2a = 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-01-04 19:34:27 +00:00
SlideData [ nSlide ] . field_20 = wall [ nWall1 ] . x ;
SlideData [ nSlide ] . field_24 = wall [ nWall1 ] . y ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
SlideData [ nSlide ] . field_28 = wall [ nWall3 ] . x ;
SlideData [ nSlide ] . field_2C = wall [ nWall3 ] . y ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
SlideData [ nSlide ] . field_30 = wall [ ecx ] . x ;
SlideData [ nSlide ] . field_34 = wall [ ecx ] . y ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
SlideData [ nSlide ] . field_38 = wall [ nWall4 ] . x ;
SlideData [ nSlide ] . field_3C = 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 ) ;
2019-08-31 07:47:15 +00:00
int nSprite = insertsprite ( nSector , 899 ) ;
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2019-08-26 03:59:14 +00:00
2021-09-07 19:28:47 +00:00
SlideData [ nSlide ] . nSprite = nSprite ;
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 )
{
D3PlayFX ( StaticSound [ kSound23 ] , SlideData [ nSlide ] . nSprite ) ;
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-15 20:13:05 +00:00
int nSeekA = LongSeek ( & x , SlideData [ nSlide ] . field_30 , 20 , 20 ) ;
int var_34 = nSeekA ;
int var_20 = nSeekA ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
int nSeekB = LongSeek ( & y , SlideData [ nSlide ] . field_34 , 20 , 20 ) ;
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 ) ;
movesprite ( SlideData [ nSlide ] . nSprite , 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-15 20:13:05 +00:00
int nSeekC = LongSeek ( & x , SlideData [ nSlide ] . field_38 , 20 , 20 ) ;
int var_30 = nSeekC ;
var_20 = nSeekC ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
int nSeekD = LongSeek ( & y , SlideData [ nSlide ] . field_3C , 20 , 20 ) ;
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 ;
D3PlayFX ( StaticSound [ nStopSound ] , SlideData [ nSlide ] . nSprite ) ;
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 ) ;
}
2019-08-26 03:59:14 +00:00
int BuildTrap ( int nSprite , int edx , int ebx , int ecx )
{
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
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
2019-08-31 07:47:15 +00:00
changespritestat ( nSprite , 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
2019-08-31 07:47:15 +00:00
sTrap [ nTrap ] . nSprite = nSprite ;
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-22 06:06:24 +00:00
return nTrap ;
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-22 06:06:24 +00:00
return nTrap ;
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-02-26 23:16:03 +00:00
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-15 20:13:05 +00:00
short nSprite = sTrap [ nTrap ] . nSprite ;
auto pSprite = & sprite [ nSprite ] ;
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-19 22:26:26 +00:00
auto pBullet = BuildBullet ( & exhumedActors [ nSprite ] , nType , 0 , pSprite - > ang , nullptr , 1 ) ;
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 ) ;
}
2019-08-26 03:59:14 +00:00
int BuildArrow ( int nSprite , int nVal )
{
2019-08-31 07:47:15 +00:00
return BuildTrap ( nSprite , 0 , - 1 , nVal ) ;
2019-08-26 03:59:14 +00:00
}
int BuildFireBall ( int nSprite , int a , int b )
{
2019-08-31 07:47:15 +00:00
return BuildTrap ( nSprite , 1 , a , b ) ;
2019-08-26 03:59:14 +00:00
}
int BuildSpark ( int nSprite , int nVal )
{
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2021-09-06 06:33:02 +00:00
int var_14 = insertsprite ( pSprite - > sectnum , 0 ) ;
2019-08-31 07:47:15 +00:00
if ( var_14 < 0 ) {
return - 1 ;
}
2020-11-06 11:02:14 +00:00
auto spr = & sprite [ var_14 ] ;
2019-08-31 07:47:15 +00:00
assert ( var_14 < kMaxSprites ) ;
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-15 16:37:39 +00:00
spr - > owner = runlist_AddRunRec ( spr - > lotag - 1 , var_14 , 0x260000 ) ;
spr - > hitag = runlist_AddRunRec ( NewRun , var_14 , 0x260000 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return var_14 ;
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-17 14:22:25 +00:00
int nSprite = RunData [ ev - > nRun ] . nObjIndex ;
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2021-09-06 06:33:02 +00:00
2019-08-31 07:47:15 +00:00
assert ( nSprite > = 0 & & nSprite < kMaxSprites ) ;
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
{
BuildSpark ( nSprite , 2 ) ;
}
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-09-06 06:33:02 +00:00
int nMov = movesprite ( nSprite , pSprite - > xvel < < 12 , pSprite - > yvel < < 12 , pSprite - > zvel , 2560 , - 2560 , CLIPMASK1 ) ;
2019-08-31 07:47:15 +00:00
if ( ! nMov ) {
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 ) ;
2019-08-31 07:47:15 +00:00
mydeletesprite ( nSprite ) ;
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 ) ;
sprite [ nFinaleSpr ] . ang = nAng ;
BuildSpark ( nFinaleSpr , 1 ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ! RandomSize ( 2 ) )
{
2019-09-21 15:47:55 +00:00
PlayFX2 ( StaticSound [ kSound78 ] | 0x2000 , nFinaleSpr ) ;
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
}
int BuildEnergyBlock ( short nSector )
{
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
2020-10-14 22:10:37 +00:00
int const nSprite = insertsprite ( nSector , 406 ) ;
auto spr = & sprite [ nSprite ] ;
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
2019-08-31 07:47:15 +00:00
sector [ nSector ] . extra = nSprite ;
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-15 16:37:39 +00:00
spr - > owner = runlist_AddRunRec ( spr - > lotag - 1 , nSprite , 0x250000 ) ;
2021-02-26 23:16:03 +00:00
spr - > backuppos ( ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nEnergyBlocks + + ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return nSprite | 0x250000 ;
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-20 20:27:16 +00:00
runlist_DamageEnemy ( i - > GetSpriteIndex ( ) , - 1 , 1600 ) ;
2019-08-31 07:47:15 +00:00
}
}
+ + v0 ;
+ + v1 ;
if ( v0 > 107 ) {
return ;
}
}
2019-08-26 03:59:14 +00:00
}
void ExplodeEnergyBlock ( int nSprite )
{
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
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
2019-08-31 07:47:15 +00:00
BuildSpark ( nSprite , 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
2019-09-21 15:47:55 +00:00
PlayFX2 ( StaticSound [ kSound78 ] , nSprite ) ;
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 ) ;
2020-02-04 21:45:10 +00:00
BuildSpark ( nSprite , 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
{
nFinaleSpr = nSprite ;
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
2019-08-31 07:47:15 +00:00
changespritestat ( nSprite , 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-17 14:22:25 +00:00
int const nSprite = RunData [ ev - > nRun ] . nObjIndex ;
2020-10-14 22:10:37 +00:00
auto spr = & sprite [ nSprite ] ;
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-15 20:13:05 +00:00
int nSprite2 = insertsprite ( lasthitsect , 0 ) ;
auto pSprite2 = & sprite [ nSprite2 ] ;
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-15 20:13:05 +00:00
BuildSpark ( nSprite2 , 0 ) ; // shoot out blue orb when damaged
mydeletesprite ( nSprite2 ) ;
}
else
{
spr - > xrepeat = 0 ; // using xrepeat to store health
ExplodeEnergyBlock ( nSprite ) ;
}
}
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
void AIEnergyBlock : : RadialDamage ( RunListEvent * ev )
{
2021-10-17 14:22:25 +00:00
int const nSprite = RunData [ ev - > nRun ] . nObjIndex ;
2021-10-15 20:13:05 +00:00
auto spr = & sprite [ nSprite ] ;
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-15 20:13:05 +00:00
ev - > nDamage = runlist_CheckRadialDamage ( nSprite ) ;
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
}
2020-10-14 22:10:37 +00:00
int BuildObject ( int const nSprite , int nOjectType , int nHitag )
2019-08-26 03:59:14 +00:00
{
2020-10-14 22:10:37 +00:00
auto spr = & sprite [ nSprite ] ;
2019-08-26 03:59:14 +00:00
2020-11-29 23:49:25 +00:00
auto nObject = ObjectList . Reserve ( 1 ) ;
2021-10-26 21:52:21 +00:00
ObjectList [ nObject ] = { } ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
changespritestat ( nSprite , 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-15 16:37:39 +00:00
spr - > owner = runlist_AddRunRec ( spr - > lotag - 1 , nObject , 0x170000 ) ;
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
if ( spr - > statnum = = kStatDestructibleSprite ) {
2019-08-31 07:47:15 +00:00
ObjectList [ nObject ] . nHealth = 4 ;
}
else {
ObjectList [ nObject ] . nHealth = 120 ;
}
ObjectList [ nObject ] . nSprite = nSprite ;
2021-10-15 16:37:39 +00:00
ObjectList [ nObject ] . field_4 = runlist_AddRunRec ( NewRun , nObject , 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
{
ObjectList [ nObject ] . field_8 = SeqOffsets [ nSeq ] ;
if ( ! nOjectType ) // if not Explosion Trigger (e.g. Exploding Fire Cauldron)
{
2019-12-02 21:19:27 +00:00
ObjectList [ nObject ] . field_0 = RandomSize ( 4 ) % ( SeqSize [ ObjectList [ nObject ] . field_8 ] - 1 ) ;
2019-08-31 07:47:15 +00:00
}
2020-10-14 22:10:37 +00:00
int nSprite2 = insertsprite ( spr - > sectnum , 0 ) ;
2021-09-06 06:33:02 +00:00
auto pSprite2 = & sprite [ nSprite2 ] ;
2019-08-31 07:47:15 +00:00
ObjectList [ nObject ] . field_10 = nSprite2 ;
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
{
ObjectList [ nObject ] . field_0 = 0 ;
ObjectList [ nObject ] . field_8 = - 1 ;
2020-10-14 22:10:37 +00:00
if ( spr - > statnum = = kStatDestructibleSprite ) {
2019-12-02 21:19:27 +00:00
ObjectList [ nObject ] . field_10 = - 1 ;
}
else {
ObjectList [ nObject ] . field_10 = - nHitag ;
}
}
2021-02-26 23:16:03 +00:00
spr - > backuppos ( ) ;
2019-08-31 07:47:15 +00:00
return nObject | 0x170000 ;
2019-08-26 03:59:14 +00:00
}
2020-02-04 21:45:10 +00:00
// in-game destructable wall mounted screen
2019-08-26 03:59:14 +00:00
void ExplodeScreen ( short nSprite )
{
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2021-09-06 06:33:02 +00:00
pSprite - > z - = GetSpriteHeight ( nSprite ) / 2 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < 30 ; i + + ) {
2020-02-04 21:45:10 +00:00
BuildSpark ( nSprite , 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 ;
2019-09-21 15:47:55 +00:00
PlayFX2 ( StaticSound [ kSound78 ] , nSprite ) ;
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-17 14:22:25 +00:00
short nObject = RunData [ ev - > nRun ] . nObjIndex ;
2021-10-15 16:49:35 +00:00
auto pObject = & ObjectList [ nObject ] ;
2019-08-31 07:47:15 +00:00
2021-10-20 22:00:26 +00:00
auto pActor = & exhumedActors [ pObject - > nSprite ] ; // ev->pObjActor;
2021-10-15 16:49:35 +00:00
short nSprite = pObject - > nSprite ;
2021-10-15 20:13:05 +00:00
auto pSprite = & sprite [ nSprite ] ;
2021-09-06 06:33:02 +00:00
short nStat = pSprite - > statnum ;
2021-10-15 16:49:35 +00:00
short bx = pObject - > field_8 ;
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-15 20:13:05 +00:00
pObject - > field_0 + + ;
if ( pObject - > field_0 > = SeqSize [ bx ] ) {
pObject - > field_0 = 0 ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
pSprite - > picnum = seq_GetSeqPicnum2 ( bx , pObject - > field_0 ) ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( pObject - > nHealth > = 0 ) {
goto FUNCOBJECT_GOTO ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
pObject - > nHealth + + ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( pObject - > nHealth )
{
FUNCOBJECT_GOTO :
if ( nStat ! = kStatExplodeTarget )
{
int nMov = movesprite ( nSprite , pSprite - > xvel < < 6 , pSprite - > yvel < < 6 , pSprite - > zvel , 0 , 0 , CLIPMASK0 ) ;
if ( pSprite - > statnum = = kStatExplodeTrigger ) {
pSprite - > pal = 1 ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
if ( nMov & 0x20000 )
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
if ( ( ( nMov & 0xC000 ) > 0x8000 ) & & ( ( nMov & 0xC000 ) = = 0xC000 ) )
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 + + ) {
BuildCreatureChunk ( nSprite | 0x4000 , seq_GetSeqPicnum ( kSeqFirePot , ( i > > 2 ) + 1 , 0 ) ) ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
runlist_RadialDamageEnemy ( nSprite , 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 + + ) {
BuildCreatureChunk ( nSprite | 0x4000 , seq_GetSeqPicnum ( kSeqFirePot , ( i > > 1 ) + 3 , 0 ) ) ;
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 ) ;
runlist_SubRunRec ( pObject - > field_4 ) ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
mydeletesprite ( nSprite ) ;
return ;
}
else
{
2021-10-21 08:20:08 +00:00
StartRegenerate ( pActor ) ;
2021-10-15 20:13:05 +00:00
pObject - > nHealth = 120 ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
pSprite - > x = sprite [ pObject - > field_10 ] . x ;
pSprite - > y = sprite [ pObject - > field_10 ] . y ;
pSprite - > z = sprite [ pObject - > field_10 ] . z ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
mychangespritesect ( nSprite , sprite [ pObject - > field_10 ] . sectnum ) ;
return ;
}
}
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
void AIObject : : Damage ( RunListEvent * ev )
{
2021-10-17 14:22:25 +00:00
short nObject = RunData [ ev - > nRun ] . nObjIndex ;
2021-10-15 20:13:05 +00:00
auto pObject = & ObjectList [ nObject ] ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
short nSprite = pObject - > nSprite ;
auto pSprite = & sprite [ nSprite ] ;
short nStat = pSprite - > statnum ;
short bx = pObject - > field_8 ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( nStat > = 150 | | pObject - > nHealth < = 0 ) {
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( nStat = = 98 )
{
D3PlayFX ( ( StaticSound [ kSound47 ] | 0x2000 ) | ( RandomSize ( 2 ) < < 9 ) , nSprite ) ;
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
pObject - > nHealth - = ( short ) ev - > nDamage ;
if ( pObject - > nHealth > 0 ) {
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( nStat = = kStatDestructibleSprite )
{
ExplodeScreen ( nSprite ) ;
}
else
{
pObject - > nHealth = - ( RandomSize ( 3 ) + 1 ) ;
}
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
void AIObject : : Draw ( RunListEvent * ev )
{
2021-10-17 14:22:25 +00:00
short nObject = RunData [ ev - > nRun ] . nObjIndex ;
2021-10-15 20:13:05 +00:00
auto pObject = & ObjectList [ nObject ] ;
short bx = pObject - > field_8 ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( bx > - 1 )
{
2021-10-17 14:22:25 +00:00
seq_PlotSequence ( ev - > nParam , bx , pObject - > field_0 , 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-17 14:22:25 +00:00
short nObject = RunData [ ev - > nRun ] . nObjIndex ;
2021-10-15 20:13:05 +00:00
auto pObject = & ObjectList [ nObject ] ;
2019-08-26 03:59:14 +00:00
2021-10-15 20:13:05 +00:00
short nSprite = pObject - > nSprite ;
auto pSprite = & sprite [ nSprite ] ;
short nStat = pSprite - > statnum ;
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( pObject - > nHealth > 0 & & pSprite - > cstat & 0x101
& & ( nStat ! = kStatExplodeTarget
| | sprite [ nRadialSpr ] . statnum = = 201
| | ( nRadialBullet ! = 3 & & nRadialBullet > - 1 )
| | sprite [ nRadialSpr ] . statnum = = kStatExplodeTrigger ) )
{
int nDamage = runlist_CheckRadialDamage ( nSprite ) ;
if ( nDamage < = 0 ) {
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( pSprite - > statnum ! = kStatAnubisDrum ) {
pObject - > nHealth - = nDamage ;
}
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-15 20:13:05 +00:00
if ( pObject - > nHealth > 0 ) {
return ;
}
2019-08-31 07:47:15 +00:00
2021-10-15 20:13:05 +00:00
if ( pSprite - > statnum = = kStatExplodeTarget )
{
pObject - > nHealth = - 1 ;
short ax = pObject - > field_10 ;
if ( ax < 0 | | ObjectList [ ax ] . nHealth < = 0 ) {
return ;
2019-08-31 07:47:15 +00:00
}
2021-10-15 20:13:05 +00:00
ObjectList [ ax ] . nHealth = - 1 ;
}
else if ( pSprite - > statnum = = kStatDestructibleSprite )
{
pObject - > nHealth = 0 ;
ExplodeScreen ( nSprite ) ;
}
else
{
pObject - > 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
{
int nObjectSprite = ObjectList [ i ] . nSprite ;
if ( sprite [ nObjectSprite ] . statnum = = kStatExplodeTarget )
{
if ( ! ObjectList [ i ] . field_10 ) {
ObjectList [ i ] . field_10 = - 1 ;
}
else
{
int edi = ObjectList [ i ] . field_10 ;
ObjectList [ i ] . field_10 = - 1 ;
2020-11-29 23:49:25 +00:00
for ( unsigned j = 0 ; j < ObjectList . Size ( ) ; j + + )
2019-08-31 07:47:15 +00:00
{
if ( i ! = j & & sprite [ ObjectList [ j ] . nSprite ] . statnum = = kStatExplodeTarget & & edi = = ObjectList [ j ] . field_10 )
{
ObjectList [ i ] . field_10 = j ;
ObjectList [ j ] . field_10 = i ;
}
}
}
}
}
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