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 "mmulti.h"
# include "v_font.h"
2020-12-09 14:56:32 +00:00
# include "blood.h"
2020-08-02 17:43:45 +00:00
# include "choke.h"
# include "zstring.h"
2020-10-04 16:31:48 +00:00
# include "razemenu.h"
2020-08-02 17:43:45 +00:00
# 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 )
{
2021-03-20 18:20:42 +00:00
predict . angle = gMe - > angle . ang ;
predict . horiz = gMe - > horizon . horiz ;
predict . horizoff = 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 ) ;
2021-03-20 18:20:42 +00:00
predict . x = gMe - > pSprite - > x ;
predict . y = gMe - > pSprite - > y ;
predict . z = gMe - > pSprite - > z ;
predict . sectnum = gMe - > pSprite - > sectnum ;
2020-08-02 17:43:45 +00:00
predict . at73 = gMe - > pSprite - > flags ;
2021-03-20 18:20:42 +00:00
predict . xvel = xvel [ gMe - > pSprite - > index ] ;
predict . yvel = yvel [ gMe - > pSprite - > index ] ;
predict . zvel = zvel [ gMe - > pSprite - > index ] ;
predict . floordist = gMe - > pXSprite - > height ;
2020-08-02 17:43:45 +00:00
predict . at48 = gMe - > posture ;
2021-03-20 18:20:42 +00:00
predict . spin = gMe - > angle . 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-11-21 22:40:08 +00:00
predict . bobPhase = gMe - > bobPhase ;
2020-09-01 19:27:32 +00:00
predict . Kills = gMe - > bobAmp ;
2021-03-20 18:20:42 +00:00
predict . bobHeight = gMe - > bobHeight ;
predict . bobWidth = gMe - > bobWidth ;
2020-08-02 17:43:45 +00:00
predict . at10 = gMe - > swayPhase ;
predict . at14 = gMe - > swayAmp ;
2021-03-20 18:20:42 +00:00
predict . shakeBobY = gMe - > swayHeight ;
predict . shakeBobX = gMe - > swayWidth ;
predict . weaponZ = gMe - > zWeapon - gMe - > zView - ( 12 < < 8 ) ;
predict . viewz = gMe - > zView ;
2020-08-02 17:43:45 +00:00
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 )
{
2021-03-20 18:20:42 +00:00
predict . viewz = predict . z - pPlayer - > pPosture [ pPlayer - > lifeMode ] [ predict . at48 ] . eyeAboveZ ;
predict . at40 = predict . z - pPlayer - > pPosture [ pPlayer - > lifeMode ] [ predict . at48 ] . weaponAboveZ ;
2020-08-02 17:43:45 +00:00
}
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 )
{
2021-03-20 18:20:42 +00:00
int x = Cos ( predict . angle . asbuild ( ) ) ;
int y = Sin ( predict . angle . asbuild ( ) ) ;
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 )
2021-01-04 11:36:54 +00:00
forward = MulScale ( pPosture - > frontAccel , forward , 8 ) ;
2020-08-02 17:43:45 +00:00
else
2021-01-04 11:36:54 +00:00
forward = MulScale ( pPosture - > backAccel , forward , 8 ) ;
2021-03-20 18:20:42 +00:00
predict . xvel + = MulScale ( forward , x , 30 ) ;
predict . yvel + = MulScale ( forward , y , 30 ) ;
2020-08-02 17:43:45 +00:00
}
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 ;
2021-01-04 11:36:54 +00:00
strafe = MulScale ( pPosture - > sideAccel , strafe , 8 ) ;
2021-03-20 18:20:42 +00:00
predict . xvel + = MulScale ( strafe , y , 30 ) ;
predict . yvel - = MulScale ( strafe , x , 30 ) ;
2020-08-02 17:43:45 +00:00
}
}
2021-03-20 18:20:42 +00:00
else if ( predict . floordist < 0x100 )
2020-08-02 17:43:45 +00:00
{
int speed = 0x10000 ;
2021-03-20 18:20:42 +00:00
if ( predict . floordist > 0 )
speed - = DivScale ( predict . floordist , 0x100 , 16 ) ;
int x = Cos ( predict . angle . asbuild ( ) ) ;
int y = Sin ( predict . angle . asbuild ( ) ) ;
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 )
2021-01-04 11:36:54 +00:00
forward = MulScale ( pPosture - > frontAccel , forward , 8 ) ;
2020-08-02 17:43:45 +00:00
else
2021-01-04 11:36:54 +00:00
forward = MulScale ( pPosture - > backAccel , forward , 8 ) ;
2021-03-20 18:20:42 +00:00
if ( predict . floordist )
2021-01-04 11:36:54 +00:00
forward = MulScale ( forward , speed , 16 ) ;
2021-03-20 18:20:42 +00:00
predict . xvel + = MulScale ( forward , x , 30 ) ;
predict . yvel + = MulScale ( forward , y , 30 ) ;
2020-08-02 17:43:45 +00:00
}
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 ;
2021-01-04 11:36:54 +00:00
strafe = MulScale ( pPosture - > sideAccel , strafe , 8 ) ;
2021-03-20 18:20:42 +00:00
if ( predict . floordist )
2021-01-04 11:36:54 +00:00
strafe = MulScale ( strafe , speed , 16 ) ;
2021-03-20 18:20:42 +00:00
predict . xvel + = MulScale ( strafe , y , 30 ) ;
predict . yvel - = MulScale ( strafe , x , 30 ) ;
2020-08-02 17:43:45 +00:00
}
}
2020-10-08 03:47:30 +00:00
if ( pInput - > avel )
2021-03-20 18:20:42 +00:00
predict . angle = degang ( pInput - > avel ) ;
2020-08-28 23:19:48 +00:00
if ( pInput - > actions & SB_TURNAROUND )
2021-03-20 18:20:42 +00:00
if ( ! predict . spin . asbuild ( ) )
predict . spin = buildlook ( - 1024 ) ;
if ( predict . spin . asbuild ( ) < 0 )
2020-08-02 17:43:45 +00:00
{
int speed ;
if ( predict . at48 = = 1 )
speed = 64 ;
else
speed = 128 ;
2021-03-20 18:20:42 +00:00
predict . spin = buildlook ( min ( predict . spin . asbuild ( ) + speed , 0 ) ) ;
predict . angle + = buildang ( speed ) ;
2020-08-02 17:43:45 +00:00
}
if ( ! predict . at71 )
predict . at6f = 0 ;
switch ( predict . at48 )
{
case 1 :
if ( predict . at71 )
2021-03-20 18:20:42 +00:00
predict . zvel - = pPosture - > normalJumpZ ; //0x5b05;
2020-08-28 23:19:48 +00:00
if ( pInput - > actions & SB_CROUCH )
2021-03-20 18:20:42 +00:00
predict . zvel + = pPosture - > normalJumpZ ; //0x5b05;
2020-08-02 17:43:45 +00:00
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 :
2021-03-20 18:20:42 +00:00
if ( ! predict . at6f & & predict . at71 & & predict . floordist = = 0 ) {
if ( packItemActive ( pPlayer , 4 ) ) predict . zvel = pPosture - > pwupJumpZ ; //-0x175555;
else predict . zvel = pPosture - > normalJumpZ ; //-0xbaaaa;
2020-08-02 17:43:45 +00:00
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-10-07 07:22:07 +00:00
predict . at20 = clamp ( predict . at20 + pInput - > horz , IntToFixed ( - 60 ) , IntToFixed ( 60 ) ) ;
2020-08-02 17:43:45 +00:00
if ( predict . at20 > 0 )
2021-01-04 11:16:09 +00:00
predict . at24 = FloatToFixed ( MulScaleF ( 120. , bsinf ( FixedToFloat ( predict . at20 ) * 8. , 16 ) ) , 30 ) ;
2020-08-02 17:43:45 +00:00
else if ( predict . at20 < 0 )
2021-01-04 11:16:09 +00:00
predict . at24 = FloatToFixed ( MulScaleF ( 180. , bsinf ( FixedToFloat ( predict . at20 ) * 8. , 16 ) ) , 30 ) ;
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
2021-03-20 18:20:42 +00:00
int nSector = predict . sectnum ;
2020-08-02 17:43:45 +00:00
int florhit = predict . at75 . florhit & 0xc000 ;
char va ;
2021-03-20 18:20:42 +00:00
if ( predict . floordist < 16 & & ( florhit = = 0x4000 | | florhit = = 0 ) )
2020-08-02 17:43:45 +00:00
va = 1 ;
else
va = 0 ;
if ( va & & ( sector [ nSector ] . floorstat & 2 ) ! = 0 )
{
2021-03-20 18:20:42 +00:00
int z1 = getflorzofslope ( nSector , predict . x , predict . y ) ;
int x2 = predict . x + MulScale ( 64 , Cos ( predict . angle . asbuild ( ) ) , 30 ) ;
int y2 = predict . y + MulScale ( 64 , Sin ( predict . angle . asbuild ( ) ) , 30 ) ;
2020-08-02 17:43:45 +00:00
short nSector2 = nSector ;
updatesector ( x2 , y2 , & nSector2 ) ;
if ( nSector2 = = nSector )
{
int z2 = getflorzofslope ( nSector2 , x2 , y2 ) ;
2021-03-20 18:20:42 +00:00
predict . horizoff = q16horiz ( interpolate ( predict . horizoff . asq16 ( ) , IntToFixed ( z1 - z2 ) > > 3 , 0x4000 ) ) ;
2020-08-02 17:43:45 +00:00
}
}
else
{
2021-03-20 18:20:42 +00:00
predict . horizoff = q16horiz ( interpolate ( predict . horizoff . asq16 ( ) , 0 , 0x4000 ) ) ;
if ( abs ( predict . horizoff . asq16 ( ) ) < 4 )
predict . horizoff = q16horiz ( 0 ) ;
2020-08-02 17:43:45 +00:00
}
2021-03-20 18:20:42 +00:00
predict . at2c = - predict . horiz . 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 ) ;
2021-03-20 18:20:42 +00:00
top + = predict . z - pSprite - > z ;
bottom + = predict . z - pSprite - > z ;
2020-08-02 17:43:45 +00:00
2021-03-20 18:20:42 +00:00
int dzb = ( bottom - predict . z ) / 4 ;
int dzt = ( predict . z - top ) / 4 ;
2020-08-02 17:43:45 +00:00
int dw = pSprite - > clipdist < < 2 ;
2021-03-20 18:20:42 +00:00
short nSector = predict . sectnum ;
2020-08-02 17:43:45 +00:00
if ( ! gNoClip )
{
2021-03-20 18:20:42 +00:00
pushmove_old ( ( int32_t * ) & predict . x , ( int32_t * ) & predict . y , ( int32_t * ) & predict . z , & predict . sectnum , dw , dzt , dzb , CLIPMASK0 ) ;
if ( predict . sectnum = = - 1 )
predict . sectnum = nSector ;
2020-08-02 17:43:45 +00:00
}
fakeProcessInput ( pPlayer , pInput ) ;
2021-03-20 18:20:42 +00:00
int nSpeed = approxDist ( predict . xvel , predict . yvel ) ;
2020-08-02 17:43:45 +00:00
2021-03-20 18:20:42 +00:00
predict . at3c = interpolate ( predict . at3c , predict . zvel , 0x7000 ) ;
int dz = predict . z - pPosture - > eyeAboveZ - predict . viewz ;
2020-08-02 17:43:45 +00:00
if ( dz > 0 )
2021-01-04 11:36:54 +00:00
predict . at3c + = MulScale ( dz < < 8 , 0xa000 , 16 ) ;
2020-08-02 17:43:45 +00:00
else
2021-01-04 11:36:54 +00:00
predict . at3c + = MulScale ( dz < < 8 , 0x1800 , 16 ) ;
2021-03-20 18:20:42 +00:00
predict . viewz + = predict . at3c > > 8 ;
2020-08-02 17:43:45 +00:00
2021-03-20 18:20:42 +00:00
predict . at44 = interpolate ( predict . at44 , predict . zvel , 0x5000 ) ;
dz = predict . z - pPosture - > weaponAboveZ - predict . at40 ;
2020-08-02 17:43:45 +00:00
if ( dz > 0 )
2021-01-04 11:36:54 +00:00
predict . at44 + = MulScale ( dz < < 8 , 0x8000 , 16 ) ;
2020-08-02 17:43:45 +00:00
else
2021-01-04 11:36:54 +00:00
predict . at44 + = MulScale ( dz < < 8 , 0xc00 , 16 ) ;
2020-08-02 17:43:45 +00:00
predict . at40 + = predict . at44 > > 8 ;
2021-03-20 18:20:42 +00:00
predict . weaponZ = predict . at40 - predict . viewz - ( 12 < < 8 ) ;
2020-08-02 17:43:45 +00:00
2020-11-21 22:40:08 +00:00
predict . bobPhase = ClipLow ( predict . bobPhase - 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 ;
2021-03-20 18:20:42 +00:00
predict . bobHeight = MulScale ( 10 * pPosture - > bobV , Sin ( predict . Kills * 2 ) , 30 ) ;
predict . bobWidth = MulScale ( predict . bobPhase * pPosture - > bobH , Sin ( predict . Kills - 256 ) , 30 ) ;
predict . shakeBobY = MulScale ( predict . bobPhase * pPosture - > swayV , Sin ( predict . at14 * 2 ) , 30 ) ;
predict . shakeBobX = MulScale ( predict . bobPhase * pPosture - > swayH , Sin ( predict . at14 - 0x155 ) , 30 ) ;
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-11-21 22:40:08 +00:00
if ( predict . bobPhase < 60 )
predict . bobPhase = ClipHigh ( predict . bobPhase + nSpeed , 60 ) ;
2020-08-02 17:43:45 +00:00
}
else
{
2020-11-21 22:40:08 +00:00
if ( predict . bobPhase < 30 )
predict . bobPhase = ClipHigh ( predict . bobPhase + nSpeed , 30 ) ;
2020-08-02 17:43:45 +00:00
}
}
2021-03-20 18:20:42 +00:00
predict . bobHeight = MulScale ( predict . bobPhase * pPosture - > bobV , Sin ( predict . Kills * 2 ) , 30 ) ;
predict . bobWidth = MulScale ( predict . bobPhase * pPosture - > bobH , Sin ( predict . Kills - 256 ) , 30 ) ;
predict . shakeBobY = MulScale ( predict . bobPhase * pPosture - > swayV , Sin ( predict . at14 * 2 ) , 30 ) ;
predict . shakeBobX = MulScale ( predict . bobPhase * pPosture - > swayH , Sin ( predict . at14 - 0x155 ) , 30 ) ;
2020-08-02 17:43:45 +00:00
}
if ( ! pXSprite - > health )
return ;
predict . at72 = 0 ;
if ( predict . at48 = = 1 )
{
predict . at72 = 1 ;
2021-03-20 18:20:42 +00:00
int nSector = predict . sectnum ;
2020-08-02 17:43:45 +00:00
int nLink = gLowerLink [ nSector ] ;
if ( nLink > 0 & & ( sprite [ nLink ] . type = = kMarkerLowGoo | | sprite [ nLink ] . type = = kMarkerLowWater ) )
{
2021-03-20 18:20:42 +00:00
if ( getceilzofslope ( nSector , predict . x , predict . y ) > predict . viewz )
2020-08-02 17:43:45 +00:00
predict . at72 = 0 ;
}
}
}
static void fakeMoveDude ( spritetype * pSprite )
{
PLAYER * pPlayer = NULL ;
int bottom , top ;
if ( IsPlayerSprite ( pSprite ) )
pPlayer = & gPlayer [ pSprite - > type - kDudePlayer1 ] ;
2020-10-11 10:38:17 +00:00
assert ( pSprite - > type > = kDudeBase & & pSprite - > type < kDudeMax ) ;
2020-08-02 17:43:45 +00:00
GetSpriteExtents ( pSprite , & top , & bottom ) ;
2021-03-20 18:20:42 +00:00
top + = predict . z - pSprite - > z ;
bottom + = predict . z - pSprite - > z ;
int bz = ( bottom - predict . z ) / 4 ;
int tz = ( predict . z - top ) / 4 ;
2020-08-02 17:43:45 +00:00
int wd = pSprite - > clipdist * 4 ;
2021-03-20 18:20:42 +00:00
int nSector = predict . sectnum ;
2020-10-11 10:38:17 +00:00
assert ( nSector > = 0 & & nSector < kMaxSectors ) ;
2021-03-20 18:20:42 +00:00
if ( predict . xvel | | predict . yvel )
2020-08-02 17:43:45 +00:00
{
if ( pPlayer & & gNoClip )
{
2021-03-20 18:20:42 +00:00
predict . x + = predict . xvel > > 12 ;
predict . y + = predict . yvel > > 12 ;
if ( ! FindSector ( predict . x , predict . y , & nSector ) )
nSector = predict . sectnum ;
2020-08-02 17:43:45 +00:00
}
else
{
short bakCstat = pSprite - > cstat ;
pSprite - > cstat & = ~ 257 ;
2021-03-20 18:20:42 +00:00
predict . at75 . hit = ClipMove ( & predict . x , & predict . y , & predict . z , & nSector , predict . xvel > > 12 , predict . yvel > > 12 , wd , tz , bz , CLIPMASK0 ) ;
2020-08-02 17:43:45 +00:00
if ( nSector = = - 1 )
2021-03-20 18:20:42 +00:00
nSector = predict . sectnum ;
2020-08-02 17:43:45 +00:00
if ( sector [ nSector ] . type > = kSectorPath & & sector [ nSector ] . type < = kSectorRotate )
{
short nSector2 = nSector ;
2021-03-20 18:20:42 +00:00
pushmove_old ( ( int32_t * ) & predict . x , ( int32_t * ) & predict . y , ( int32_t * ) & predict . z , & nSector2 , wd , tz , bz , CLIPMASK0 ) ;
2020-08-02 17:43:45 +00:00
if ( nSector2 ! = - 1 )
nSector = nSector2 ;
}
2020-10-11 10:38:17 +00:00
assert ( nSector > = 0 ) ;
2020-08-02 17:43:45 +00:00
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 )
{
// ???
}
}
2021-03-20 18:20:42 +00:00
actWallBounceVector ( & predict . xvel , & predict . yvel , nHitWall , 0 ) ;
2020-08-02 17:43:45 +00:00
break ;
}
}
}
2021-03-20 18:20:42 +00:00
if ( predict . sectnum ! = nSector )
2020-08-02 17:43:45 +00:00
{
2020-10-11 10:38:17 +00:00
assert ( nSector > = 0 & & nSector < kMaxSectors ) ;
2021-03-20 18:20:42 +00:00
predict . sectnum = nSector ;
2020-08-02 17:43:45 +00:00
}
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 ;
2021-03-20 18:20:42 +00:00
if ( predict . zvel )
predict . z + = predict . zvel > > 8 ;
2020-08-02 17:43:45 +00:00
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 ;
2021-03-20 18:20:42 +00:00
pTempSprite - > x = predict . x ;
pTempSprite - > y = predict . y ;
pTempSprite - > z = predict . z ;
pTempSprite - > sectnum = predict . sectnum ;
2020-08-02 17:43:45 +00:00
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 )
{
2021-03-20 18:20:42 +00:00
int cz = getceilzofslope ( nSector , predict . x , predict . y ) ;
2020-08-02 17:43:45 +00:00
if ( cz > top )
vc + = ( ( bottom - cz ) * - 80099 ) / ( bottom - top ) ;
else
vc = 0 ;
}
else
{
2021-03-20 18:20:42 +00:00
int fz = getflorzofslope ( nSector , predict . x , predict . y ) ;
2020-08-02 17:43:45 +00:00
if ( fz < bottom )
vc + = ( ( bottom - fz ) * - 80099 ) / ( bottom - top ) ;
}
}
else
{
if ( bUnderwater )
vc = 0 ;
else if ( bottom > = floorZ )
vc = 0 ;
}
if ( vc )
{
2021-03-20 18:20:42 +00:00
predict . z + = ( ( vc * 4 ) / 2 ) > > 8 ;
predict . zvel + = vc ;
2020-08-02 17:43:45 +00:00
}
}
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 ) ;
2021-03-20 18:20:42 +00:00
if ( bottom < = floorZ & & predict . z - floorZ2 < bz )
2020-08-02 17:43:45 +00:00
{
floorZ = floorZ2 ;
floorHit = floorHit2 ;
}
}
if ( floorZ < = bottom )
{
predict . at75 . florhit = floorHit ;
2021-03-20 18:20:42 +00:00
predict . z + = floorZ - bottom ;
int var44 = predict . zvel - velFloor [ predict . sectnum ] ;
2020-08-02 17:43:45 +00:00
if ( var44 > 0 )
{
2021-03-20 18:20:42 +00:00
actFloorBounceVector ( & predict . xvel , & predict . yvel , & var44 , predict . sectnum , 0 ) ;
predict . zvel = var44 ;
if ( abs ( predict . zvel ) < 0x10000 )
2020-08-02 17:43:45 +00:00
{
2021-03-20 18:20:42 +00:00
predict . zvel = velFloor [ predict . sectnum ] ;
2020-08-02 17:43:45 +00:00
predict . at73 & = ~ 4 ;
}
else
predict . at73 | = 4 ;
}
2021-03-20 18:20:42 +00:00
else if ( predict . zvel = = 0 )
2020-08-02 17:43:45 +00:00
predict . at73 & = ~ 4 ;
}
else
{
predict . at75 . florhit = 0 ;
if ( predict . at73 & 2 )
predict . at73 | = 4 ;
}
if ( top < = ceilZ )
{
predict . at75 . ceilhit = ceilHit ;
2021-03-20 18:20:42 +00:00
predict . z + = ClipLow ( ceilZ - top , 0 ) ;
if ( predict . zvel < = 0 & & ( predict . at73 & 4 ) )
predict . zvel = MulScale ( - predict . zvel , 0x2000 , 16 ) ;
2020-08-02 17:43:45 +00:00
}
else
predict . at75 . ceilhit = 0 ;
GetSpriteExtents ( pTempSprite , & top , & bottom ) ;
2020-10-02 20:14:01 +00:00
memcpy ( pSprite , & pSpriteBak , sizeof ( pSpriteBak ) ) ;
2021-03-20 18:20:42 +00:00
predict . floordist = ClipLow ( floorZ - bottom , 0 ) > > 8 ;
if ( predict . xvel | | predict . yvel )
2020-08-02 17:43:45 +00:00
{
if ( ( floorHit & 0xc000 ) = = 0xc000 )
{
int nHitSprite = floorHit & 0x3fff ;
if ( ( sprite [ nHitSprite ] . cstat & 0x30 ) = = 0 )
{
2021-03-20 18:20:42 +00:00
predict . xvel + = MulScale ( 4 , predict . x - sprite [ nHitSprite ] . x , 2 ) ;
predict . yvel + = MulScale ( 4 , predict . y - sprite [ nHitSprite ] . y , 2 ) ;
2020-08-02 17:43:45 +00:00
return ;
}
}
int nXSector = sector [ pSprite - > sectnum ] . extra ;
if ( nXSector > 0 & & xsector [ nXSector ] . Underwater )
return ;
2021-03-20 18:20:42 +00:00
if ( predict . floordist > = 0x100 )
2020-08-02 17:43:45 +00:00
return ;
int nDrag = gDudeDrag ;
2021-03-20 18:20:42 +00:00
if ( predict . floordist > 0 )
nDrag - = scale ( gDudeDrag , predict . floordist , 0x100 ) ;
predict . xvel - = mulscale16r ( predict . xvel , nDrag ) ;
predict . yvel - = mulscale16r ( predict . yvel , nDrag ) ;
if ( approxDist ( predict . xvel , predict . yvel ) < 0x1000 )
predict . xvel = predict . yvel = 0 ;
2020-08-02 17:43:45 +00:00
}
}
static void fakeActAirDrag ( spritetype * , int num )
{
int xvec = 0 ;
int yvec = 0 ;
2021-03-20 18:20:42 +00:00
int nSector = predict . sectnum ;
2020-10-11 10:38:17 +00:00
assert ( nSector > = 0 & & nSector < kMaxSectors ) ;
2020-08-02 17:43:45 +00:00
sectortype * pSector = & sector [ nSector ] ;
int nXSector = pSector - > extra ;
if ( nXSector > 0 )
{
2020-10-11 10:38:17 +00:00
assert ( nXSector < kMaxXSectors ) ;
2020-08-02 17:43:45 +00:00
XSECTOR * pXSector = & xsector [ nXSector ] ;
if ( pXSector - > windVel & & ( pXSector - > windAlways | | pXSector - > busy ) )
{
int vel = pXSector - > windVel < < 12 ;
if ( ! pXSector - > windAlways & & pXSector - > busy )
2021-01-04 11:36:54 +00:00
vel = MulScale ( vel , pXSector - > busy , 16 ) ;
xvec = MulScale ( vel , Cos ( pXSector - > windAng ) , 30 ) ;
yvec = MulScale ( vel , Sin ( pXSector - > windAng ) , 30 ) ;
2020-08-02 17:43:45 +00:00
}
}
2021-03-20 18:20:42 +00:00
predict . xvel + = MulScale ( xvec - predict . xvel , num , 16 ) ;
predict . yvel + = MulScale ( yvec - predict . yvel , num , 16 ) ;
predict . zvel - = MulScale ( predict . zvel , num , 16 ) ;
2020-08-02 17:43:45 +00:00
}
void fakeActProcessSprites ( void )
{
spritetype * pSprite = gMe - > pSprite ;
if ( pSprite - > statnum = = kStatDude )
{
int nXSprite = pSprite - > extra ;
2020-10-11 10:38:17 +00:00
assert ( nXSprite > 0 & & nXSprite < kMaxXSprites ) ;
2021-03-20 18:20:42 +00:00
int nSector = predict . sectnum ;
2020-08-02 17:43:45 +00:00
int nXSector = sector [ nSector ] . extra ;
XSECTOR * pXSector = NULL ;
if ( nXSector > 0 )
{
2020-10-11 10:38:17 +00:00
assert ( nXSector > 0 & & nXSector < kMaxXSectors ) ;
assert ( xsector [ nXSector ] . reference = = nSector ) ;
2020-08-02 17:43:45 +00:00
pXSector = & xsector [ nXSector ] ;
}
if ( pXSector )
{
int top , bottom ;
GetSpriteExtents ( pSprite , & top , & bottom ) ;
2021-03-20 18:20:42 +00:00
top + = predict . z - pSprite - > z ;
bottom + = predict . z - pSprite - > z ;
if ( getflorzofslope ( nSector , predict . x , predict . y ) < bottom )
2020-08-02 17:43:45 +00:00
{
int angle = pXSector - > panAngle ;
int speed = 0 ;
if ( pXSector - > panAlways | | pXSector - > state | | pXSector - > busy )
{
speed = pXSector - > panVel < < 9 ;
if ( ! pXSector - > panAlways & & pXSector - > busy )
2021-01-04 11:36:54 +00:00
speed = MulScale ( speed , pXSector - > busy , 16 ) ;
2020-08-02 17:43:45 +00:00
}
if ( sector [ nSector ] . floorstat & 64 )
angle = ( GetWallAngle ( sector [ nSector ] . wallptr ) + 512 ) & 2047 ;
2021-03-20 18:20:42 +00:00
predict . xvel + = MulScale ( speed , Cos ( angle ) , 30 ) ;
predict . yvel + = MulScale ( speed , Sin ( angle ) , 30 ) ;
2020-08-02 17:43:45 +00:00
}
}
if ( pXSector & & pXSector - > Underwater )
fakeActAirDrag ( pSprite , 5376 ) ;
else
fakeActAirDrag ( pSprite , 128 ) ;
2021-03-20 18:20:42 +00:00
if ( ( predict . at73 & 4 ) ! = 0 | | predict . xvel ! = 0 | | predict . yvel ! = 0 | | predict . zvel ! = 0 | | velFloor [ predict . sectnum ] ! = 0 | | velCeil [ predict . sectnum ] ! = 0 )
2020-08-02 17:43:45 +00:00
{
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 20:55:54 +00:00
if ( gMe - > angle . ang ! = 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