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"
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
# define kMaxBobs 200
# define kMaxDrips 50
# define kMaxMoveSects 50
# define kMaxObjects 128
# define kMaxWallFace 4096
# define kMaxSlideData 128
# define kMaxPoints 1024
# define kMaxTraps 40
# define kMaxTrails 20
# define kMaxTrailPoints 100
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 ;
short pad ;
2019-08-26 03:59:14 +00:00
} ;
struct TrailPoint
{
2019-08-31 07:47:15 +00:00
int x ;
int y ;
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 ;
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?
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
} ;
// TODO - rename
struct slideData2
{
2019-08-31 07:47:15 +00:00
short nChannel ;
short field_2 ;
short field_4 ;
short field_6 ;
short field_8 ;
uint8_t field_A [ 6 ] ; // pad?
2019-08-26 03:59:14 +00:00
} ;
struct slideData
{
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 ;
2019-08-26 03:59:14 +00:00
} ;
Trap sTrap [ kMaxTraps ] ;
Bob sBob [ kMaxBobs ] ;
Trail sTrail [ kMaxTrails ] ;
TrailPoint sTrailPoint [ kMaxTrailPoints ] ;
Elev Elevator [ kMaxElevs ] ;
Object ObjectList [ kMaxObjects ] ;
MoveSect sMoveSect [ kMaxMoveSects ] ;
slideData SlideData [ kMaxSlideData ] ;
short sMoveDir [ kMaxMoveSects ] ;
wallFace WallFace [ kMaxWallFace ] ;
slideData2 SlideData2 [ kMaxSlideData ] ;
Point PointList [ kMaxPoints ] ;
short nTrapInterval [ kMaxTraps ] ;
short sBobID [ kMaxBobs ] ;
short PointCount ;
short PointFree [ kMaxPoints ] ;
short SlideCount = 0 ;
short SlideFree [ kMaxSlides ] ;
char nTrailPointVal [ kMaxTrailPoints ] ;
short nTrailPointPrev [ kMaxTrailPoints ] ;
short nTrailPointNext [ kMaxTrailPoints ] ;
Drip sDrip [ kMaxDrips ] ;
short ElevCount = - 1 ;
short WallFaceCount = - 1 ;
2019-08-31 07:47:15 +00:00
int lFinaleStart ;
2019-08-26 03:59:14 +00:00
short nTrailPoints ;
short nEnergyBlocks ;
short nMoveSects ;
short nFinaleStage ;
short nTrails ;
short nTraps ;
short nFinaleSpr ;
short ObjectCount ;
short nDrips ;
short nBobs = 0 ;
short nDronePitch = 0 ;
short nSmokeSparks = 0 ;
// done
void InitObjects ( )
{
2019-08-31 07:47:15 +00:00
ObjectCount = 0 ;
nTraps = 0 ;
nDrips = 0 ;
nBobs = 0 ;
nTrails = 0 ;
nTrailPoints = 0 ;
nMoveSects = 0 ;
memset ( sTrail , - 1 , sizeof ( sTrail ) ) ;
nEnergyBlocks = 0 ;
nDronePitch = 0 ;
nFinaleStage = 0 ;
lFinaleStart = 0 ;
nSmokeSparks = 0 ;
2019-08-26 03:59:14 +00:00
}
// done
void InitElev ( )
{
2019-08-31 07:47:15 +00:00
ElevCount = kMaxElevs ;
2019-08-26 03:59:14 +00:00
}
// done
int BuildWallSprite ( int nSector )
{
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
2019-08-31 07:47:15 +00:00
int nSprite = insertsprite ( nSector , 401 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . x = ( x + x2 ) / 2 ;
sprite [ nSprite ] . y = ( y + y2 ) / 2 ;
sprite [ nSprite ] . z = ( sector [ nSector ] . floorz + sector [ nSector ] . ceilingz ) / 2 ;
sprite [ nSprite ] . cstat = 0x8000 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return nSprite ;
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 ;
int ecx = 0x7FFFFFFF ;
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 ;
int nSprite = - 1 ;
for ( i = 0 ; i < kMaxSprites ; i + + )
{
if ( sprite [ i ] . lotag = = 0 )
{
if ( ( sprite [ i ] . cstat & 0x50 ) = = 80 )
{
int var_28 = sprite [ i ] . x ;
int ebx = sprite [ i ] . y ;
if ( ( var_28 > = var_24 ) & & ( esi > = var_28 ) & & ( ebx > = ecx ) & & ( ebx < = edi ) )
{
sprite [ i ] . owner = nSprite ;
nSprite = i ;
}
}
}
}
if ( nSprite < 0 )
{
nSprite = insertsprite ( nSector , 401 ) ;
sprite [ nSprite ] . x = ( var_24 + esi ) / 2 ;
sprite [ nSprite ] . y = ( ecx + edi ) / 2 ;
sprite [ nSprite ] . z = sector [ nSector ] . floorz ;
sprite [ nSprite ] . cstat = 0x8000 ;
sprite [ nSprite ] . owner = - 1 ;
sprite [ nSprite ] . lotag = 0 ;
sprite [ nSprite ] . hitag = 0 ;
}
return nSprite ;
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
{
2019-08-31 07:47:15 +00:00
assert ( ElevCount > 0 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( ElevCount < = 0 ) {
return - 1 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
ElevCount - - ;
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 ) {
nWallSprite = BuildWallSprite ( nSector ) ;
}
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
2019-08-31 07:47:15 +00:00
assert ( ElevCount > 0 ) ;
if ( ElevCount < = 0 ) {
return - 1 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
ElevCount - - ;
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 ) {
nWallSprite = BuildWallSprite ( nSector ) ;
}
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
2019-08-31 07:47:15 +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 )
{
short nSprite = headspritesect [ nSector ] ;
int nZDiff = sector [ nSector ] . floorz - sector [ nSector ] . ceilingz ;
while ( nSprite ! = - 1 )
{
if ( ( sprite [ nSprite ] . cstat & 0x101 ) & & ( nZDiff < GetSpriteHeight ( nSprite ) ) )
{
if ( nVal ! = 1 ) {
return 1 ;
}
b = 1 ;
runlist_DamageEnemy ( nSprite , - 1 , 5 ) ;
if ( sprite [ nSprite ] . statnum = = 100 & & PlayerList [ GetPlayerFromSprite ( nSprite ) ] . nHealth < = 0 )
{
PlayFXAtXYZ ( StaticSound [ kSoundJonFDie ] ,
sprite [ nSprite ] . x ,
sprite [ nSprite ] . y ,
sprite [ nSprite ] . z ,
2019-11-28 00:03:29 +00:00
sprite [ nSprite ] . sectnum | 0x4000 ) ;
2019-08-31 07:47:15 +00:00
}
}
nSprite = nextspritesect [ nSprite ] ;
}
}
else
{
for ( int i = headspritesect [ nSector ] ; i ! = - 1 ; i = nextspritesect [ i ] )
{
if ( sprite [ i ] . cstat & 0x101 ) {
return 1 ;
}
}
b = 0 ;
}
return b ;
2019-08-26 03:59:14 +00:00
}
// done
void MoveSectorSprites ( int nSector , int z )
{
2019-08-31 07:47:15 +00:00
int nSprite = headspritesect [ nSector ] ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
while ( nSprite ! = - 1 )
{
if ( sprite [ nSprite ] . statnum ! = 200 ) {
sprite [ nSprite ] . z + = z ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nSprite = nextspritesect [ nSprite ] ;
}
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
}
2020-08-28 09:02:13 +00:00
void FuncElev ( int a , int , int nRun )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
short nElev = RunData [ nRun ] . nVal ;
assert ( nElev > = 0 & & nElev < kMaxElevs ) ;
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
2019-08-31 07:47:15 +00:00
int nMessage = a & 0x7F0000 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nMessage < 0x10000 ) {
return ;
}
2019-08-26 03:59:14 +00:00
// int var_24 = var_18 & 0x10; // floor based?
2019-08-31 07:47:15 +00:00
switch ( nMessage )
{
default :
{
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 0x10000 :
{
2019-08-26 03:59:14 +00:00
// short ax = var_18 & 8;
2019-08-31 07:47:15 +00:00
short dx = sRunChannels [ nChannel ] . c ;
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!
if ( var_18 & 0x8 )
{
if ( dx ) {
edi = 1 ;
}
else {
edi = 0 ;
}
}
else
{
// loc_20D48:
if ( var_18 & 0x10 ) // was var_24
{
if ( Elevator [ nElev ] . field_32 < 0 )
{
Elevator [ nElev ] . field_32 = runlist_AddRunRec ( NewRun , RunData [ nRun ] . nMoves ) ;
StartElevSound ( Elevator [ nElev ] . nSprite , var_18 ) ;
edi = 1 ;
}
}
else
{
if ( dx < 0 ) {
edi = 0 ;
}
else
{
if ( dx = = Elevator [ nElev ] . nCurZOffset | | dx > = Elevator [ nElev ] . nCountZOffsets )
{
Elevator [ nElev ] . field_36 = dx ;
edi = 1 ;
}
else
{
Elevator [ nElev ] . nCurZOffset = sRunChannels [ nChannel ] . c ;
edi = 1 ;
}
}
}
}
assert ( edi ! = 999 ) ;
// loc_20DF9:
if ( edi )
{
if ( Elevator [ nElev ] . field_32 < 0 )
{
Elevator [ nElev ] . field_32 = runlist_AddRunRec ( NewRun , RunData [ nRun ] . nMoves ) ;
StartElevSound ( Elevator [ nElev ] . nSprite , var_18 ) ;
}
}
else
{
//loc_20E4E:
if ( Elevator [ nElev ] . field_32 > = 0 )
{
runlist_SubRunRec ( Elevator [ nElev ] . field_32 ) ;
Elevator [ nElev ] . field_32 = - 1 ;
}
}
return ;
}
case 0x20000 :
{
short nSector = Elevator [ nElev ] . nSector ;
short di = Elevator [ nElev ] . nSprite ;
int ebp = 0 ; // initialise to *something*
if ( var_18 & 0x2 )
{
int nZOffset = Elevator [ nElev ] . nCurZOffset ;
int nZVal = Elevator [ nElev ] . zOffsets [ nZOffset ] ;
short nSectorB = nSector ;
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 ;
StartElevSound ( di , var_18 ) ;
}
else
{
StopSpriteSound ( di ) ;
runlist_SubRunRec ( nRun ) ;
Elevator [ nElev ] . field_32 = - 1 ;
runlist_ReadyChannel ( nChannel ) ;
D3PlayFX ( StaticSound [ nStopSound ] , Elevator [ nElev ] . nSprite ) ;
}
}
else
{
assert ( nSector = = nSectorB ) ;
MoveSectorSprites ( nSector , nVal ) ;
if ( nVal < 0 & & CheckSectorSprites ( nSector , 2 ) )
{
runlist_ChangeChannel ( nChannel , sRunChannels [ nChannel ] . c = = 0 ) ;
return ;
}
}
}
else
{
// loc_20FC3:
int ceilZ = sector [ nSector ] . ceilingz ;
sectortype * var_28 = & sector [ nSector ] ;
int nZOffset = Elevator [ nElev ] . nCurZOffset ;
int zVal = Elevator [ nElev ] . zOffsets [ nZOffset ] ;
int nVal = LongSeek ( & ceilZ , zVal , Elevator [ nElev ] . field_6 , Elevator [ nElev ] . field_A ) ;
ebp = nVal ;
if ( ! nVal )
{
if ( var_18 & 0x10 )
{
Elevator [ nElev ] . nCurZOffset ^ = 1 ;
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 ) ;
}
return ;
}
else if ( nVal > 0 )
{
if ( ceilZ = = zVal )
{
if ( var_18 & 0x4 ) {
SetQuake ( di , 30 ) ;
}
2019-08-26 03:59:14 +00:00
2019-09-21 15:47:55 +00:00
PlayFXAtXYZ ( StaticSound [ kSound26 ] , sprite [ di ] . x , sprite [ di ] . y , sprite [ di ] . z , sprite [ di ] . sectnum ) ;
2019-08-31 07:47:15 +00:00
}
if ( var_18 & 0x4 )
{
if ( CheckSectorSprites ( nSector , 1 ) ) {
return ;
}
}
else
{
if ( CheckSectorSprites ( nSector , 0 ) )
{
runlist_ChangeChannel ( nChannel , sRunChannels [ nChannel ] . c = = 0 ) ;
return ;
}
}
}
var_28 - > ceilingz = ceilZ ;
}
// maybe this doesn't go here?
while ( di ! = - 1 )
{
sprite [ di ] . z + = ebp ;
di = sprite [ di ] . owner ;
}
return ;
}
}
2019-08-26 03:59:14 +00:00
}
// done
void InitWallFace ( )
{
2019-08-31 07:47:15 +00:00
WallFaceCount = kMaxWallFace ;
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
{
2019-08-31 07:47:15 +00:00
if ( WallFaceCount < = 0 ) {
2019-11-24 09:03:19 +00:00
I_Error ( " Too many wall faces! \n " ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
WallFaceCount - - ;
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
2019-08-31 07:47:15 +00:00
return WallFaceCount | 0x70000 ;
2019-08-26 03:59:14 +00:00
}
2020-08-28 09:02:13 +00:00
void FuncWallFace ( int a , int , int nRun )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
int nWallFace = RunData [ nRun ] . nVal ;
assert ( nWallFace > = 0 & & nWallFace < kMaxWallFace ) ;
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
if ( ( a & 0x7F0000 ) ! = 0x10000 )
return ;
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
}
// done
void InitPoint ( )
{
2019-08-31 07:47:15 +00:00
PointCount = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < kMaxPoints ; i + + ) {
PointFree [ i ] = i ;
}
2019-08-26 03:59:14 +00:00
}
// done
int GrabPoint ( )
{
2019-08-31 07:47:15 +00:00
return PointFree [ PointCount + + ] ;
2019-08-26 03:59:14 +00:00
}
// done
void InitSlide ( )
{
2019-08-31 07:47:15 +00:00
SlideCount = kMaxSlides ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < kMaxSlides ; i + + ) {
SlideFree [ i ] = i ;
}
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
}
2020-02-04 21:45:10 +00:00
int BuildSlide ( int nChannel , int nStartWall , int ebx , int ecx , int nWall2 , int nWall3 , int nWall4 )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
if ( SlideCount < = 0 ) {
2019-11-24 09:03:19 +00:00
I_Error ( " Too many slides! \n " ) ;
2019-08-31 07:47:15 +00:00
return - 1 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SlideCount - - ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nSlide = SlideCount ;
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
2019-08-31 07:47:15 +00:00
SlideData2 [ nSlide ] . field_4 = - 1 ;
SlideData2 [ nSlide ] . nChannel = nChannel ;
SlideData2 [ nSlide ] . field_2 = - 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
2019-08-31 07:47:15 +00:00
SlideData2 [ nSlide ] . field_2 = 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 + + )
{
short ax = SlideData2 [ nSlide ] . field_2 ;
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
2019-08-31 07:47:15 +00:00
PointList [ nPoint ] . field_E = SlideData2 [ nSlide ] . field_2 ;
PointList [ nPoint ] . field_0 = wall [ nWall ] . nextsector ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SlideData2 [ nSlide ] . field_2 = nPoint ;
}
}
}
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
SlideData [ nSlide ] . field_0 = nStartWall ;
SlideData [ nSlide ] . field_4 = ebx ;
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
2020-02-04 21:45:10 +00:00
SlideData [ nSlide ] . field_20 = wall [ ebx ] . x ;
SlideData [ nSlide ] . field_24 = wall [ ebx ] . 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
2019-08-31 07:47:15 +00:00
int nSprite = insertsprite ( nSector , 899 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SlideData2 [ nSlide ] . field_6 = nSprite ;
sprite [ nSprite ] . cstat = 0x8000 ;
2020-02-04 21:45:10 +00:00
sprite [ nSprite ] . x = wall [ nStartWall ] . x ;
sprite [ nSprite ] . y = wall [ nStartWall ] . y ;
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . z = sector [ nSector ] . floorz ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SlideData2 [ nSlide ] . field_8 = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return nSlide | 0x80000 ;
2019-08-26 03:59:14 +00:00
}
2020-08-28 09:02:13 +00:00
void FuncSlide ( int a , int , int nRun )
2019-08-26 03:59:14 +00:00
{
2019-12-02 15:15:45 +00:00
int nSlide = RunData [ nRun ] . nVal ;
2019-08-31 07:47:15 +00:00
assert ( nSlide > = 0 & & nSlide < kMaxSlides ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short nChannel = SlideData2 [ nSlide ] . nChannel ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nMessage = a & 0x7F0000 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int ebp = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short cx = sRunChannels [ nChannel ] . c ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
switch ( nMessage )
{
case 0x10000 :
{
if ( SlideData2 [ nSlide ] . field_4 > = 0 )
{
runlist_SubRunRec ( SlideData2 [ nSlide ] . field_4 ) ;
SlideData2 [ nSlide ] . field_4 = - 1 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( sRunChannels [ nChannel ] . c & & sRunChannels [ nChannel ] . c ! = 1 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2019-12-02 15:15:45 +00:00
SlideData2 [ nSlide ] . field_4 = runlist_AddRunRec ( NewRun , RunData [ nRun ] . nMoves ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( SlideData2 [ nSlide ] . field_8 ! = sRunChannels [ nChannel ] . c )
{
D3PlayFX ( StaticSound [ kSound23 ] , SlideData2 [ nSlide ] . field_6 ) ;
SlideData2 [ nSlide ] . field_8 = sRunChannels [ nChannel ] . c ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 0x20000 :
{
int clipmask = ebp + 1 ; // RENAME
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +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
2019-08-31 07:47:15 +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
2019-08-31 07:47:15 +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
2019-08-31 07:47:15 +00:00
dragpoint ( SlideData [ nSlide ] . field_4 , x , y , 0 ) ;
movesprite ( SlideData2 [ nSlide ] . field_6 , var_34 < < 14 , var_2C < < 14 , 0 , 0 , 0 , CLIPMASK1 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_34 = = 0 )
{
if ( var_2C = = 0 )
{
ebp = clipmask ;
}
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nWall = SlideData [ nSlide ] . field_0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
y = wall [ nWall ] . y + var_24 ;
x = wall [ nWall ] . x + var_20 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
dragpoint ( SlideData [ nSlide ] . field_0 , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nWall = SlideData [ nSlide ] . field_C ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
x = wall [ nWall ] . x ;
y = wall [ nWall ] . y ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +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
2019-08-31 07:47:15 +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
2019-08-31 07:47:15 +00:00
dragpoint ( SlideData [ nSlide ] . field_C , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( var_30 = = 0 & & edi = = 0 ) {
ebp + + ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nWall = SlideData [ nSlide ] . field_8 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
x = wall [ nWall ] . x + var_20 ;
y = wall [ nWall ] . y + var_24 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +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
2020-02-04 21:45:10 +00:00
int nSeekA = LongSeek ( & x , SlideData [ nSlide ] . x1 , 20 , 20 ) ;
2019-08-31 07:47:15 +00:00
int edi = nSeekA ;
int var_1C = nSeekA ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
int nSeekB = LongSeek ( & y , SlideData [ nSlide ] . y1 , 20 , 20 ) ;
2019-08-31 07:47:15 +00:00
int ecx = nSeekB ;
int var_28 = nSeekB ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
dragpoint ( SlideData [ nSlide ] . field_0 , x , y , 0 ) ;
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
if ( edi = = 0 & & ecx = = 0 ) {
ebp = clipmask ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nWall = SlideData [ nSlide ] . field_4 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
y = wall [ nWall ] . y + var_28 ;
x = wall [ nWall ] . x + var_1C ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
dragpoint ( SlideData [ nSlide ] . field_4 , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nWall = SlideData [ nSlide ] . field_8 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
x = wall [ nWall ] . x ;
y = wall [ nWall ] . y ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
int nSeekC = LongSeek ( & x , SlideData [ nSlide ] . x2 , 20 , 20 ) ;
2019-08-31 07:47:15 +00:00
edi = nSeekC ;
var_1C = nSeekC ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
int nSeekD = LongSeek ( & y , SlideData [ nSlide ] . y2 , 20 , 20 ) ;
2019-08-31 07:47:15 +00:00
ecx = nSeekD ;
var_28 = nSeekD ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
dragpoint ( SlideData [ nSlide ] . field_8 , x , y , 0 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( edi = = 0 & & ecx = = 0 ) {
ebp + + ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nWall = SlideData [ nSlide ] . field_C ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
y = wall [ nWall ] . y + var_28 ;
x = wall [ nWall ] . x + var_1C ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
dragpoint ( SlideData [ nSlide ] . field_C , x , y , 0 ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// loc_21A51:
if ( ebp > = 2 )
{
runlist_SubRunRec ( SlideData2 [ nSlide ] . field_4 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
SlideData2 [ nSlide ] . field_4 = - 1 ;
D3PlayFX ( StaticSound [ nStopSound ] , SlideData2 [ nSlide ] . field_6 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
runlist_ReadyChannel ( nChannel ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return ;
}
}
2019-08-26 03:59:14 +00:00
}
int BuildTrap ( int nSprite , int edx , int ebx , int ecx )
{
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
2019-08-31 07:47:15 +00:00
if ( nTraps > = kMaxTraps ) {
2019-11-24 09:03:19 +00:00
I_Error ( " Too many traps! \n " ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short nTrap = nTraps ;
nTraps + + ;
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
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . cstat = 0x8000 ;
sprite [ nSprite ] . xvel = 0 ;
sprite [ nSprite ] . yvel = 0 ;
sprite [ nSprite ] . zvel = 0 ;
sprite [ nSprite ] . extra = - 1 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . lotag = runlist_HeadRun ( ) + 1 ;
sprite [ nSprite ] . hitag = runlist_AddRunRec ( NewRun , nTrap | 0x1F0000 ) ;
sprite [ nSprite ] . owner = runlist_AddRunRec ( sprite [ nSprite ] . lotag - 1 , nTrap | 0x1F0000 ) ;
2019-08-26 03:59:14 +00:00
// GrabTimeSlot(3);
2019-08-31 07:47:15 +00:00
sTrap [ nTrap ] . nSprite = nSprite ;
sTrap [ nTrap ] . nType = ( var_14 = = 0 ) + 14 ;
sTrap [ nTrap ] . field_0 = - 1 ;
nTrapInterval [ nTrap ] = 64 - ( 2 * var_10 ) ;
if ( nTrapInterval [ nTrap ] < 5 ) {
nTrapInterval [ nTrap ] = 5 ;
}
sTrap [ nTrap ] . field_C = 0 ;
sTrap [ nTrap ] . field_A = 0 ;
if ( var_18 = = - 1 ) {
return nTrap | 0x1F0000 ;
}
sTrap [ nTrap ] . field_6 = - 1 ;
sTrap [ nTrap ] . field_8 = - 1 ;
short nSector = sprite [ nSprite ] . sectnum ;
short nWall = sector [ nSector ] . wallptr ;
int i = 0 ;
while ( 1 )
{
if ( sector [ nSector ] . wallnum > = i ) {
return nTrap | 0x1F0000 ;
}
if ( var_18 = = wall [ nWall ] . hitag )
{
if ( sTrap [ nTrap ] . field_6 ! = - 1 )
{
sTrap [ nTrap ] . field_8 = nWall ;
sTrap [ nTrap ] . field_C = wall [ nWall ] . picnum ;
return nTrap | 0x1F0000 ;
}
else
{
sTrap [ nTrap ] . field_6 = nWall ;
sTrap [ nTrap ] . field_A = wall [ nWall ] . picnum ;
}
}
ecx + + ;
nWall + + ;
}
2019-08-26 03:59:14 +00:00
}
2020-08-28 09:02:13 +00:00
void FuncTrap ( int a , int , int nRun )
2019-08-26 03:59:14 +00:00
{
2019-11-22 00:10:56 +00:00
short nTrap = RunData [ nRun ] . nVal ;
2019-08-31 07:47:15 +00:00
short nSprite = sTrap [ nTrap ] . nSprite ;
int nMessage = a & 0x7F0000 ;
switch ( nMessage )
{
case 0x10000 :
{
short nChannel = a & 0x3FFF ;
if ( sRunChannels [ nChannel ] . c > 0 )
{
sTrap [ nTrap ] . field_0 = 12 ;
}
else
{
sTrap [ nTrap ] . field_0 = - 1 ;
}
return ;
}
case 0x20000 :
{
if ( sTrap [ nTrap ] . field_0 > = 0 )
{
sTrap [ nTrap ] . field_0 - - ;
if ( sTrap [ nTrap ] . field_0 > 10 ) {
return ;
}
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
short nType = sTrap [ nTrap ] . nType ;
if ( sTrap [ nTrap ] . field_0 = = 0 )
{
sTrap [ nTrap ] . field_0 = nTrapInterval [ nTrap ] ;
if ( nType = = 14 )
{
short nWall = sTrap [ nTrap ] . field_6 ;
if ( nWall > - 1 )
{
wall [ nWall ] . picnum = sTrap [ nTrap ] . field_A ;
}
nWall = sTrap [ nTrap ] . field_8 ;
if ( nWall > - 1 )
{
wall [ nWall ] . picnum = sTrap [ nTrap ] . field_C ;
}
}
}
else
{
// loc_21D92:
if ( sTrap [ nTrap ] . field_0 ! = 5 ) {
return ;
}
int nBullet = BuildBullet ( nSprite , nType , 0 , 0 , 0 , sprite [ nSprite ] . ang , 0 , 1 ) ;
2019-11-22 00:10:56 +00:00
if ( nBullet > - 1 )
2019-08-31 07:47:15 +00:00
{
2019-11-22 00:10:56 +00:00
short nBulletSprite = nBullet & 0xFFFF ; // isolate the sprite index (disregard top 16 bits)
assert ( nBulletSprite > = 0 ) ;
2019-08-31 07:47:15 +00:00
2019-11-22 00:10:56 +00:00
if ( nType = = 15 )
2019-08-31 07:47:15 +00:00
{
2019-11-22 00:10:56 +00:00
sprite [ nBulletSprite ] . ang = ( sprite [ nBulletSprite ] . ang - 512 ) & kAngleMask ;
D3PlayFX ( StaticSound [ kSound32 ] , nSprite ) ;
2019-08-31 07:47:15 +00:00
}
2019-11-22 00:10:56 +00:00
else
2019-08-31 07:47:15 +00:00
{
2019-11-22 00:10:56 +00:00
sprite [ nBulletSprite ] . clipdist = 50 ;
2019-08-31 07:47:15 +00:00
2019-11-22 00:10:56 +00:00
short nWall = sTrap [ nTrap ] . field_6 ;
if ( nWall > - 1 )
{
wall [ nWall ] . picnum = sTrap [ nTrap ] . field_A + 1 ;
}
nWall = sTrap [ nTrap ] . field_8 ;
if ( nWall > - 1 )
{
wall [ nWall ] . picnum = sTrap [ nTrap ] . field_C + 1 ;
}
D3PlayFX ( StaticSound [ kSound36 ] , nSprite ) ;
}
2019-08-31 07:47:15 +00:00
}
}
}
return ;
}
case 0x30000 :
case 0x90000 :
case 0x80000 :
2019-11-01 00:36:20 +00:00
case 0xA0000 :
2019-08-31 07:47:15 +00:00
return ;
default :
DebugOut ( " unknown msg %d for trap \n " , a & 0x7F0000 ) ;
return ;
}
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 )
{
2019-08-31 07:47:15 +00:00
int var_14 = insertsprite ( sprite [ nSprite ] . sectnum , 0 ) ;
if ( var_14 < 0 ) {
return - 1 ;
}
assert ( var_14 < kMaxSprites ) ;
sprite [ var_14 ] . x = sprite [ nSprite ] . x ;
sprite [ var_14 ] . y = sprite [ nSprite ] . y ;
sprite [ var_14 ] . cstat = 0 ;
sprite [ var_14 ] . shade = - 127 ;
sprite [ var_14 ] . pal = 1 ;
sprite [ var_14 ] . xoffset = 0 ;
sprite [ var_14 ] . yoffset = 0 ;
2019-11-18 22:15:48 +00:00
sprite [ var_14 ] . xrepeat = 50 ;
2019-08-31 07:47:15 +00:00
sprite [ var_14 ] . yrepeat = 50 ;
if ( nVal > = 2 )
{
sprite [ var_14 ] . picnum = kEnergy2 ;
nSmokeSparks + + ;
if ( nVal = = 3 )
{
sprite [ var_14 ] . xrepeat = 120 ;
2019-11-20 16:21:32 +00:00
sprite [ var_14 ] . yrepeat = 120 ;
2019-08-31 07:47:15 +00:00
}
else
{
2019-11-18 22:15:48 +00:00
sprite [ var_14 ] . xrepeat = sprite [ nSprite ] . xrepeat + 15 ;
sprite [ var_14 ] . yrepeat = sprite [ nSprite ] . xrepeat + 15 ;
2019-08-31 07:47:15 +00:00
}
}
else
{
int nAngle = ( sprite [ nSprite ] . ang + 256 ) - RandomSize ( 9 ) ;
if ( nVal )
{
2020-02-04 21:45:10 +00:00
sprite [ var_14 ] . xvel = Cos ( nAngle ) > > 5 ;
2019-08-31 07:47:15 +00:00
sprite [ var_14 ] . yvel = Sin ( nAngle ) > > 5 ;
}
else
{
2020-02-04 21:45:10 +00:00
sprite [ var_14 ] . xvel = Cos ( nAngle ) > > 6 ;
2019-08-31 07:47:15 +00:00
sprite [ var_14 ] . yvel = Sin ( nAngle ) > > 6 ;
}
sprite [ var_14 ] . zvel = - ( RandomSize ( 4 ) < < 7 ) ;
2020-02-04 21:45:10 +00:00
sprite [ var_14 ] . picnum = kTile985 + nVal ;
2019-08-31 07:47:15 +00:00
}
sprite [ var_14 ] . z = sprite [ nSprite ] . z ;
sprite [ var_14 ] . lotag = runlist_HeadRun ( ) + 1 ;
sprite [ var_14 ] . clipdist = 1 ;
sprite [ var_14 ] . hitag = 0 ;
2019-08-26 03:59:14 +00:00
// GrabTimeSlot(3);
2019-08-31 07:47:15 +00:00
sprite [ var_14 ] . extra = - 1 ;
sprite [ var_14 ] . owner = runlist_AddRunRec ( sprite [ var_14 ] . lotag - 1 , var_14 | 0x260000 ) ;
sprite [ var_14 ] . 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
}
2020-08-28 09:02:13 +00:00
void FuncSpark ( int a , int , int nRun )
2019-08-26 03:59:14 +00:00
{
2019-11-18 22:15:48 +00:00
int nSprite = RunData [ nRun ] . nVal ;
2019-08-31 07:47:15 +00:00
assert ( nSprite > = 0 & & nSprite < kMaxSprites ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nMessage = a & 0x7F0000 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nMessage ! = 0x20000 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . shade + = 3 ;
sprite [ nSprite ] . xrepeat - = 2 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( sprite [ nSprite ] . xrepeat > = 4 & & sprite [ nSprite ] . shade < = 100 )
{
sprite [ nSprite ] . 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
2019-11-18 22:15:48 +00:00
if ( sprite [ nSprite ] . picnum = = kTile986 & & ( sprite [ nSprite ] . xrepeat & 2 ) )
2019-08-31 07:47:15 +00:00
{
BuildSpark ( nSprite , 2 ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( sprite [ nSprite ] . picnum > = kTile3000 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . zvel + = 128 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nMov = movesprite ( nSprite , sprite [ nSprite ] . xvel < < 12 , sprite [ nSprite ] . yvel < < 12 , sprite [ nSprite ] . zvel , 2560 , - 2560 , CLIPMASK1 ) ;
if ( ! nMov ) {
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( sprite [ nSprite ] . zvel < = 0 ) {
return ;
}
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . xvel = 0 ;
2019-11-18 22:15:48 +00:00
sprite [ nSprite ] . yvel = 0 ;
sprite [ nSprite ] . zvel = 0 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( sprite [ nSprite ] . picnum > kTile3000 ) {
nSmokeSparks - - ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
runlist_DoSubRunRec ( sprite [ nSprite ] . owner ) ;
runlist_FreeRun ( sprite [ nSprite ] . lotag - 1 ) ;
runlist_SubRunRec ( sprite [ nSprite ] . hitag ) ;
mydeletesprite ( nSprite ) ;
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 ;
static int dword_1542FC = 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 ) ;
2020-08-25 22:49:25 +00:00
dword_1542FC = gameclock + 120 ;
2020-02-04 21:45:10 +00:00
nFinaleStage + + ;
2019-08-31 07:47:15 +00:00
}
}
else if ( nFinaleStage < = 2 )
{
2020-08-25 22:49:25 +00:00
if ( gameclock > = dword_1542FC )
2019-08-31 07:47:15 +00:00
{
PlayLocalSound ( StaticSound [ kSound77 ] , 0 ) ;
nFinaleStage + + ;
2020-08-25 22:49:25 +00:00
dword_1542FC = gameclock + 360 ;
2019-08-31 07:47:15 +00:00
}
}
2020-08-25 22:49:25 +00:00
else if ( nFinaleStage = = 3 & & gameclock > = dword_1542FC )
2019-08-31 07:47:15 +00:00
{
2020-08-22 08:03:21 +00:00
EndLevel = true ;
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
2019-08-31 07:47:15 +00:00
int nSprite = insertsprite ( nSector , 406 ) ;
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
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . x = xAvg ;
sprite [ nSprite ] . 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
// GrabTimeSlot(3);
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . 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?
int nRepeat = ( sprite [ nSprite ] . z - sector [ nSector ] . floorz ) > > 8 ;
if ( nRepeat > 255 ) {
nRepeat = 255 ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . xrepeat = nRepeat ;
sprite [ nSprite ] . cstat = 0x8000 ;
sprite [ nSprite ] . xvel = 0 ;
sprite [ nSprite ] . yvel = 0 ;
sprite [ nSprite ] . zvel = 0 ;
sprite [ nSprite ] . extra = - 1 ;
sprite [ nSprite ] . lotag = runlist_HeadRun ( ) + 1 ;
sprite [ nSprite ] . hitag = 0 ;
sprite [ nSprite ] . owner = runlist_AddRunRec ( sprite [ nSprite ] . lotag - 1 , nSprite | 0x250000 ) ;
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 ;
int i ;
v0 = 99 ;
v1 = 99 ;
while ( 1 )
{
if ( v0 ! = 100 )
{
for ( i = headspritestat [ v1 ] ; i ! = - 1 ; i = nextspritestat [ i ] )
{
runlist_DamageEnemy ( i , - 1 , 1600 ) ;
}
}
+ + v0 ;
+ + v1 ;
if ( v0 > 107 ) {
return ;
}
}
2019-08-26 03:59:14 +00:00
}
void ExplodeEnergyBlock ( int nSprite )
{
2019-08-31 07:47:15 +00:00
short nSector = sprite [ nSprite ] . 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 ;
sector [ nSector ] . floorz = sprite [ nSprite ] . z ;
2019-11-20 16:21:32 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . z = ( sprite [ nSprite ] . 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
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . cstat = 0 ;
sprite [ nSprite ] . 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
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . 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 + + )
{
sprite [ nSprite ] . 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 ;
2020-08-25 22:49:25 +00:00
lFinaleStart = gameclock ;
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
}
2019-11-18 22:15:48 +00:00
void FuncEnergyBlock ( int a , int nDamage , int nRun )
2019-08-26 03:59:14 +00:00
{
2019-08-31 07:47:15 +00:00
short nSprite = RunData [ nRun ] . nVal ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nMessage = a & 0x7F0000 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
switch ( nMessage )
{
case 0x20000 :
case 0x30000 :
case 0x90000 :
{
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 0xA0000 :
{
short nSector = sprite [ nSprite ] . sectnum ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( sector [ nSector ] . extra = = - 1 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nFloorZ = sector [ nSector ] . floorz ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sector [ nSector ] . floorz = sprite [ nSprite ] . z ;
sprite [ nSprite ] . z - = 256 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nDamage = runlist_CheckRadialDamage ( nSprite ) ;
2019-08-26 03:59:14 +00:00
2019-11-18 22:15:48 +00:00
// restore previous values
2019-08-31 07:47:15 +00:00
sector [ nSector ] . floorz = nFloorZ ;
sprite [ nSprite ] . z + = 256 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nDamage < = 0 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
// fall through to case 0x80000
2019-12-02 14:56:24 +00:00
fallthrough__ ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
case 0x80000 :
{
nDamage > > = 2 ;
if ( nDamage < = 0 ) {
return ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( nDamage < sprite [ nSprite ] . xrepeat )
{
sprite [ nSprite ] . xrepeat - = nDamage ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
int nSprite2 = insertsprite ( lasthitsect , 0 ) ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite2 ] . ang = a & 0xFFFF ;
sprite [ nSprite2 ] . x = lasthitx ;
sprite [ nSprite2 ] . y = lasthity ;
sprite [ nSprite2 ] . z = lasthitz ;
2019-08-26 03:59:14 +00:00
2020-02-04 21:45:10 +00:00
BuildSpark ( nSprite2 , 0 ) ; // shoot out blue orb when damaged
2019-08-31 07:47:15 +00:00
mydeletesprite ( nSprite2 ) ;
}
else
{
2020-02-04 21:45:10 +00:00
sprite [ nSprite ] . xrepeat = 0 ; // using xrepeat to store health
2019-08-31 07:47:15 +00:00
ExplodeEnergyBlock ( nSprite ) ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return ;
}
}
2019-08-26 03:59:14 +00:00
}
int BuildObject ( short nSprite , int nOjectType , int nHitag )
{
2019-08-31 07:47:15 +00:00
if ( ObjectCount > = kMaxObjects ) {
2019-11-24 09:03:19 +00:00
I_Error ( " Too many objects! \n " ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short nObject = ObjectCount ;
ObjectCount + + ;
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
sprite [ nSprite ] . cstat = ( sprite [ nSprite ] . cstat | 0x101 ) & 0x7FFD ;
sprite [ nSprite ] . xvel = 0 ;
sprite [ nSprite ] . yvel = 0 ;
sprite [ nSprite ] . zvel = 0 ;
sprite [ nSprite ] . extra = - 1 ;
sprite [ nSprite ] . lotag = runlist_HeadRun ( ) + 1 ;
sprite [ nSprite ] . hitag = 0 ;
sprite [ nSprite ] . owner = runlist_AddRunRec ( sprite [ nSprite ] . lotag - 1 , nObject | 0x170000 ) ;
2019-08-26 03:59:14 +00:00
// GrabTimeSlot(3);
2019-08-31 07:47:15 +00:00
if ( sprite [ nSprite ] . statnum = = kStatDestructibleSprite ) {
ObjectList [ nObject ] . nHealth = 4 ;
}
else {
ObjectList [ nObject ] . nHealth = 120 ;
}
ObjectList [ nObject ] . nSprite = nSprite ;
ObjectList [ nObject ] . field_4 = runlist_AddRunRec ( NewRun , nObject | 0x170000 ) ;
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
}
int nSprite2 = insertsprite ( sprite [ nSprite ] . sectnum , 0 ) ;
ObjectList [ nObject ] . field_10 = nSprite2 ;
sprite [ nSprite2 ] . cstat = 0x8000 ;
sprite [ nSprite2 ] . x = sprite [ nSprite ] . x ;
sprite [ nSprite2 ] . y = sprite [ nSprite ] . y ;
sprite [ nSprite2 ] . z = sprite [ nSprite ] . z ;
}
2019-12-02 21:19:27 +00:00
else
{
ObjectList [ nObject ] . field_0 = 0 ;
ObjectList [ nObject ] . field_8 = - 1 ;
if ( sprite [ nSprite ] . statnum = = kStatDestructibleSprite ) {
ObjectList [ nObject ] . field_10 = - 1 ;
}
else {
ObjectList [ nObject ] . field_10 = - nHitag ;
}
}
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 )
{
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . 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
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . cstat = 0x8000 ;
2019-09-21 15:47:55 +00:00
PlayFX2 ( StaticSound [ kSound78 ] , nSprite ) ;
2019-08-26 03:59:14 +00:00
}
void FuncObject ( int a , int b , int nRun )
{
2019-08-31 07:47:15 +00:00
short nObject = RunData [ nRun ] . nVal ;
short nSprite = ObjectList [ nObject ] . nSprite ;
short nStat = sprite [ nSprite ] . statnum ;
short bx = ObjectList [ nObject ] . field_8 ;
int nMessage = a & 0x7F0000 ;
switch ( nMessage )
{
default :
{
DebugOut ( " unknown msg %d for Object \n " , a & 0x7F0000 ) ;
return ;
}
case 0x30000 :
return ;
case 0x80000 :
{
if ( nStat > = 150 | | ObjectList [ nObject ] . nHealth < = 0 ) {
return ;
}
if ( nStat = = 98 )
{
D3PlayFX ( ( StaticSound [ kSound47 ] | 0x2000 ) | ( RandomSize ( 2 ) < < 9 ) , nSprite ) ;
return ;
}
ObjectList [ nObject ] . nHealth - = ( short ) b ;
if ( ObjectList [ nObject ] . nHealth > 0 ) {
return ;
}
if ( nStat = = kStatDestructibleSprite )
{
ExplodeScreen ( nSprite ) ;
}
else
{
ObjectList [ nObject ] . nHealth = - ( RandomSize ( 3 ) + 1 ) ;
}
return ;
}
case 0x90000 :
{
if ( bx > - 1 )
{
seq_PlotSequence ( a & 0xFFFF , bx , ObjectList [ nObject ] . field_0 , 1 ) ;
}
return ;
}
case 0xA0000 :
{
if ( ObjectList [ nObject ] . nHealth > 0 & & sprite [ nSprite ] . cstat & 0x101
& & ( nStat ! = kStatExplodeTarget
| | sprite [ nRadialSpr ] . statnum = = 201
2020-01-07 00:11:19 +00:00
| | ( nRadialBullet ! = 3 & & nRadialBullet > - 1 )
2019-08-31 07:47:15 +00:00
| | sprite [ nRadialSpr ] . statnum = = kStatExplodeTrigger ) )
{
int nDamage = runlist_CheckRadialDamage ( nSprite ) ;
if ( nDamage < = 0 ) {
return ;
}
2020-02-27 01:03:13 +00:00
if ( sprite [ nSprite ] . statnum ! = kStatAnubisDrum ) {
2019-08-31 07:47:15 +00:00
ObjectList [ nObject ] . nHealth - = nDamage ;
}
if ( sprite [ nSprite ] . statnum = = kStatExplodeTarget )
{
sprite [ nSprite ] . xvel = 0 ;
sprite [ nSprite ] . yvel = 0 ;
2019-11-20 16:21:32 +00:00
sprite [ nSprite ] . zvel = 0 ;
2019-08-31 07:47:15 +00:00
}
2020-02-27 01:03:13 +00:00
else if ( sprite [ nSprite ] . statnum ! = kStatAnubisDrum )
2019-08-31 07:47:15 +00:00
{
sprite [ nSprite ] . xvel > > = 1 ;
sprite [ nSprite ] . yvel > > = 1 ;
sprite [ nSprite ] . zvel > > = 1 ;
}
if ( ObjectList [ nObject ] . nHealth > 0 ) {
return ;
}
if ( sprite [ nSprite ] . statnum = = kStatExplodeTarget )
{
ObjectList [ nObject ] . nHealth = - 1 ;
short ax = ObjectList [ nObject ] . field_10 ;
if ( ax < 0 | | ObjectList [ ax ] . nHealth < = 0 ) {
return ;
}
ObjectList [ ax ] . nHealth = - 1 ;
}
else if ( sprite [ nSprite ] . statnum = = kStatDestructibleSprite )
{
ObjectList [ nObject ] . nHealth = 0 ;
ExplodeScreen ( nSprite ) ;
}
else
{
ObjectList [ nObject ] . nHealth = - ( RandomSize ( 4 ) + 1 ) ;
}
}
return ;
}
case 0x20000 :
{
if ( nStat = = 97 | | ( ! ( sprite [ nSprite ] . cstat & 0x101 ) ) ) {
return ;
}
if ( nStat ! = kStatExplodeTarget ) {
Gravity ( nSprite ) ;
}
// do animation
if ( bx ! = - 1 )
{
ObjectList [ nObject ] . field_0 + + ;
if ( ObjectList [ nObject ] . field_0 > = SeqSize [ bx ] ) {
ObjectList [ nObject ] . field_0 = 0 ;
}
sprite [ nSprite ] . picnum = seq_GetSeqPicnum2 ( bx , ObjectList [ nObject ] . field_0 ) ;
}
if ( ObjectList [ nObject ] . nHealth > = 0 ) {
goto FUNCOBJECT_GOTO ;
}
ObjectList [ nObject ] . nHealth + + ;
if ( ObjectList [ nObject ] . nHealth )
{
2019-08-26 03:59:14 +00:00
FUNCOBJECT_GOTO :
2019-08-31 07:47:15 +00:00
if ( nStat ! = kStatExplodeTarget )
{
int nMov = movesprite ( nSprite , sprite [ nSprite ] . xvel < < 6 , sprite [ nSprite ] . yvel < < 6 , sprite [ nSprite ] . zvel , 0 , 0 , CLIPMASK0 ) ;
if ( sprite [ nSprite ] . statnum = = kStatExplodeTrigger ) {
sprite [ nSprite ] . pal = 1 ;
}
if ( nMov & 0x20000 )
{
sprite [ nSprite ] . xvel - = sprite [ nSprite ] . xvel > > 3 ;
sprite [ nSprite ] . yvel - = sprite [ nSprite ] . yvel > > 3 ;
}
if ( ( ( nMov & 0xC000 ) > 0x8000 ) & & ( ( nMov & 0xC000 ) = = 0xC000 ) )
{
sprite [ nSprite ] . yvel = 0 ;
sprite [ nSprite ] . xvel = 0 ;
}
}
return ;
}
else
{
int var_18 ;
// red branch
if ( ( nStat = = kStatExplodeTarget ) | | ( sprite [ nSprite ] . z < sector [ sprite [ nSprite ] . sectnum ] . floorz ) )
{
var_18 = 36 ;
}
else
{
var_18 = 34 ;
}
AddFlash ( sprite [ nSprite ] . sectnum , sprite [ nSprite ] . x , sprite [ nSprite ] . y , sprite [ nSprite ] . z , 128 ) ;
BuildAnim ( - 1 , var_18 , 0 , sprite [ nSprite ] . x , sprite [ nSprite ] . y , sector [ sprite [ nSprite ] . sectnum ] . floorz , sprite [ nSprite ] . sectnum , 240 , 4 ) ;
2019-08-26 03:59:14 +00:00
// int edi = nSprite | 0x4000;
2019-08-31 07:47:15 +00:00
if ( nStat = = kStatExplodeTrigger )
{
for ( int i = 4 ; i < 8 ; i + + ) {
BuildCreatureChunk ( nSprite | 0x4000 , seq_GetSeqPicnum ( kSeqFirePot , ( i > > 2 ) + 1 , 0 ) ) ;
}
runlist_RadialDamageEnemy ( nSprite , 200 , 20 ) ;
}
else if ( nStat = = kStatExplodeTarget )
{
for ( int i = 0 ; i < 8 ; i + + ) {
BuildCreatureChunk ( nSprite | 0x4000 , seq_GetSeqPicnum ( kSeqFirePot , ( i > > 1 ) + 3 , 0 ) ) ;
}
}
2020-08-23 14:24:54 +00:00
if ( currentLevel - > levelNumber < = 20 | | nStat ! = kStatExplodeTrigger )
2019-08-31 07:47:15 +00:00
{
runlist_SubRunRec ( sprite [ nSprite ] . owner ) ;
runlist_SubRunRec ( ObjectList [ nObject ] . field_4 ) ;
mydeletesprite ( nSprite ) ;
return ;
}
else
{
StartRegenerate ( nSprite ) ;
ObjectList [ nObject ] . nHealth = 120 ;
sprite [ nSprite ] . x = sprite [ ObjectList [ nObject ] . field_10 ] . x ;
sprite [ nSprite ] . y = sprite [ ObjectList [ nObject ] . field_10 ] . y ;
sprite [ nSprite ] . z = sprite [ ObjectList [ nObject ] . field_10 ] . z ;
mychangespritesect ( nSprite , sprite [ ObjectList [ nObject ] . field_10 ] . sectnum ) ;
return ;
}
}
}
}
2019-08-26 03:59:14 +00:00
}
void BuildDrip ( int nSprite )
{
2019-08-31 07:47:15 +00:00
if ( nDrips > = kMaxDrips ) {
2019-11-24 09:03:19 +00:00
I_Error ( " Too many drips! \n " ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sDrip [ nDrips ] . nSprite = nSprite ;
sDrip [ nDrips ] . field_2 = RandomSize ( 8 ) + 90 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
nDrips + + ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sprite [ nSprite ] . cstat = 0x8000u ;
2019-08-26 03:59:14 +00:00
}
void DoDrips ( )
{
2019-08-31 07:47:15 +00:00
int i ;
for ( i = 0 ; i < nDrips ; i + + )
{
sDrip [ i ] . field_2 - - ;
if ( sDrip [ i ] . field_2 < = 0 )
{
short nSprite = sDrip [ i ] . nSprite ;
short nSeqOffset = SeqOffsets [ kSeqDrips ] ;
if ( ! ( SectFlag [ sprite [ nSprite ] . sectnum ] & kSectLava ) ) {
nSeqOffset + + ;
}
seq_MoveSequence ( nSprite , nSeqOffset , RandomSize ( 2 ) % SeqSize [ nSeqOffset ] ) ;
sDrip [ i ] . field_2 = RandomSize ( 8 ) + 90 ;
}
}
for ( i = 0 ; i < nBobs ; i + + )
{
sBob [ i ] . field_2 + = 4 ;
int edx = Sin ( sBob [ i ] . field_2 < < 3 ) > > 4 ;
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 ;
2019-08-26 03:59:14 +00:00
// int var_14 = nSector;
// int edi = edx;
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < nBobs ; i + + )
{
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 )
{
2019-08-31 07:47:15 +00:00
if ( nBobs > = kMaxBobs ) {
2019-11-24 09:03:19 +00:00
I_Error ( " Too many bobs! \n " ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
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 ;
sBobID [ nBobs ] = nHitag ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sBob [ nBobs ] . nSector = nSector ;
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
2019-08-31 07:47:15 +00:00
nBobs + + ;
2019-08-26 03:59:14 +00:00
}
// Confirmed 100% correct with original .exe
int FindTrail ( int nVal )
{
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < nTrails ; i + + )
{
if ( sTrail [ i ] . field_2 = = nVal )
return i ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sTrail [ nTrails ] . field_2 = nVal ;
sTrail [ nTrails ] . field_0 = - 1 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
return nTrails + + ;
2019-08-26 03:59:14 +00:00
}
// ok ?
void ProcessTrailSprite ( int nSprite , int nLotag , int nHitag )
{
2019-08-31 07:47:15 +00:00
if ( nTrailPoints > = 100 ) {
2019-11-24 09:03:19 +00:00
I_Error ( " Too many trail point sprites (900-949)... increase MAX_TRAILPOINTS \n " ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
short nPoint = nTrailPoints ;
nTrailPoints + + ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
sTrailPoint [ nPoint ] . x = sprite [ nSprite ] . x ;
sTrailPoint [ nPoint ] . y = sprite [ nSprite ] . 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
2019-08-31 07:47:15 +00:00
nTrailPointVal [ nPoint ] = 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
2019-11-02 18:29:18 +00:00
nTrailPointNext [ nPoint ] = - 1 ;
nTrailPointPrev [ nPoint ] = - 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 )
{
if ( nTrailPointVal [ field0 ] > var_14 )
{
nTrailPointPrev [ nPoint ] = nTrailPointPrev [ field0 ] ;
nTrailPointPrev [ field0 ] = nPoint ;
nTrailPointNext [ nPoint ] = 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 ;
field0 = nTrailPointNext [ field0 ] ;
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
if ( field0 = = - 1 )
{
nTrailPointNext [ ecx ] = nPoint ;
nTrailPointPrev [ nPoint ] = ecx ;
nTrailPointNext [ nPoint ] = - 1 ;
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
if ( nMoveSects > = kMaxMoveSects ) {
2019-11-24 09:03:19 +00:00
I_Error ( " Too many moving sectors \n " ) ;
2019-08-31 07:47:15 +00:00
}
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
CreatePushBlock ( 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
2019-08-31 07:47:15 +00:00
sMoveDir [ nMoveSects ] = 1 ;
2019-08-26 03:59:14 +00:00
2019-08-31 07:47:15 +00:00
MoveSect * pMoveSect = & sMoveSect [ nMoveSects ] ;
nMoveSects + + ;
2019-08-26 03:59:14 +00:00
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 ( )
{
2019-08-31 07:47:15 +00:00
for ( int i = 0 ; i < nMoveSects ; i + + )
{
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 ;
BlockInfo * pBlockInfo = & sBlockInfo [ nBlock ] ;
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 )
{
sMoveDir [ i ] = - sMoveDir [ i ] ;
if ( sMoveDir [ i ] > 0 )
{
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 ;
2019-08-26 03:59:14 +00:00
// TrailPoint *pTrail = &sTrailPoint[nTrail];
2019-08-31 07:47:15 +00:00
// loc_23872:
int nAngle = GetMyAngle ( sTrailPoint [ nTrail ] . x - pBlockInfo - > x , sTrailPoint [ nTrail ] . y - pBlockInfo - > y ) ;
int nXVel = ( Sin ( nAngle + 512 ) < < 4 ) * sMoveSect [ i ] . field_10 ;
int nYVel = ( Sin ( nAngle ) < < 4 ) * sMoveSect [ i ] . field_10 ;
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 ;
if ( sMoveDir [ i ] > 0 )
{
sMoveSect [ i ] . nTrailPoint = nTrailPointNext [ sMoveSect [ i ] . nTrailPoint ] ;
}
else
{
sMoveSect [ i ] . nTrailPoint = nTrailPointPrev [ sMoveSect [ i ] . nTrailPoint ] ;
}
}
}
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 ;
if ( sMoveDir [ i ] > 0 )
{
2019-11-20 16:21:32 +00:00
sMoveSect [ i ] . nTrailPoint = nTrailPointNext [ sMoveSect [ i ] . nTrailPoint ] ;
2019-08-31 07:47:15 +00:00
}
else
{
sMoveSect [ i ] . nTrailPoint = nTrailPointPrev [ sMoveSect [ i ] . nTrailPoint ] ;
}
}
// 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 ( )
{
2019-08-31 07:47:15 +00:00
int i , j ;
for ( i = 0 ; i < nMoveSects ; i + + )
{
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 ;
for ( j = 0 ; j < nMoveSects ; j + + )
{
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 ;
}
}
}
}
for ( i = 0 ; i < nBobs ; i + + )
{
if ( sBob [ i ] . field_3 = = 0 )
{
int bobID = sBobID [ i ] ;
for ( j = 0 ; j < nBobs ; j + + )
{
if ( j ! = i )
{
if ( sBob [ i ] . field_3 ! = 0 & & sBobID [ j ] = = bobID ) {
SnapSectors ( i , j , 0 ) ;
}
}
}
}
}
2020-08-23 14:24:54 +00:00
if ( currentLevel - > levelNumber ! = kMap20 )
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 ) ;
sprite [ nSprite ] . cstat = 0x8000 ;
}
nWall + + ;
}
}
for ( i = 0 ; i < kMaxSprites ; i + + )
{
if ( sprite [ i ] . statnum < kMaxStatus & & sprite [ i ] . picnum = = kTile3603 )
{
changespritestat ( i , 407 ) ;
sprite [ i ] . pal = 1 ;
}
}
}
// esi is i
for ( i = 0 ; i < ObjectCount ; i + + )
{
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 ;
// ecx, ebx is j
for ( j = 0 ; j < ObjectCount ; j + + )
{
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
static SavegameHelper sgh ( " objects " ,
SA ( sTrap ) ,
SA ( sBob ) ,
SA ( sTrail ) ,
SA ( sTrailPoint ) ,
SA ( Elevator ) ,
SA ( ObjectList ) ,
SA ( sMoveSect ) ,
SA ( SlideData ) ,
SA ( sMoveDir ) ,
SA ( WallFace ) ,
SA ( SlideData2 ) ,
SA ( PointList ) ,
SA ( nTrapInterval ) ,
SA ( sBobID ) ,
SA ( PointFree ) ,
SA ( SlideFree ) ,
SA ( nTrailPointVal ) ,
SA ( nTrailPointPrev ) ,
SA ( nTrailPointNext ) ,
SA ( sDrip ) ,
SV ( PointCount ) ,
SV ( SlideCount ) ,
SV ( ElevCount ) ,
SV ( WallFaceCount ) ,
SV ( lFinaleStart ) ,
SV ( nTrailPoints ) ,
SV ( nEnergyBlocks ) ,
SV ( nMoveSects ) ,
SV ( nFinaleStage ) ,
SV ( nTrails ) ,
SV ( nTraps ) ,
SV ( nFinaleSpr ) ,
SV ( ObjectCount ) ,
SV ( nDrips ) ,
SV ( nBobs ) ,
SV ( nDronePitch ) ,
SV ( nSmokeSparks ) ,
nullptr ) ;
2019-11-22 23:11:37 +00:00
END_PS_NS