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;
|
|
|
|
|
|
|
|
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;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.slope = gMe->slope;
|
|
|
|
predict.cantJump = gMe->cantJump;
|
|
|
|
predict.isRunning = gMe->isRunning;
|
|
|
|
predict.isUnderwater = gMe->isUnderwater;
|
|
|
|
predict.jump = !!(gMe->input.actions & SB_JUMP);
|
2021-12-23 09:21:17 +00:00
|
|
|
predict.x = gMe->actor->spr.x;
|
|
|
|
predict.y = gMe->actor->spr.y;
|
|
|
|
predict.z = gMe->actor->spr.z;
|
|
|
|
predict.sector = gMe->actor->spr.sector;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.sprflags = gMe->actor->spr.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-12-23 13:14:28 +00:00
|
|
|
predict.floordist = gMe->actor->xspr.height;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.posture = gMe->posture;
|
2021-03-20 18:20:42 +00:00
|
|
|
predict.spin = gMe->angle.spin;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.lookCenter = !!(gMe->input.actions & SB_CENTERVIEW);
|
|
|
|
predict.hit = 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;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.swayPhase = gMe->swayPhase;
|
|
|
|
predict.swayAmp = gMe->swayAmp;
|
2021-03-20 18:20:42 +00:00
|
|
|
predict.shakeBobY = gMe->swayHeight;
|
|
|
|
predict.shakeBobX = gMe->swayWidth;
|
2021-12-29 21:56:21 +00:00
|
|
|
predict.weaponZ = gMe->zWeapon - gMe->zView - (12 << 8);
|
2021-03-20 18:20:42 +00:00
|
|
|
predict.viewz = gMe->zView;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.zViewVel = gMe->zViewVel;
|
|
|
|
predict.zWeapon = gMe->zWeapon;
|
|
|
|
predict.zWeaponVel = gMe->zWeaponVel;
|
2021-12-29 21:56:21 +00:00
|
|
|
predictOld = predict;
|
2021-11-23 23:10:48 +00:00
|
|
|
#endif
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 21:56:21 +00:00
|
|
|
void viewUpdatePrediction(InputPacket* pInput)
|
2020-08-02 17:43:45 +00:00
|
|
|
{
|
2022-09-10 12:34:44 +00:00
|
|
|
#if 0
|
2021-12-29 21:56:21 +00:00
|
|
|
predictOld = predict;
|
2021-12-23 09:21:17 +00:00
|
|
|
auto bakCstat = gMe->actor->spr.cstat;
|
2021-12-29 21:56:21 +00:00
|
|
|
gMe->actor->spr.cstat = 0;
|
|
|
|
fakePlayerProcess(gMe, pInput);
|
|
|
|
fakeActProcessSprites();
|
|
|
|
gMe->actor->spr.cstat = bakCstat;
|
2022-09-10 12:34:44 +00:00
|
|
|
predictFifo[gPredictTail&255] = predict;
|
|
|
|
gPredictTail++;
|
|
|
|
#endif
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 21:56:21 +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
|
2022-09-08 11:57:17 +00:00
|
|
|
POSTURE* pPosture = &pPlayer->pPosture[pPlayer->lifeMode][predict.posture];
|
2021-12-29 21:56:21 +00:00
|
|
|
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.isRunning = !!(gMe->input.actions & SB_RUN);
|
|
|
|
predict.jump = !!(gMe->input.actions & SB_JUMP);
|
|
|
|
if (predict.posture == 1)
|
2021-12-29 21:56:21 +00:00
|
|
|
{
|
|
|
|
int x = Cos(predict.angle.asbuild());
|
|
|
|
int y = Sin(predict.angle.asbuild());
|
|
|
|
if (pInput->fvel)
|
|
|
|
{
|
|
|
|
int forward = pInput->fvel;
|
|
|
|
if (forward > 0)
|
|
|
|
forward = MulScale(pPosture->frontAccel, forward, 8);
|
|
|
|
else
|
|
|
|
forward = MulScale(pPosture->backAccel, forward, 8);
|
|
|
|
predict.xvel += MulScale(forward, x, 30);
|
|
|
|
predict.yvel += MulScale(forward, y, 30);
|
|
|
|
}
|
|
|
|
if (pInput->svel)
|
|
|
|
{
|
|
|
|
int strafe = pInput->svel;
|
|
|
|
strafe = MulScale(pPosture->sideAccel, strafe, 8);
|
|
|
|
predict.xvel += MulScale(strafe, y, 30);
|
|
|
|
predict.yvel -= MulScale(strafe, x, 30);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (predict.floordist < 0x100)
|
|
|
|
{
|
|
|
|
int speed = 0x10000;
|
|
|
|
if (predict.floordist > 0)
|
|
|
|
speed -= DivScale(predict.floordist, 0x100, 16);
|
|
|
|
int x = Cos(predict.angle.asbuild());
|
|
|
|
int y = Sin(predict.angle.asbuild());
|
|
|
|
if (pInput->fvel)
|
|
|
|
{
|
|
|
|
int forward = pInput->fvel;
|
|
|
|
if (forward > 0)
|
|
|
|
forward = MulScale(pPosture->frontAccel, forward, 8);
|
|
|
|
else
|
|
|
|
forward = MulScale(pPosture->backAccel, forward, 8);
|
|
|
|
if (predict.floordist)
|
|
|
|
forward = MulScale(forward, speed, 16);
|
|
|
|
predict.xvel += MulScale(forward, x, 30);
|
|
|
|
predict.yvel += MulScale(forward, y, 30);
|
|
|
|
}
|
|
|
|
if (pInput->svel)
|
|
|
|
{
|
|
|
|
int strafe = pInput->svel;
|
|
|
|
strafe = MulScale(pPosture->sideAccel, strafe, 8);
|
|
|
|
if (predict.floordist)
|
|
|
|
strafe = MulScale(strafe, speed, 16);
|
|
|
|
predict.xvel += MulScale(strafe, y, 30);
|
|
|
|
predict.yvel -= MulScale(strafe, x, 30);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pInput->avel)
|
|
|
|
predict.angle = degang(pInput->avel);
|
|
|
|
if (pInput->actions & SB_TURNAROUND)
|
|
|
|
if (!predict.spin)
|
|
|
|
predict.spin = -1024;
|
|
|
|
if (predict.spin < 0)
|
|
|
|
{
|
|
|
|
int speed;
|
2022-09-08 11:57:17 +00:00
|
|
|
if (predict.posture == 1)
|
2021-12-29 21:56:21 +00:00
|
|
|
speed = 64;
|
|
|
|
else
|
|
|
|
speed = 128;
|
|
|
|
|
|
|
|
predict.spin = min(int(predict.spin) + speed, 0);
|
2022-08-22 16:46:55 +00:00
|
|
|
predict.angle += DAngle::fromBuild(speed);
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
|
|
|
|
2022-09-08 11:57:17 +00:00
|
|
|
if (!predict.jump)
|
|
|
|
predict.cantJump = 0;
|
2021-12-29 21:56:21 +00:00
|
|
|
|
2022-09-08 11:57:17 +00:00
|
|
|
switch (predict.posture)
|
2021-12-29 21:56:21 +00:00
|
|
|
{
|
|
|
|
case 1:
|
2022-09-08 11:57:17 +00:00
|
|
|
if (predict.jump)
|
2021-12-29 21:56:21 +00:00
|
|
|
predict.zvel -= pPosture->normalJumpZ;//0x5b05;
|
|
|
|
if (pInput->actions & SB_CROUCH)
|
|
|
|
predict.zvel += pPosture->normalJumpZ;//0x5b05;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
if (!(pInput->actions & SB_CROUCH))
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.posture = 0;
|
2021-12-29 21:56:21 +00:00
|
|
|
break;
|
|
|
|
default:
|
2022-09-08 11:57:17 +00:00
|
|
|
if (!predict.cantJump && predict.jump && predict.floordist == 0) {
|
2021-12-29 21:56:21 +00:00
|
|
|
if (packItemActive(pPlayer, 4)) predict.zvel = pPosture->pwupJumpZ;//-0x175555;
|
|
|
|
else predict.zvel = pPosture->normalJumpZ;//-0xbaaaa;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.cantJump = 1;
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
|
|
|
if (pInput->actions & SB_CROUCH)
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.posture = 2;
|
2021-12-29 21:56:21 +00:00
|
|
|
break;
|
|
|
|
}
|
2020-09-16 00:06:50 +00:00
|
|
|
|
2020-10-07 06:16:58 +00:00
|
|
|
#if 0
|
2022-09-08 11:57:17 +00:00
|
|
|
if (predict.lookCenter && !(pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN)))
|
2021-12-29 21:56:21 +00:00
|
|
|
{
|
|
|
|
if (predict.at20 < 0)
|
|
|
|
predict.at20 = min(predict.at20 + IntToFixed(4), 0);
|
|
|
|
if (predict.at20 > 0)
|
|
|
|
predict.at20 = max(predict.at20 - IntToFixed(4), 0);
|
|
|
|
if (predict.at20 == 0)
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.lookCenter = 0;
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (pInput->actions & SB_LOOK_UP)
|
|
|
|
predict.at20 = min(predict.at20 + IntToFixed(4), IntToFixed(60));
|
|
|
|
if (pInput->actions & SB_LOOK_DOWN)
|
|
|
|
predict.at20 = max(predict.at20 - IntToFixed(4), IntToFixed(-60));
|
|
|
|
}
|
|
|
|
predict.at20 = clamp(predict.at20 + pInput->horz, IntToFixed(-60), IntToFixed(60));
|
|
|
|
|
|
|
|
if (predict.at20 > 0)
|
2022-09-25 10:47:07 +00:00
|
|
|
predict.at24 = FloatToFixed(MulScaleF(120., bsin f(FixedToFloat(predict.at20) * 8., 16)), 30);
|
2021-12-29 21:56:21 +00:00
|
|
|
else if (predict.at20 < 0)
|
2022-09-25 10:47:07 +00:00
|
|
|
predict.at24 = FloatToFixed(MulScaleF(180., bsin f(FixedToFloat(predict.at20) * 8., 16)), 30);
|
2021-12-29 21:56:21 +00:00
|
|
|
else
|
|
|
|
predict.at24 = 0;
|
2020-10-07 06:16:58 +00:00
|
|
|
#endif
|
2020-08-02 17:43:45 +00:00
|
|
|
|
2021-12-29 21:56:21 +00:00
|
|
|
int nSector = predict.sector;
|
2022-09-08 11:57:17 +00:00
|
|
|
int florhit = predict.hit.florhit.type;
|
2021-11-16 17:36:34 +00:00
|
|
|
bool va = (predict.floordist < 16 && (florhit == kHitSector || florhit == 0));
|
|
|
|
|
2021-12-29 21:56:21 +00:00
|
|
|
if (va && (sector[nSector].floorstat & 2) != 0)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
int nSector2 = nSector;
|
|
|
|
updatesector(x2, y2, &nSector2);
|
|
|
|
if (nSector2 == nSector)
|
|
|
|
{
|
|
|
|
int z2 = getflorzofslope(nSector2, x2, y2);
|
2022-09-07 04:20:51 +00:00
|
|
|
predict.horizoff = interpolatedvalue(predict.horizoff, q16horiz((z1 - z2) << 13), 0x4000);
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-09-27 02:38:57 +00:00
|
|
|
predict.horizoff = interpolatedvalue(predict.horizoff, pitchhoriz(nullAngle.Degrees()), 0x4000);
|
2022-09-27 04:12:16 +00:00
|
|
|
if (abs(predict.horizoff.Degrees()) < 1.79)
|
2022-09-27 02:38:57 +00:00
|
|
|
predict.horizoff = pitchhoriz(nullAngle.Degrees());
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
2022-09-27 04:12:16 +00:00
|
|
|
predict.slope = -predict.horiz.Tan() * 16384.;
|
2021-11-23 23:10:48 +00:00
|
|
|
#endif
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 21:56:21 +00:00
|
|
|
void fakePlayerProcess(PLAYER* pPlayer, InputPacket* pInput)
|
2020-08-02 17:43:45 +00:00
|
|
|
{
|
2021-11-26 19:41:03 +00:00
|
|
|
#if 0
|
2021-12-29 21:56:21 +00:00
|
|
|
auto pSprite = pPlayer->actor;
|
2022-09-08 11:57:17 +00:00
|
|
|
POSTURE* pPosture = &pPlayer->pPosture[pPlayer->lifeMode][predict.posture];
|
2021-12-29 21:56:21 +00:00
|
|
|
|
|
|
|
int top, bottom;
|
|
|
|
GetSpriteExtents(pSprite, &top, &bottom);
|
|
|
|
|
|
|
|
top += predict.z - pSprite->z;
|
|
|
|
bottom += predict.z - pSprite->z;
|
|
|
|
|
|
|
|
int dzb = (bottom - predict.z) / 4;
|
|
|
|
int dzt = (predict.z - top) / 4;
|
|
|
|
|
|
|
|
int dw = pSprite->clipdist << 2;
|
|
|
|
int nSector = predict.sector;
|
|
|
|
if (!gNoClip)
|
|
|
|
{
|
|
|
|
pushmove(&predict.pos, &predict.sector, dw, dzt, dzb, CLIPMASK0);
|
|
|
|
if (predict.sector == -1)
|
|
|
|
predict.sector = nSector;
|
|
|
|
}
|
|
|
|
fakeProcessInput(pPlayer, pInput);
|
|
|
|
|
|
|
|
int nSpeed = approxDist(predict.xvel, predict.yvel);
|
|
|
|
|
2022-09-10 13:52:27 +00:00
|
|
|
predict.zViewVel = interpolatedvalue(predict.zViewVel, predict.zvel, FixedToFloat(0x7000));
|
2021-12-29 21:56:21 +00:00
|
|
|
int dz = predict.z - pPosture->eyeAboveZ - predict.viewz;
|
|
|
|
if (dz > 0)
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.zViewVel += MulScale(dz << 8, 0xa000, 16);
|
2021-12-29 21:56:21 +00:00
|
|
|
else
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.zViewVel += MulScale(dz << 8, 0x1800, 16);
|
|
|
|
predict.viewz += predict.zViewVel >> 8;
|
2021-12-29 21:56:21 +00:00
|
|
|
|
2022-09-10 13:52:27 +00:00
|
|
|
predict.zWeaponVel = interpolatedvalue(predict.zWeaponVel, predict.zvel, FixedToFloat(0x5000));
|
2022-09-08 11:57:17 +00:00
|
|
|
dz = predict.z - pPosture->weaponAboveZ - predict.zWeapon;
|
2021-12-29 21:56:21 +00:00
|
|
|
if (dz > 0)
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.azWeaponVelt44 += MulScale(dz << 8, 0x8000, 16);
|
2021-12-29 21:56:21 +00:00
|
|
|
else
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.zWeaponVel += MulScale(dz << 8, 0xc00, 16);
|
|
|
|
predict.zWeapon += predict.zWeaponVel >> 8;
|
2021-12-29 21:56:21 +00:00
|
|
|
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.weaponZ = predict.zWeapon - predict.viewz - (12 << 8);
|
2021-12-29 21:56:21 +00:00
|
|
|
|
|
|
|
predict.bobPhase = ClipLow(predict.bobPhase - 4, 0);
|
|
|
|
|
|
|
|
nSpeed >>= FRACBITS;
|
2022-09-08 11:57:17 +00:00
|
|
|
if (predict.posture == 1)
|
2020-08-02 17:43:45 +00:00
|
|
|
{
|
2021-12-29 21:56:21 +00:00
|
|
|
predict.Kills = (predict.Kills + 17) & 2047;
|
|
|
|
predict.at14 = (predict.at14 + 17) & 2047;
|
|
|
|
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)
|
|
|
|
{
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.Kills = (predict.Kills + (pPosture->pace[predict.isRunning] * 4)) & 2047;
|
|
|
|
predict.at14 = (predict.at14 + (pPosture->pace[predict.isRunning] * 4) / 2) & 2047;
|
|
|
|
if (predict.isRunning)
|
2020-08-02 17:43:45 +00:00
|
|
|
{
|
2020-11-21 22:40:08 +00:00
|
|
|
if (predict.bobPhase < 60)
|
2021-12-29 21:56:21 +00:00
|
|
|
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)
|
2021-12-29 21:56:21 +00:00
|
|
|
predict.bobPhase = ClipHigh(predict.bobPhase + nSpeed, 30);
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-29 21:56:21 +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)
|
2021-12-29 21:56:21 +00:00
|
|
|
return;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.isUnderwater = 0;
|
|
|
|
if (predict.posture == 1)
|
2020-08-02 17:43:45 +00:00
|
|
|
{
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.isUnderwater = 1;
|
2021-12-29 21:56:21 +00:00
|
|
|
int nSector = predict.sector;
|
|
|
|
auto nLink = getLowerLink(nSector);
|
2021-12-21 22:18:23 +00:00
|
|
|
if (nLink && (nLink->spr.type == kMarkerLowGoo || nLink->spr.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)
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.isUnderwater = 0;
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-26 19:41:03 +00:00
|
|
|
#endif
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 21:56:21 +00:00
|
|
|
static void fakeMoveDude(DBloodActor* actor)
|
2020-08-02 17:43:45 +00:00
|
|
|
{
|
2021-09-04 18:19:38 +00:00
|
|
|
#if 0 // not needed for single player, temporarily disabled due to icompatibilities with the refactored API.
|
2021-12-29 21:56:21 +00:00
|
|
|
PLAYER* pPlayer = NULL;
|
|
|
|
int bottom, top;
|
|
|
|
if (IsPlayerSprite(pSprite))
|
|
|
|
pPlayer = &gPlayer[pSprite->type - kDudePlayer1];
|
|
|
|
assert(pSprite->type >= kDudeBase && pSprite->type < kDudeMax);
|
|
|
|
GetSpriteExtents(pSprite, &top, &bottom);
|
2021-03-20 18:20:42 +00:00
|
|
|
top += predict.z - pSprite->z;
|
|
|
|
bottom += predict.z - pSprite->z;
|
2021-12-29 21:56:21 +00:00
|
|
|
int bz = (bottom - predict.z) / 4;
|
|
|
|
int tz = (predict.z - top) / 4;
|
|
|
|
int wd = pSprite->clipdist * 4;
|
|
|
|
int nSector = predict.sector;
|
|
|
|
assert(validSectorIndex(nSector));
|
|
|
|
if (predict.xvel || predict.yvel)
|
|
|
|
{
|
|
|
|
if (pPlayer && gNoClip)
|
|
|
|
{
|
|
|
|
predict.x += predict.xvel >> 12;
|
|
|
|
predict.y += predict.yvel >> 12;
|
|
|
|
if (!FindSector(predict.x, predict.y, &nSector))
|
|
|
|
nSector = predict.sector;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto bakCstat = pSprite->cstat;
|
|
|
|
pSprite->cstat &= ~CSTAT_SPRITE_BLOCK_ALL;
|
2022-09-08 11:57:17 +00:00
|
|
|
ClipMove(&predict.pos, &nSector, predict.xvel >> 12, predict.yvel >> 12, wd, tz, bz, CLIPMASK0, predict.hit.hit);
|
2021-12-29 21:56:21 +00:00
|
|
|
if (nSector == -1)
|
|
|
|
nSector = predict.sector;
|
|
|
|
|
|
|
|
if (sector[nSector].type >= kSectorPath && sector[nSector].type <= kSectorRotate)
|
|
|
|
{
|
|
|
|
int nSector2 = nSector;
|
|
|
|
pushmove(&predict.pos, &nSector2, wd, tz, bz, CLIPMASK0);
|
|
|
|
if (nSector2 != -1)
|
|
|
|
nSector = nSector2;
|
|
|
|
}
|
|
|
|
|
|
|
|
assert(nSector >= 0);
|
|
|
|
|
|
|
|
pSprite->cstat = bakCstat;
|
|
|
|
}
|
2022-09-08 11:57:17 +00:00
|
|
|
switch (predict.hit.hit.type)
|
2021-12-29 21:56:21 +00:00
|
|
|
{
|
|
|
|
case kHitSprite:
|
|
|
|
{
|
2022-09-08 11:57:17 +00:00
|
|
|
int nHitWall = predict.hit.hit.index;
|
2021-12-29 21:56:21 +00:00
|
|
|
walltype* pHitWall = &wall[nHitWall];
|
|
|
|
if (pHitWall->twoSided())
|
|
|
|
{
|
|
|
|
sectortype* pHitSector = &pHitWall->nextSector();
|
2022-02-02 23:59:12 +00:00
|
|
|
if (top < pHitSector->ceiling z || bottom > pHitSector->floor z)
|
2021-12-29 21:56:21 +00:00
|
|
|
{
|
|
|
|
// ???
|
|
|
|
}
|
|
|
|
}
|
|
|
|
actWallBounceVector(&predict.xvel, &predict.yvel, pHitWall, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (predict.sector != nSector)
|
|
|
|
{
|
|
|
|
assert(validSectorIndex(nSector));
|
|
|
|
predict.sector = nSector;
|
|
|
|
}
|
|
|
|
bool bUnderwater = 0;
|
|
|
|
bool bDepth = 0;
|
|
|
|
if (sector[sector].hasX())
|
|
|
|
{
|
|
|
|
XSECTOR* pXSector = §or[sector].xs();
|
|
|
|
if (pXSector->Underwater)
|
|
|
|
bUnderwater = 1;
|
|
|
|
if (pXSector->Depth)
|
|
|
|
bDepth = 1;
|
|
|
|
}
|
|
|
|
auto nUpperLink = getUpperLink(nSector);
|
|
|
|
auto nLowerLink = getLowerLink(nSector);
|
|
|
|
if (nUpperLink >= 0 && (nUpperLink->spr.type == kMarkerUpWater || nUpperLink->spr.type == kMarkerUpGoo))
|
|
|
|
bDepth = 1;
|
|
|
|
if (nLowerLink >= 0 && (nLowerLink->spr.type == kMarkerLowWater || nLowerLink->spr.type == kMarkerLowGoo))
|
|
|
|
bDepth = 1;
|
|
|
|
if (pPlayer)
|
|
|
|
wd += 16;
|
|
|
|
|
|
|
|
if (predict.zvel)
|
|
|
|
predict.z += predict.zvel >> 8;
|
|
|
|
|
|
|
|
spritetype pSpriteBak; memcpy(&pSpriteBak, pSprite, sizeof(pSpriteBak));
|
|
|
|
auto pTempSprite = pSprite;
|
|
|
|
pTempSprite->x = predict.x;
|
|
|
|
pTempSprite->y = predict.y;
|
|
|
|
pTempSprite->z = predict.z;
|
|
|
|
pTempSprite->sector = predict.sector;
|
|
|
|
int ceilZ, floorZ;
|
|
|
|
Collision ceilColl, floorColl;
|
|
|
|
GetZRange(pTempSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, wd, CLIPMASK0);
|
|
|
|
GetSpriteExtents(pTempSprite, &top, &bottom);
|
2022-09-08 11:57:17 +00:00
|
|
|
if (predict.sprflags & 2)
|
2021-12-29 21:56:21 +00:00
|
|
|
{
|
|
|
|
int vc = 58254;
|
|
|
|
if (bDepth)
|
|
|
|
{
|
|
|
|
if (bUnderwater)
|
|
|
|
{
|
|
|
|
int cz = getceilzofslope(nSector, predict.x, predict.y);
|
|
|
|
if (cz > top)
|
|
|
|
vc += ((bottom - cz) * -80099) / (bottom - top);
|
|
|
|
else
|
|
|
|
vc = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int fz = getflorzofslope(nSector, predict.x, predict.y);
|
|
|
|
if (fz < bottom)
|
|
|
|
vc += ((bottom - fz) * -80099) / (bottom - top);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (bUnderwater)
|
|
|
|
vc = 0;
|
|
|
|
else if (bottom >= floorZ)
|
|
|
|
vc = 0;
|
|
|
|
}
|
|
|
|
if (vc)
|
|
|
|
{
|
|
|
|
predict.z += ((vc * 4) / 2) >> 8;
|
|
|
|
predict.zvel += vc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GetSpriteExtents(pTempSprite, &top, &bottom);
|
|
|
|
if (bottom >= floorZ)
|
|
|
|
{
|
|
|
|
int floorZ2 = floorZ;
|
|
|
|
auto floorHit2 = floorColl;
|
|
|
|
GetZRange(pTempSprite, &ceilZ, &ceilColl, &floorZ, &floorColl, pSprite->clipdist << 2, CLIPMASK0, PARALLAXCLIP_CEILING | PARALLAXCLIP_FLOOR);
|
|
|
|
if (bottom <= floorZ && predict.z - floorZ2 < bz)
|
|
|
|
{
|
|
|
|
floorZ = floorZ2;
|
|
|
|
floorColl = floorHit2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (floorZ <= bottom)
|
|
|
|
{
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.hit.florhit = floorColl;
|
2021-12-29 21:56:21 +00:00
|
|
|
predict.z += floorZ - bottom;
|
|
|
|
int var44 = predict.zvel - predict.sector()->velFloor;
|
|
|
|
if (var44 > 0)
|
|
|
|
{
|
|
|
|
actFloorBounceVector(&predict.xvel, &predict.yvel, &var44, predict.sector, 0);
|
|
|
|
predict.zvel = var44;
|
|
|
|
if (abs(predict.zvel) < 0x10000)
|
|
|
|
{
|
|
|
|
predict.zvel = predict.sector()->velFloor;
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.sprflags &= ~4;
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
|
|
|
else
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.sprflags |= 4;
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
|
|
|
else if (predict.zvel == 0)
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.sprflags &= ~4;
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.hit.florhit.setNone();
|
|
|
|
if (predict.sprflags & 2)
|
|
|
|
predict.sprflags |= 4;
|
2021-12-29 21:56:21 +00:00
|
|
|
}
|
|
|
|
if (top <= ceilZ)
|
|
|
|
{
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.hit.ceilhit = ceilColl;
|
2021-12-29 21:56:21 +00:00
|
|
|
predict.z += ClipLow(ceilZ - top, 0);
|
2022-09-08 11:57:17 +00:00
|
|
|
if (predict.zvel <= 0 && (predict.sprflags & 4))
|
2021-12-29 21:56:21 +00:00
|
|
|
predict.zvel = MulScale(-predict.zvel, 0x2000, 16);
|
|
|
|
}
|
|
|
|
else
|
2022-09-08 11:57:17 +00:00
|
|
|
predict.hit.ceilhit = 0;
|
2021-12-29 21:56:21 +00:00
|
|
|
|
|
|
|
GetSpriteExtents(pTempSprite, &top, &bottom);
|
|
|
|
memcpy(pSprite, &pSpriteBak, sizeof(pSpriteBak));
|
|
|
|
predict.floordist = ClipLow(floorZ - bottom, 0) >> 8;
|
|
|
|
if (predict.xvel || predict.yvel)
|
|
|
|
{
|
|
|
|
if (floorColl.type == kHitSprite)
|
|
|
|
{
|
|
|
|
auto hitactor = floorColl.actor;
|
|
|
|
if ((hitactor->spr.cstat & 0x30) == 0)
|
|
|
|
{
|
|
|
|
predict.xvel += MulScale(4, predict.x - hitactor->spr.x, 2);
|
|
|
|
predict.yvel += MulScale(4, predict.y - hitactor->spr.y, 2);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (pSprite->sector()->hasX() && pSprite->sector()->xs().Underwater)
|
|
|
|
return;
|
|
|
|
if (predict.floordist >= 0x100)
|
|
|
|
return;
|
|
|
|
int nDrag = gDudeDrag;
|
|
|
|
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;
|
|
|
|
}
|
2021-09-04 18:19:38 +00:00
|
|
|
#endif
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
|
|
|
|
2021-12-29 21:56:21 +00:00
|
|
|
static void fakeActAirDrag(DBloodActor*, int num)
|
2020-08-02 17:43:45 +00:00
|
|
|
{
|
2021-11-20 18:10:02 +00:00
|
|
|
#if 0
|
2021-12-29 21:56:21 +00:00
|
|
|
int xvec = 0;
|
|
|
|
int yvec = 0;
|
|
|
|
assert(validSectorIndex(predict.sector));
|
|
|
|
sectortype* pSector = §or[predict.sector];
|
|
|
|
if (pSector->hasX())
|
|
|
|
{
|
|
|
|
XSECTOR* pXSector = &pSector->xs();
|
|
|
|
if (pXSector->windVel && (pXSector->windAlways || pXSector->busy))
|
|
|
|
{
|
|
|
|
int vel = pXSector->windVel << 12;
|
|
|
|
if (!pXSector->windAlways && pXSector->busy)
|
|
|
|
vel = MulScale(vel, pXSector->busy, 16);
|
|
|
|
xvec = MulScale(vel, Cos(pXSector->windAng), 30);
|
|
|
|
yvec = MulScale(vel, Sin(pXSector->windAng), 30);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
2021-12-23 12:28:21 +00:00
|
|
|
auto pSprite = gMe->actor;
|
2020-08-02 17:43:45 +00:00
|
|
|
if (pSprite->statnum == kStatDude)
|
|
|
|
{
|
2021-12-01 23:13:07 +00:00
|
|
|
int nSector = predict.sector;
|
2021-12-29 21:56:21 +00:00
|
|
|
auto pSector = §or[predict.sector];
|
|
|
|
auto pXSector = pSector->hasX() ? &pSector->xs() : nullptr;
|
2020-08-02 17:43:45 +00:00
|
|
|
if (pXSector)
|
|
|
|
{
|
2021-12-29 21:56:21 +00:00
|
|
|
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;
|
2021-12-29 21:56:21 +00:00
|
|
|
int speed = 0;
|
2020-08-02 17:43:45 +00:00
|
|
|
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-12-29 21:56:21 +00:00
|
|
|
if (pSector->floorstat & 64)
|
|
|
|
angle = (GetWallAngle(pSector->firstWall()) + 512) & 2047;
|
|
|
|
predict.xvel += MulScale(speed, Cos(angle), 30);
|
|
|
|
predict.yvel += MulScale(speed, Sin(angle), 30);
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
|
|
|
}
|
2021-12-29 21:56:21 +00:00
|
|
|
if (pXSector && pXSector->Underwater)
|
|
|
|
fakeActAirDrag(pSprite, 5376);
|
|
|
|
else
|
|
|
|
fakeActAirDrag(pSprite, 128);
|
|
|
|
|
2022-09-08 11:57:17 +00:00
|
|
|
if ((predict.sprflags & 4) != 0 || predict.xvel != 0 || predict.yvel != 0 || predict.zvel != 0 || predict.sector()->velFloor != 0 || predict.sector()->velCeil != 0)
|
2021-12-29 21:56:21 +00:00
|
|
|
{
|
|
|
|
fakeMoveDude(pSprite);
|
|
|
|
}
|
2020-08-02 17:43:45 +00:00
|
|
|
}
|
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
|
2021-12-29 21:56:21 +00:00
|
|
|
auto pSprite = gMe->actor;
|
|
|
|
VIEW* pView = &predictFifo[(gNetFifoTail - 1) & 255];
|
|
|
|
if (gMe->angle.ang != pView->at30 || pView->at24 != gMe->horizon.horiz || pView->at50 != pSprite->x || pView->at54 != pSprite->y || pView->at58 != pSprite->z)
|
|
|
|
{
|
|
|
|
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
|