2020-08-02 17:43:45 +00:00
//-------------------------------------------------------------------------
/*
Copyright ( C ) 2010 - 2019 EDuke32 developers and contributors
Copyright ( C ) 2019 Nuke . YKT
This file is part of NBlood .
NBlood 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 .
*/
//-------------------------------------------------------------------------
# include "ns.h" // Must come before everything else!
# include <stdlib.h>
# include <string.h>
# include "compat.h"
# include "build.h"
# include "pragmas.h"
# include "mmulti.h"
# include "v_font.h"
# include "endgame.h"
# include "aistate.h"
# include "loadsave.h"
# include "sectorfx.h"
# include "choke.h"
# include "view.h"
# include "nnexts.h"
# include "zstring.h"
# include "menu.h"
# include "gstrings.h"
# include "v_2ddrawer.h"
# include "v_video.h"
# include "v_font.h"
# include "glbackend/glbackend.h"
BEGIN_BLD_NS
2020-08-26 15:12:48 +00:00
void fakePlayerProcess ( PLAYER * pPlayer , InputPacket * pInput ) ;
2020-08-02 17:43:45 +00:00
void fakeActProcessSprites ( void ) ;
bool gPrediction = true ;
VIEW predict , predictOld ;
static VIEW predictFifo [ 256 ] ;
void viewInitializePrediction ( void )
{
predict . at30 = gMe - > q16ang ;
2020-10-07 06:16:58 +00:00
predict . at24 = gMe - > horizon . horiz ;
predict . at28 = gMe - > horizon . horizoff ;
2020-08-02 17:43:45 +00:00
predict . at2c = gMe - > slope ;
predict . at6f = gMe - > cantJump ;
predict . at70 = gMe - > isRunning ;
predict . at72 = gMe - > isUnderwater ;
2020-08-28 23:19:48 +00:00
predict . at71 = ! ! ( gMe - > input . actions & SB_JUMP ) ;
2020-08-02 17:43:45 +00:00
predict . at50 = gMe - > pSprite - > x ;
predict . at54 = gMe - > pSprite - > y ;
predict . at58 = gMe - > pSprite - > z ;
predict . at68 = gMe - > pSprite - > sectnum ;
predict . at73 = gMe - > pSprite - > flags ;
predict . at5c = xvel [ gMe - > pSprite - > index ] ;
predict . at60 = yvel [ gMe - > pSprite - > index ] ;
predict . at64 = zvel [ gMe - > pSprite - > index ] ;
predict . at6a = gMe - > pXSprite - > height ;
predict . at48 = gMe - > posture ;
predict . at4c = gMe - > spin ;
2020-08-28 23:19:48 +00:00
predict . at6e = ! ! ( gMe - > input . actions & SB_CENTERVIEW ) ;
2020-08-02 17:43:45 +00:00
memcpy ( & predict . at75 , & gSpriteHit [ gMe - > pSprite - > extra ] , sizeof ( SPRITEHIT ) ) ;
2020-09-01 19:27:32 +00:00
predict . TotalKills = gMe - > bobPhase ;
predict . Kills = gMe - > bobAmp ;
2020-08-02 17:43:45 +00:00
predict . at8 = gMe - > bobHeight ;
predict . atc = gMe - > bobWidth ;
predict . at10 = gMe - > swayPhase ;
predict . at14 = gMe - > swayAmp ;
predict . at18 = gMe - > swayHeight ;
predict . at1c = gMe - > swayWidth ;
predict . at34 = gMe - > zWeapon - gMe - > zView - ( 12 < < 8 ) ;
predict . at38 = gMe - > zView ;
predict . at3c = gMe - > zViewVel ;
predict . at40 = gMe - > zWeapon ;
predict . at44 = gMe - > zWeaponVel ;
predictOld = predict ;
}
2020-08-26 15:12:48 +00:00
void viewUpdatePrediction ( InputPacket * pInput )
2020-08-02 17:43:45 +00:00
{
predictOld = predict ;
short bakCstat = gMe - > pSprite - > cstat ;
gMe - > pSprite - > cstat = 0 ;
fakePlayerProcess ( gMe , pInput ) ;
fakeActProcessSprites ( ) ;
gMe - > pSprite - > cstat = bakCstat ;
2020-09-01 21:34:04 +00:00
//predictFifo[gPredictTail&255] = predict;
//gPredictTail++;
2020-08-02 17:43:45 +00:00
}
static void sub_158B4 ( PLAYER * pPlayer )
{
predict . at38 = predict . at58 - pPlayer - > pPosture [ pPlayer - > lifeMode ] [ predict . at48 ] . eyeAboveZ ;
predict . at40 = predict . at58 - pPlayer - > pPosture [ pPlayer - > lifeMode ] [ predict . at48 ] . weaponAboveZ ;
}
2020-08-26 15:12:48 +00:00
static void fakeProcessInput ( PLAYER * pPlayer , InputPacket * pInput )
2020-08-02 17:43:45 +00:00
{
POSTURE * pPosture = & pPlayer - > pPosture [ pPlayer - > lifeMode ] [ predict . at48 ] ;
2020-08-28 23:19:48 +00:00
predict . at70 = ! ! ( gMe - > input . actions & SB_RUN ) ;
predict . at71 = ! ! ( gMe - > input . actions & SB_JUMP ) ;
2020-08-02 17:43:45 +00:00
if ( predict . at48 = = 1 )
{
2020-09-01 13:00:35 +00:00
int x = Cos ( FixedToInt ( predict . at30 ) ) ;
int y = Sin ( FixedToInt ( predict . at30 ) ) ;
2020-08-26 14:54:13 +00:00
if ( pInput - > fvel )
2020-08-02 17:43:45 +00:00
{
2020-08-26 14:54:13 +00:00
int forward = pInput - > fvel ;
2020-08-02 17:43:45 +00:00
if ( forward > 0 )
forward = mulscale8 ( pPosture - > frontAccel , forward ) ;
else
forward = mulscale8 ( pPosture - > backAccel , forward ) ;
predict . at5c + = mulscale30 ( forward , x ) ;
predict . at60 + = mulscale30 ( forward , y ) ;
}
2020-08-26 14:54:13 +00:00
if ( pInput - > svel )
2020-08-02 17:43:45 +00:00
{
2020-08-26 14:54:13 +00:00
int strafe = pInput - > svel ;
2020-08-02 17:43:45 +00:00
strafe = mulscale8 ( pPosture - > sideAccel , strafe ) ;
predict . at5c + = mulscale30 ( strafe , y ) ;
predict . at60 - = mulscale30 ( strafe , x ) ;
}
}
else if ( predict . at6a < 0x100 )
{
int speed = 0x10000 ;
if ( predict . at6a > 0 )
speed - = divscale16 ( predict . at6a , 0x100 ) ;
2020-09-01 13:00:35 +00:00
int x = Cos ( FixedToInt ( predict . at30 ) ) ;
int y = Sin ( FixedToInt ( predict . at30 ) ) ;
2020-08-26 14:54:13 +00:00
if ( pInput - > fvel )
2020-08-02 17:43:45 +00:00
{
2020-08-26 14:54:13 +00:00
int forward = pInput - > fvel ;
2020-08-02 17:43:45 +00:00
if ( forward > 0 )
forward = mulscale8 ( pPosture - > frontAccel , forward ) ;
else
forward = mulscale8 ( pPosture - > backAccel , forward ) ;
if ( predict . at6a )
forward = mulscale16 ( forward , speed ) ;
predict . at5c + = mulscale30 ( forward , x ) ;
predict . at60 + = mulscale30 ( forward , y ) ;
}
2020-08-26 14:54:13 +00:00
if ( pInput - > svel )
2020-08-02 17:43:45 +00:00
{
2020-08-26 14:54:13 +00:00
int strafe = pInput - > svel ;
2020-08-02 17:43:45 +00:00
strafe = mulscale8 ( pPosture - > sideAccel , strafe ) ;
if ( predict . at6a )
strafe = mulscale16 ( strafe , speed ) ;
predict . at5c + = mulscale30 ( strafe , y ) ;
predict . at60 - = mulscale30 ( strafe , x ) ;
}
}
2020-08-26 14:54:13 +00:00
if ( pInput - > q16avel )
predict . at30 = ( predict . at30 + pInput - > q16avel ) & 0x7ffffff ;
2020-08-28 23:19:48 +00:00
if ( pInput - > actions & SB_TURNAROUND )
2020-08-02 17:43:45 +00:00
if ( ! predict . at4c )
predict . at4c = - 1024 ;
if ( predict . at4c < 0 )
{
int speed ;
if ( predict . at48 = = 1 )
speed = 64 ;
else
speed = 128 ;
predict . at4c = min ( predict . at4c + speed , 0 ) ;
2020-09-01 13:00:35 +00:00
predict . at30 + = IntToFixed ( speed ) ;
2020-08-02 17:43:45 +00:00
}
if ( ! predict . at71 )
predict . at6f = 0 ;
switch ( predict . at48 )
{
case 1 :
if ( predict . at71 )
predict . at64 - = pPosture - > normalJumpZ ; //0x5b05;
2020-08-28 23:19:48 +00:00
if ( pInput - > actions & SB_CROUCH )
2020-08-02 17:43:45 +00:00
predict . at64 + = pPosture - > normalJumpZ ; //0x5b05;
break ;
case 2 :
2020-08-28 23:19:48 +00:00
if ( ! ( pInput - > actions & SB_CROUCH ) )
2020-08-02 17:43:45 +00:00
predict . at48 = 0 ;
break ;
default :
if ( ! predict . at6f & & predict . at71 & & predict . at6a = = 0 ) {
if ( packItemActive ( pPlayer , 4 ) ) predict . at64 = pPosture - > pwupJumpZ ; //-0x175555;
else predict . at64 = pPosture - > normalJumpZ ; //-0xbaaaa;
predict . at6f = 1 ;
}
2020-08-28 23:19:48 +00:00
if ( pInput - > actions & SB_CROUCH )
2020-08-02 17:43:45 +00:00
predict . at48 = 2 ;
break ;
}
2020-09-16 00:06:50 +00:00
2020-10-07 06:16:58 +00:00
#if 0
2020-09-16 00:06:50 +00:00
if ( predict . at6e & & ! ( pInput - > actions & ( SB_LOOK_UP | SB_LOOK_DOWN ) ) )
2020-08-02 17:43:45 +00:00
{
if ( predict . at20 < 0 )
2020-09-01 13:00:35 +00:00
predict . at20 = min ( predict . at20 + IntToFixed ( 4 ) , 0 ) ;
2020-08-02 17:43:45 +00:00
if ( predict . at20 > 0 )
2020-09-01 13:00:35 +00:00
predict . at20 = max ( predict . at20 - IntToFixed ( 4 ) , 0 ) ;
2020-08-02 17:43:45 +00:00
if ( predict . at20 = = 0 )
predict . at6e = 0 ;
}
else
{
2020-09-16 00:06:50 +00:00
if ( pInput - > actions & SB_LOOK_UP )
2020-09-01 13:00:35 +00:00
predict . at20 = min ( predict . at20 + IntToFixed ( 4 ) , IntToFixed ( 60 ) ) ;
2020-09-16 00:06:50 +00:00
if ( pInput - > actions & SB_LOOK_DOWN )
2020-09-01 13:00:35 +00:00
predict . at20 = max ( predict . at20 - IntToFixed ( 4 ) , IntToFixed ( - 60 ) ) ;
2020-08-02 17:43:45 +00:00
}
2020-09-16 00:06:50 +00:00
predict . at20 = clamp ( predict . at20 + pInput - > q16horz , IntToFixed ( - 60 ) , IntToFixed ( 60 ) ) ;
2020-08-02 17:43:45 +00:00
if ( predict . at20 > 0 )
2020-09-16 02:31:32 +00:00
predict . at24 = FloatToFixed ( fmulscale30 ( 120. , Sinf ( FixedToFloat ( predict . at20 ) * 8. ) ) ) ;
2020-08-02 17:43:45 +00:00
else if ( predict . at20 < 0 )
2020-09-16 02:31:32 +00:00
predict . at24 = FloatToFixed ( fmulscale30 ( 180. , Sinf ( FixedToFloat ( predict . at20 ) * 8. ) ) ) ;
2020-08-02 17:43:45 +00:00
else
predict . at24 = 0 ;
2020-10-07 06:16:58 +00:00
# endif
2020-08-02 17:43:45 +00:00
int nSector = predict . at68 ;
int florhit = predict . at75 . florhit & 0xc000 ;
char va ;
if ( predict . at6a < 16 & & ( florhit = = 0x4000 | | florhit = = 0 ) )
va = 1 ;
else
va = 0 ;
if ( va & & ( sector [ nSector ] . floorstat & 2 ) ! = 0 )
{
int z1 = getflorzofslope ( nSector , predict . at50 , predict . at54 ) ;
2020-09-01 13:00:35 +00:00
int x2 = predict . at50 + mulscale30 ( 64 , Cos ( FixedToInt ( predict . at30 ) ) ) ;
int y2 = predict . at54 + mulscale30 ( 64 , Sin ( FixedToInt ( predict . at30 ) ) ) ;
2020-08-02 17:43:45 +00:00
short nSector2 = nSector ;
updatesector ( x2 , y2 , & nSector2 ) ;
if ( nSector2 = = nSector )
{
int z2 = getflorzofslope ( nSector2 , x2 , y2 ) ;
2020-10-07 06:16:58 +00:00
predict . at28 = q16horiz ( interpolate ( predict . at28 . asq16 ( ) , IntToFixed ( z1 - z2 ) > > 3 , 0x4000 ) ) ;
2020-08-02 17:43:45 +00:00
}
}
else
{
2020-10-07 06:16:58 +00:00
predict . at28 = q16horiz ( interpolate ( predict . at28 . asq16 ( ) , 0 , 0x4000 ) ) ;
if ( klabs ( predict . at28 . asq16 ( ) ) < 4 )
predict . at28 = q16horiz ( 0 ) ;
2020-08-02 17:43:45 +00:00
}
2020-10-07 06:16:58 +00:00
predict . at2c = - predict . at24 . asq16 ( ) > > 9 ;
2020-08-02 17:43:45 +00:00
}
2020-08-26 15:12:48 +00:00
void fakePlayerProcess ( PLAYER * pPlayer , InputPacket * pInput )
2020-08-02 17:43:45 +00:00
{
spritetype * pSprite = pPlayer - > pSprite ;
XSPRITE * pXSprite = pPlayer - > pXSprite ;
POSTURE * pPosture = & pPlayer - > pPosture [ pPlayer - > lifeMode ] [ predict . at48 ] ;
int top , bottom ;
GetSpriteExtents ( pSprite , & top , & bottom ) ;
top + = predict . at58 - pSprite - > z ;
bottom + = predict . at58 - pSprite - > z ;
int dzb = ( bottom - predict . at58 ) / 4 ;
int dzt = ( predict . at58 - top ) / 4 ;
int dw = pSprite - > clipdist < < 2 ;
short nSector = predict . at68 ;
if ( ! gNoClip )
{
pushmove_old ( ( int32_t * ) & predict . at50 , ( int32_t * ) & predict . at54 , ( int32_t * ) & predict . at58 , & predict . at68 , dw , dzt , dzb , CLIPMASK0 ) ;
if ( predict . at68 = = - 1 )
predict . at68 = nSector ;
}
fakeProcessInput ( pPlayer , pInput ) ;
int nSpeed = approxDist ( predict . at5c , predict . at60 ) ;
predict . at3c = interpolate ( predict . at3c , predict . at64 , 0x7000 ) ;
int dz = predict . at58 - pPosture - > eyeAboveZ - predict . at38 ;
if ( dz > 0 )
predict . at3c + = mulscale16 ( dz < < 8 , 0xa000 ) ;
else
predict . at3c + = mulscale16 ( dz < < 8 , 0x1800 ) ;
predict . at38 + = predict . at3c > > 8 ;
predict . at44 = interpolate ( predict . at44 , predict . at64 , 0x5000 ) ;
dz = predict . at58 - pPosture - > weaponAboveZ - predict . at40 ;
if ( dz > 0 )
predict . at44 + = mulscale16 ( dz < < 8 , 0x8000 ) ;
else
predict . at44 + = mulscale16 ( dz < < 8 , 0xc00 ) ;
predict . at40 + = predict . at44 > > 8 ;
predict . at34 = predict . at40 - predict . at38 - ( 12 < < 8 ) ;
2020-09-01 19:27:32 +00:00
predict . TotalKills = ClipLow ( predict . TotalKills - 4 , 0 ) ;
2020-08-02 17:43:45 +00:00
2020-09-01 13:00:35 +00:00
nSpeed > > = FRACBITS ;
2020-08-02 17:43:45 +00:00
if ( predict . at48 = = 1 )
{
2020-09-01 19:27:32 +00:00
predict . Kills = ( predict . Kills + 17 ) & 2047 ;
2020-08-02 17:43:45 +00:00
predict . at14 = ( predict . at14 + 17 ) & 2047 ;
2020-09-01 19:27:32 +00:00
predict . at8 = mulscale30 ( 10 * pPosture - > bobV , Sin ( predict . Kills * 2 ) ) ;
predict . atc = mulscale30 ( predict . TotalKills * pPosture - > bobH , Sin ( predict . Kills - 256 ) ) ;
predict . at18 = mulscale30 ( predict . TotalKills * pPosture - > swayV , Sin ( predict . at14 * 2 ) ) ;
predict . at1c = mulscale30 ( predict . TotalKills * pPosture - > swayH , Sin ( predict . at14 - 0x155 ) ) ;
2020-08-02 17:43:45 +00:00
}
else
{
if ( pXSprite - > height < 256 )
{
2020-09-01 19:27:32 +00:00
predict . Kills = ( predict . Kills + ( pPosture - > pace [ predict . at70 ] * 4 ) ) & 2047 ;
2020-08-02 17:43:45 +00:00
predict . at14 = ( predict . at14 + ( pPosture - > pace [ predict . at70 ] * 4 ) / 2 ) & 2047 ;
if ( predict . at70 )
{
2020-09-01 19:27:32 +00:00
if ( predict . TotalKills < 60 )
predict . TotalKills = ClipHigh ( predict . TotalKills + nSpeed , 60 ) ;
2020-08-02 17:43:45 +00:00
}
else
{
2020-09-01 19:27:32 +00:00
if ( predict . TotalKills < 30 )
predict . TotalKills = ClipHigh ( predict . TotalKills + nSpeed , 30 ) ;
2020-08-02 17:43:45 +00:00
}
}
2020-09-01 19:27:32 +00:00
predict . at8 = mulscale30 ( predict . TotalKills * pPosture - > bobV , Sin ( predict . Kills * 2 ) ) ;
predict . atc = mulscale30 ( predict . TotalKills * pPosture - > bobH , Sin ( predict . Kills - 256 ) ) ;
predict . at18 = mulscale30 ( predict . TotalKills * pPosture - > swayV , Sin ( predict . at14 * 2 ) ) ;
predict . at1c = mulscale30 ( predict . TotalKills * pPosture - > swayH , Sin ( predict . at14 - 0x155 ) ) ;
2020-08-02 17:43:45 +00:00
}
if ( ! pXSprite - > health )
return ;
predict . at72 = 0 ;
if ( predict . at48 = = 1 )
{
predict . at72 = 1 ;
int nSector = predict . at68 ;
int nLink = gLowerLink [ nSector ] ;
if ( nLink > 0 & & ( sprite [ nLink ] . type = = kMarkerLowGoo | | sprite [ nLink ] . type = = kMarkerLowWater ) )
{
if ( getceilzofslope ( nSector , predict . at50 , predict . at54 ) > predict . at38 )
predict . at72 = 0 ;
}
}
}
static void fakeMoveDude ( spritetype * pSprite )
{
PLAYER * pPlayer = NULL ;
int bottom , top ;
if ( IsPlayerSprite ( pSprite ) )
pPlayer = & gPlayer [ pSprite - > type - kDudePlayer1 ] ;
dassert ( pSprite - > type > = kDudeBase & & pSprite - > type < kDudeMax ) ;
GetSpriteExtents ( pSprite , & top , & bottom ) ;
top + = predict . at58 - pSprite - > z ;
bottom + = predict . at58 - pSprite - > z ;
int bz = ( bottom - predict . at58 ) / 4 ;
int tz = ( predict . at58 - top ) / 4 ;
int wd = pSprite - > clipdist * 4 ;
int nSector = predict . at68 ;
dassert ( nSector > = 0 & & nSector < kMaxSectors ) ;
if ( predict . at5c | | predict . at60 )
{
if ( pPlayer & & gNoClip )
{
predict . at50 + = predict . at5c > > 12 ;
predict . at54 + = predict . at60 > > 12 ;
if ( ! FindSector ( predict . at50 , predict . at54 , & nSector ) )
nSector = predict . at68 ;
}
else
{
short bakCstat = pSprite - > cstat ;
pSprite - > cstat & = ~ 257 ;
predict . at75 . hit = ClipMove ( & predict . at50 , & predict . at54 , & predict . at58 , & nSector , predict . at5c > > 12 , predict . at60 > > 12 , wd , tz , bz , CLIPMASK0 ) ;
if ( nSector = = - 1 )
nSector = predict . at68 ;
if ( sector [ nSector ] . type > = kSectorPath & & sector [ nSector ] . type < = kSectorRotate )
{
short nSector2 = nSector ;
pushmove_old ( ( int32_t * ) & predict . at50 , ( int32_t * ) & predict . at54 , ( int32_t * ) & predict . at58 , & nSector2 , wd , tz , bz , CLIPMASK0 ) ;
if ( nSector2 ! = - 1 )
nSector = nSector2 ;
}
dassert ( nSector > = 0 ) ;
pSprite - > cstat = bakCstat ;
}
switch ( predict . at75 . hit & 0xc000 )
{
case 0x8000 :
{
int nHitWall = predict . at75 . hit & 0x3fff ;
walltype * pHitWall = & wall [ nHitWall ] ;
if ( pHitWall - > nextsector ! = - 1 )
{
sectortype * pHitSector = & sector [ pHitWall - > nextsector ] ;
if ( top < pHitSector - > ceilingz | | bottom > pHitSector - > floorz )
{
// ???
}
}
actWallBounceVector ( & predict . at5c , & predict . at60 , nHitWall , 0 ) ;
break ;
}
}
}
if ( predict . at68 ! = nSector )
{
dassert ( nSector > = 0 & & nSector < kMaxSectors ) ;
predict . at68 = nSector ;
}
char bUnderwater = 0 ;
char bDepth = 0 ;
int nXSector = sector [ nSector ] . extra ;
if ( nXSector > 0 )
{
XSECTOR * pXSector = & xsector [ nXSector ] ;
if ( pXSector - > Underwater )
bUnderwater = 1 ;
if ( pXSector - > Depth )
bDepth = 1 ;
}
int nUpperLink = gUpperLink [ nSector ] ;
int nLowerLink = gLowerLink [ nSector ] ;
if ( nUpperLink > = 0 & & ( sprite [ nUpperLink ] . type = = kMarkerUpWater | | sprite [ nUpperLink ] . type = = kMarkerUpGoo ) )
bDepth = 1 ;
if ( nLowerLink > = 0 & & ( sprite [ nLowerLink ] . type = = kMarkerLowWater | | sprite [ nLowerLink ] . type = = kMarkerLowGoo ) )
bDepth = 1 ;
if ( pPlayer )
wd + = 16 ;
if ( predict . at64 )
predict . at58 + = predict . at64 > > 8 ;
2020-10-02 20:14:01 +00:00
static_assert ( sizeof ( tspritetype ) = = sizeof ( spritetype ) ) ;
tspritetype pSpriteBak ; memcpy ( & pSpriteBak , pSprite , sizeof ( pSpriteBak ) ) ; // how dare you??? (Use a tspritetype here so that if the sprite storage gets refactored, this line gets flagged.)
2020-08-02 17:43:45 +00:00
spritetype * pTempSprite = pSprite ;
pTempSprite - > x = predict . at50 ;
pTempSprite - > y = predict . at54 ;
pTempSprite - > z = predict . at58 ;
pTempSprite - > sectnum = predict . at68 ;
int ceilZ , ceilHit , floorZ , floorHit ;
GetZRange ( pTempSprite , & ceilZ , & ceilHit , & floorZ , & floorHit , wd , CLIPMASK0 ) ;
GetSpriteExtents ( pTempSprite , & top , & bottom ) ;
if ( predict . at73 & 2 )
{
int vc = 58254 ;
if ( bDepth )
{
if ( bUnderwater )
{
int cz = getceilzofslope ( nSector , predict . at50 , predict . at54 ) ;
if ( cz > top )
vc + = ( ( bottom - cz ) * - 80099 ) / ( bottom - top ) ;
else
vc = 0 ;
}
else
{
int fz = getflorzofslope ( nSector , predict . at50 , predict . at54 ) ;
if ( fz < bottom )
vc + = ( ( bottom - fz ) * - 80099 ) / ( bottom - top ) ;
}
}
else
{
if ( bUnderwater )
vc = 0 ;
else if ( bottom > = floorZ )
vc = 0 ;
}
if ( vc )
{
predict . at58 + = ( ( vc * 4 ) / 2 ) > > 8 ;
predict . at64 + = vc ;
}
}
GetSpriteExtents ( pTempSprite , & top , & bottom ) ;
if ( bottom > = floorZ )
{
int floorZ2 = floorZ ;
int floorHit2 = floorHit ;
GetZRange ( pTempSprite , & ceilZ , & ceilHit , & floorZ , & floorHit , pSprite - > clipdist < < 2 , CLIPMASK0 , PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR ) ;
if ( bottom < = floorZ & & predict . at58 - floorZ2 < bz )
{
floorZ = floorZ2 ;
floorHit = floorHit2 ;
}
}
if ( floorZ < = bottom )
{
predict . at75 . florhit = floorHit ;
predict . at58 + = floorZ - bottom ;
int var44 = predict . at64 - velFloor [ predict . at68 ] ;
if ( var44 > 0 )
{
actFloorBounceVector ( & predict . at5c , & predict . at60 , & var44 , predict . at68 , 0 ) ;
predict . at64 = var44 ;
if ( klabs ( predict . at64 ) < 0x10000 )
{
predict . at64 = velFloor [ predict . at68 ] ;
predict . at73 & = ~ 4 ;
}
else
predict . at73 | = 4 ;
}
else if ( predict . at64 = = 0 )
predict . at73 & = ~ 4 ;
}
else
{
predict . at75 . florhit = 0 ;
if ( predict . at73 & 2 )
predict . at73 | = 4 ;
}
if ( top < = ceilZ )
{
predict . at75 . ceilhit = ceilHit ;
predict . at58 + = ClipLow ( ceilZ - top , 0 ) ;
if ( predict . at64 < = 0 & & ( predict . at73 & 4 ) )
predict . at64 = mulscale16 ( - predict . at64 , 0x2000 ) ;
}
else
predict . at75 . ceilhit = 0 ;
GetSpriteExtents ( pTempSprite , & top , & bottom ) ;
2020-10-02 20:14:01 +00:00
memcpy ( pSprite , & pSpriteBak , sizeof ( pSpriteBak ) ) ;
2020-08-02 17:43:45 +00:00
predict . at6a = ClipLow ( floorZ - bottom , 0 ) > > 8 ;
if ( predict . at5c | | predict . at60 )
{
if ( ( floorHit & 0xc000 ) = = 0xc000 )
{
int nHitSprite = floorHit & 0x3fff ;
if ( ( sprite [ nHitSprite ] . cstat & 0x30 ) = = 0 )
{
predict . at5c + = mulscale ( 4 , predict . at50 - sprite [ nHitSprite ] . x , 2 ) ;
predict . at60 + = mulscale ( 4 , predict . at54 - sprite [ nHitSprite ] . y , 2 ) ;
return ;
}
}
int nXSector = sector [ pSprite - > sectnum ] . extra ;
if ( nXSector > 0 & & xsector [ nXSector ] . Underwater )
return ;
if ( predict . at6a > = 0x100 )
return ;
int nDrag = gDudeDrag ;
if ( predict . at6a > 0 )
nDrag - = scale ( gDudeDrag , predict . at6a , 0x100 ) ;
predict . at5c - = mulscale16r ( predict . at5c , nDrag ) ;
predict . at60 - = mulscale16r ( predict . at60 , nDrag ) ;
if ( approxDist ( predict . at5c , predict . at60 ) < 0x1000 )
predict . at5c = predict . at60 = 0 ;
}
}
static void fakeActAirDrag ( spritetype * , int num )
{
int xvec = 0 ;
int yvec = 0 ;
int nSector = predict . at68 ;
dassert ( nSector > = 0 & & nSector < kMaxSectors ) ;
sectortype * pSector = & sector [ nSector ] ;
int nXSector = pSector - > extra ;
if ( nXSector > 0 )
{
dassert ( nXSector < kMaxXSectors ) ;
XSECTOR * pXSector = & xsector [ nXSector ] ;
if ( pXSector - > windVel & & ( pXSector - > windAlways | | pXSector - > busy ) )
{
int vel = pXSector - > windVel < < 12 ;
if ( ! pXSector - > windAlways & & pXSector - > busy )
vel = mulscale16 ( vel , pXSector - > busy ) ;
xvec = mulscale30 ( vel , Cos ( pXSector - > windAng ) ) ;
yvec = mulscale30 ( vel , Sin ( pXSector - > windAng ) ) ;
}
}
predict . at5c + = mulscale16 ( xvec - predict . at5c , num ) ;
predict . at60 + = mulscale16 ( yvec - predict . at60 , num ) ;
predict . at64 - = mulscale16 ( predict . at64 , num ) ;
}
void fakeActProcessSprites ( void )
{
spritetype * pSprite = gMe - > pSprite ;
if ( pSprite - > statnum = = kStatDude )
{
int nXSprite = pSprite - > extra ;
dassert ( nXSprite > 0 & & nXSprite < kMaxXSprites ) ;
int nSector = predict . at68 ;
int nXSector = sector [ nSector ] . extra ;
XSECTOR * pXSector = NULL ;
if ( nXSector > 0 )
{
dassert ( nXSector > 0 & & nXSector < kMaxXSectors ) ;
dassert ( xsector [ nXSector ] . reference = = nSector ) ;
pXSector = & xsector [ nXSector ] ;
}
if ( pXSector )
{
int top , bottom ;
GetSpriteExtents ( pSprite , & top , & bottom ) ;
top + = predict . at58 - pSprite - > z ;
bottom + = predict . at58 - pSprite - > z ;
if ( getflorzofslope ( nSector , predict . at50 , predict . at54 ) < bottom )
{
int angle = pXSector - > panAngle ;
int speed = 0 ;
if ( pXSector - > panAlways | | pXSector - > state | | pXSector - > busy )
{
speed = pXSector - > panVel < < 9 ;
if ( ! pXSector - > panAlways & & pXSector - > busy )
speed = mulscale16 ( speed , pXSector - > busy ) ;
}
if ( sector [ nSector ] . floorstat & 64 )
angle = ( GetWallAngle ( sector [ nSector ] . wallptr ) + 512 ) & 2047 ;
predict . at5c + = mulscale30 ( speed , Cos ( angle ) ) ;
predict . at60 + = mulscale30 ( speed , Sin ( angle ) ) ;
}
}
if ( pXSector & & pXSector - > Underwater )
fakeActAirDrag ( pSprite , 5376 ) ;
else
fakeActAirDrag ( pSprite , 128 ) ;
if ( ( predict . at73 & 4 ) ! = 0 | | predict . at5c ! = 0 | | predict . at60 ! = 0 | | predict . at64 ! = 0 | | velFloor [ predict . at68 ] ! = 0 | | velCeil [ predict . at68 ] ! = 0 )
{
fakeMoveDude ( pSprite ) ;
}
}
}
void viewCorrectPrediction ( void )
{
2020-09-01 21:34:04 +00:00
#if 0
2020-08-02 17:43:45 +00:00
spritetype * pSprite = gMe - > pSprite ;
VIEW * pView = & predictFifo [ ( gNetFifoTail - 1 ) & 255 ] ;
2020-10-07 06:16:58 +00:00
if ( gMe - > q16ang ! = pView - > at30 | | pView - > at24 ! = gMe - > horizon . horiz | | pView - > at50 ! = pSprite - > x | | pView - > at54 ! = pSprite - > y | | pView - > at58 ! = pSprite - > z )
2020-08-02 17:43:45 +00:00
{
viewInitializePrediction ( ) ;
predictOld = gPrevView [ myconnectindex ] ;
gPredictTail = gNetFifoTail ;
while ( gPredictTail < gNetFifoHead [ myconnectindex ] )
{
viewUpdatePrediction ( & gFifoInput [ gPredictTail & 255 ] [ myconnectindex ] ) ;
}
}
2020-09-01 21:34:04 +00:00
# endif
2020-08-02 17:43:45 +00:00
}
END_BLD_NS