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 "build.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"
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-11-23 23:10:48 +00:00
#if 0
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 ;
2021-11-23 23:10:48 +00:00
predict . sector = gMe - > pSprite - > sector ;
2020-08-02 17:43:45 +00:00
predict . at73 = gMe - > pSprite - > flags ;
2021-09-05 07:53:06 +00:00
predict . xvel = gMe - > actor - > xvel ;
predict . yvel = gMe - > actor - > yvel ;
predict . zvel = gMe - > actor - > zvel ;
2021-03-20 18:20:42 +00:00
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 ) ;
2021-09-05 07:53:06 +00:00
predict . at75 = gMe - > actor - > hit ;
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 ;
2021-11-23 23:10:48 +00:00
# endif
2020-08-02 17:43:45 +00:00
}
2020-08-26 15:12:48 +00:00
void viewUpdatePrediction ( InputPacket * pInput )
2020-08-02 17:43:45 +00:00
{
predictOld = predict ;
2021-11-16 17:15:56 +00:00
auto bakCstat = gMe - > pSprite - > cstat ;
2020-08-02 17:43:45 +00:00
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
{
2021-11-23 23:10:48 +00:00
#if 0
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-04-11 05:43:11 +00:00
if ( ! predict . spin )
predict . spin = - 1024 ;
if ( predict . spin < 0 )
2020-08-02 17:43:45 +00:00
{
int speed ;
if ( predict . at48 = = 1 )
speed = 64 ;
else
speed = 128 ;
2021-04-11 05:43:11 +00:00
predict . spin = min ( int ( predict . spin ) + speed , 0 ) ;
2021-03-20 18:20:42 +00:00
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 ;
2021-09-02 18:23:51 +00:00
int florhit = predict . at75 . florhit . type ;
2021-11-16 17:36:34 +00:00
bool va = ( predict . floordist < 16 & & ( florhit = = kHitSector | | florhit = = 0 ) ) ;
2020-08-02 17:43:45 +00:00
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 ) ;
2021-11-06 14:53:16 +00:00
int nSector2 = nSector ;
2020-08-02 17:43:45 +00:00
updatesector ( x2 , y2 , & nSector2 ) ;
if ( nSector2 = = nSector )
{
int z2 = getflorzofslope ( nSector2 , x2 , y2 ) ;
2021-11-06 03:00:41 +00:00
predict . horizoff = interpolatedhorizon ( predict . horizoff , q16horiz ( ( z1 - z2 ) < < 13 ) , 0x4000 ) ;
2020-08-02 17:43:45 +00:00
}
}
else
{
2021-11-06 03:00:41 +00:00
predict . horizoff = interpolatedhorizon ( predict . horizoff , q16horiz ( 0 ) , 0x4000 ) ;
2021-03-20 18:20:42 +00:00
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 ;
2021-11-23 23:10:48 +00:00
# endif
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-11-16 17:15:56 +00:00
int nSector = predict . sectnum ;
2020-08-02 17:43:45 +00:00
if ( ! gNoClip )
{
2021-10-30 11:00:18 +00:00
pushmove ( & predict . pos , & predict . sectnum , dw , dzt , dzb , CLIPMASK0 ) ;
2021-03-20 18:20:42 +00:00
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-04-11 06:45:19 +00:00
predict . at3c = interpolatedvalue ( predict . at3c , predict . zvel , 0x7000 ) ;
2021-03-20 18:20:42 +00:00
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-04-11 06:45:19 +00:00
predict . at44 = interpolatedvalue ( predict . at44 , predict . zvel , 0x5000 ) ;
2021-03-20 18:20:42 +00:00
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 ;
2021-09-04 20:24:34 +00:00
auto nLink = getLowerLink ( nSector ) ;
if ( nLink & & ( nLink - > s ( ) . type = = kMarkerLowGoo | | nLink - > s ( ) . type = = kMarkerLowWater ) )
2020-08-02 17:43:45 +00:00
{
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 )
{
2021-09-04 18:19:38 +00:00
#if 0 // not needed for single player, temporarily disabled due to icompatibilities with the refactored API.
2020-08-02 17:43:45 +00:00
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 ;
2021-11-09 08:06:54 +00:00
assert ( validSectorIndex ( nSector ) ) ;
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
{
2021-11-16 17:15:56 +00:00
auto bakCstat = pSprite - > cstat ;
2020-08-02 17:43:45 +00:00
pSprite - > cstat & = ~ 257 ;
2021-10-30 10:26:35 +00:00
predict . at75 . hit = ClipMove ( & predict . pos , & 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 )
{
2021-11-07 18:35:55 +00:00
int nSector2 = nSector ;
2021-10-30 11:00:18 +00:00
pushmove ( & predict . pos , & 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 ;
}
2021-09-02 18:23:51 +00:00
switch ( predict . at75 . hit . type )
2020-08-02 17:43:45 +00:00
{
2021-09-02 18:23:51 +00:00
case kHitSprite :
2020-08-02 17:43:45 +00:00
{
2021-09-02 18:23:51 +00:00
int nHitWall = predict . at75 . hit . index ;
2021-11-23 22:39:10 +00:00
walltype * pHitWall = & wall [ nHitWall ] ;
2021-11-23 22:04:21 +00:00
if ( pHitWall - > twoSided ( ) )
2020-08-02 17:43:45 +00:00
{
2021-11-23 22:04:21 +00:00
sectortype * pHitSector = & pHitWall - > nextSector ( ) ;
2020-08-02 17:43:45 +00:00
if ( top < pHitSector - > ceilingz | | bottom > pHitSector - > floorz )
{
// ???
}
}
2021-11-21 08:45:50 +00:00
actWallBounceVector ( & predict . xvel , & predict . yvel , pHitWall , 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
{
2021-11-09 08:06:54 +00:00
assert ( validSectorIndex ( nSector ) ) ;
2021-03-20 18:20:42 +00:00
predict . sectnum = nSector ;
2020-08-02 17:43:45 +00:00
}
2021-11-16 17:36:34 +00:00
bool bUnderwater = 0 ;
bool bDepth = 0 ;
2021-11-19 18:33:38 +00:00
if ( sector [ sectnum ] . hasX ( ) )
2020-08-02 17:43:45 +00:00
{
2021-11-19 18:33:38 +00:00
XSECTOR * pXSector = & sector [ sectnum ] . xs ( ) ;
2020-08-02 17:43:45 +00:00
if ( pXSector - > Underwater )
bUnderwater = 1 ;
if ( pXSector - > Depth )
bDepth = 1 ;
}
2021-09-04 20:24:34 +00:00
auto nUpperLink = getUpperLink ( nSector ) ;
auto nLowerLink = getLowerLink ( nSector ) ;
if ( nUpperLink > = 0 & & ( nUpperLink - > s ( ) . type = = kMarkerUpWater | | nUpperLink - > s ( ) . type = = kMarkerUpGoo ) )
2020-08-02 17:43:45 +00:00
bDepth = 1 ;
2021-09-04 20:24:34 +00:00
if ( nLowerLink > = 0 & & ( nLowerLink - > s ( ) . type = = kMarkerLowWater | | nLowerLink - > s ( ) . type = = kMarkerLowGoo ) )
2020-08-02 17:43:45 +00:00
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 ;
2021-09-02 18:23:51 +00:00
int ceilZ , floorZ ;
Collision ceilColl , floorColl ;
GetZRange ( pTempSprite , & ceilZ , & ceilColl , & floorZ , & floorColl , wd , CLIPMASK0 ) ;
2020-08-02 17:43:45 +00:00
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 ;
2021-09-02 18:23:51 +00:00
auto floorHit2 = floorColl ;
GetZRange ( pTempSprite , & ceilZ , & ceilColl , & floorZ , & floorColl , 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 ;
2021-09-02 18:23:51 +00:00
floorColl = floorHit2 ;
2020-08-02 17:43:45 +00:00
}
}
if ( floorZ < = bottom )
{
2021-09-02 18:23:51 +00:00
predict . at75 . florhit = floorColl ;
2021-03-20 18:20:42 +00:00
predict . z + = floorZ - bottom ;
2021-11-20 18:10:02 +00:00
int var44 = predict . zvel - predict . sector ( ) - > velFloor ;
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-11-20 18:10:02 +00:00
predict . zvel = predict . sector ( ) - > velFloor ;
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
{
2021-09-02 18:23:51 +00:00
predict . at75 . florhit . setNone ( ) ;
2020-08-02 17:43:45 +00:00
if ( predict . at73 & 2 )
predict . at73 | = 4 ;
}
if ( top < = ceilZ )
{
2021-09-02 18:23:51 +00:00
predict . at75 . ceilhit = ceilColl ;
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
{
2021-09-02 18:23:51 +00:00
if ( floorColl . type = = kHitSprite )
2020-08-02 17:43:45 +00:00
{
2021-09-02 18:23:51 +00:00
auto hitactor = floorColl . actor ;
if ( ( hitactor - > s ( ) . cstat & 0x30 ) = = 0 )
2020-08-02 17:43:45 +00:00
{
2021-09-02 18:23:51 +00:00
predict . xvel + = MulScale ( 4 , predict . x - hitactor - > s ( ) . x , 2 ) ;
predict . yvel + = MulScale ( 4 , predict . y - hitactor - > s ( ) . y , 2 ) ;
2020-08-02 17:43:45 +00:00
return ;
}
}
2021-11-19 19:25:16 +00:00
if ( pSprite - > sector ( ) - > hasX ( ) & & pSprite - > sector ( ) - > xs ( ) . Underwater )
2020-08-02 17:43:45 +00:00
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
}
2021-09-04 18:19:38 +00:00
# endif
2020-08-02 17:43:45 +00:00
}
static void fakeActAirDrag ( spritetype * , int num )
{
2021-11-20 18:10:02 +00:00
#if 0
2020-08-02 17:43:45 +00:00
int xvec = 0 ;
int yvec = 0 ;
2021-11-19 16:29:49 +00:00
assert ( validSectorIndex ( predict . sectnum ) ) ;
sectortype * pSector = & sector [ predict . sectnum ] ;
if ( pSector - > hasX ( ) )
2020-08-02 17:43:45 +00:00
{
2021-11-19 16:29:49 +00:00
XSECTOR * pXSector = & pSector - > xs ( ) ;
2020-08-02 17:43:45 +00:00
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 ) ;
2021-11-20 18:10:02 +00:00
# endif
2020-08-02 17:43:45 +00:00
}
void fakeActProcessSprites ( void )
{
2021-11-20 18:10:02 +00:00
#if 0
2020-08-02 17:43:45 +00:00
spritetype * pSprite = gMe - > pSprite ;
if ( pSprite - > statnum = = kStatDude )
{
2021-03-20 18:20:42 +00:00
int nSector = predict . sectnum ;
2021-11-19 16:29:49 +00:00
auto pSector = & sector [ predict . sectnum ] ;
auto pXSector = pSector - > hasX ( ) ? & pSector - > xs ( ) : nullptr ;
2020-08-02 17:43:45 +00:00
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
}
2021-11-19 16:29:49 +00:00
if ( pSector - > floorstat & 64 )
angle = ( GetWallAngle ( pSector - > 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-11-20 18:10:02 +00:00
if ( ( predict . at73 & 4 ) ! = 0 | | predict . xvel ! = 0 | | predict . yvel ! = 0 | | predict . zvel ! = 0 | | predict . sector ( ) - > velFloor ! = 0 | | predict . sector ( ) - > velCeil ! = 0 )
2020-08-02 17:43:45 +00:00
{
fakeMoveDude ( pSprite ) ;
}
}
2021-11-20 18:10:02 +00:00
# endif
2020-08-02 17:43:45 +00:00
}
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