- Move crouch toggling back into the backend so the toggle key can be used as a swim key.

* Reverts 272dfa762d, but is a fresh implementation.
* I doubted anyone was doing this but apparently not.
* Exhumed needed a bit more work as it has very specific underwater checks.
This commit is contained in:
Mitchell Richters 2023-09-24 13:40:15 +10:00
parent 615267dbd4
commit 29e021b5bf
19 changed files with 124 additions and 134 deletions

View file

@ -52,6 +52,7 @@ CUSTOM_CVAR(Int, cl_viewtilting, 0, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
GameInput gameInput{}; GameInput gameInput{};
bool crouch_toggle = false;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -78,32 +79,6 @@ bool scaletozero(DAngle& angle, const double scale, const double push)
} }
//---------------------------------------------------------------------------
//
// Handle all the game-side crouch requirements.
//
//---------------------------------------------------------------------------
void processCrouchToggle(bool& toggle, ESyncBits& actions, const bool crouchable, const bool disabletoggle)
{
if (actions & SB_CROUCH_LOCK)
{
toggle = !toggle && crouchable;
actions &= ~SB_CROUCH_LOCK;
}
if ((actions & (SB_CROUCH|SB_JUMP)) || disabletoggle)
{
toggle = 0;
}
if (toggle)
{
actions |= SB_CROUCH;
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// Player's movement function, called from game's ticker or from gi->doPlayerMovement() as required. // Player's movement function, called from game's ticker or from gi->doPlayerMovement() as required.
@ -285,6 +260,7 @@ void GameInput::processInputBits()
else dpad_lock = 0; else dpad_lock = 0;
gi->reapplyInputBits(&inputBuffer); gi->reapplyInputBits(&inputBuffer);
const auto crouchState = gi->getCrouchState();
inputBuffer.actions |= ActionsToSend; inputBuffer.actions |= ActionsToSend;
ActionsToSend = 0; ActionsToSend = 0;
@ -301,21 +277,25 @@ void GameInput::processInputBits()
inputBuffer.actions &= ~SB_CENTERVIEW; inputBuffer.actions &= ~SB_CENTERVIEW;
} }
if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch))
{
const bool canCrouch = crouchState & CS_CANCROUCH;
crouch_toggle = !crouch_toggle && canCrouch;
if (canCrouch) buttonMap.ClearButton(gamefunc_Toggle_Crouch);
}
if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Jump) || (crouchState & CS_DISABLETOGGLE))
crouch_toggle = false;
if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || crouch_toggle)
inputBuffer.actions |= SB_CROUCH;
if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming))
joyAxes[JOYAXIS_Forward] = 0; joyAxes[JOYAXIS_Forward] = 0;
if (buttonMap.ButtonDown(gamefunc_Jump)) if (buttonMap.ButtonDown(gamefunc_Jump))
inputBuffer.actions |= SB_JUMP; inputBuffer.actions |= SB_JUMP;
if (buttonMap.ButtonDown(gamefunc_Crouch))
inputBuffer.actions |= SB_CROUCH;
if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch))
{
inputBuffer.actions |= SB_CROUCH_LOCK;
buttonMap.ClearButton(gamefunc_Toggle_Crouch);
}
if (buttonMap.ButtonDown(gamefunc_Fire)) if (buttonMap.ButtonDown(gamefunc_Fire))
inputBuffer.actions |= SB_FIRE; inputBuffer.actions |= SB_FIRE;
@ -327,6 +307,7 @@ void GameInput::processInputBits()
if (isBlood() || isExhumed()) buttonMap.ClearButton(gamefunc_Open); if (isBlood() || isExhumed()) buttonMap.ClearButton(gamefunc_Open);
inputBuffer.actions |= SB_OPEN; inputBuffer.actions |= SB_OPEN;
} }
if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run))) if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)))
inputBuffer.actions |= SB_RUN; inputBuffer.actions |= SB_RUN;

View file

@ -3,6 +3,12 @@
#include "serializer.h" #include "serializer.h"
#include "gamefuncs.h" #include "gamefuncs.h"
enum : unsigned
{
CS_CANCROUCH = 1,
CS_DISABLETOGGLE = 2,
};
inline double getTicrateScale(const double value) inline double getTicrateScale(const double value)
{ {
return value / GameTicRate; return value / GameTicRate;
@ -173,5 +179,4 @@ extern GameInput gameInput;
class FSerializer; class FSerializer;
FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def); FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def);
void processCrouchToggle(bool& toggle, ESyncBits& actions, const bool crouchable, const bool disabletoggle);
bool scaletozero(DAngle& angle, const double scale, const double push = (7646143. / 110386328.)); bool scaletozero(DAngle& angle, const double scale, const double push = (7646143. / 110386328.));

View file

@ -120,6 +120,7 @@ struct GameInterface
virtual void StartSoundEngine() = 0; virtual void StartSoundEngine() = 0;
virtual void reapplyInputBits(InputPacket* const input) = 0; virtual void reapplyInputBits(InputPacket* const input) = 0;
virtual void doPlayerMovement(const float scaleAdjust) = 0; virtual void doPlayerMovement(const float scaleAdjust) = 0;
virtual unsigned getCrouchState() = 0;
virtual FString statFPS() virtual FString statFPS()
{ {

View file

@ -34,11 +34,10 @@ enum ESyncBits_ : uint32_t
SB_LOOK_UP = SB_AIM_UP|SB_CENTERVIEW, SB_LOOK_UP = SB_AIM_UP|SB_CENTERVIEW,
SB_LOOK_DOWN = SB_AIM_DOWN|SB_CENTERVIEW, SB_LOOK_DOWN = SB_AIM_DOWN|SB_CENTERVIEW,
SB_CROUCH = 1 << 25, SB_CROUCH = 1 << 25,
SB_CROUCH_LOCK = 1 << 26, SB_RUN = 1 << 26,
SB_RUN = 1 << 27, SB_JUMP = 1 << 27,
SB_JUMP = 1 << 28, SB_FIRE = 1 << 28,
SB_FIRE = 1 << 29, SB_ALTFIRE = 1 << 29,
SB_ALTFIRE = 1 << 30,
SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits
SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1),

View file

@ -72,6 +72,7 @@
void WriteSavePic(FileWriter* file, int width, int height); void WriteSavePic(FileWriter* file, int width, int height);
extern bool crouch_toggle;
extern FString savename; extern FString savename;
extern FString BackupSaveGame; extern FString BackupSaveGame;
int SaveVersion; int SaveVersion;
@ -89,6 +90,21 @@ END_BLD_NS
// //
//============================================================================= //=============================================================================
static void SerializeGlobals(FSerializer& arc)
{
if (arc.BeginObject("globals"))
{
arc("crouch_toggle", crouch_toggle)
.EndObject();
}
}
//=============================================================================
//
//
//
//=============================================================================
static void SerializeSession(FSerializer& arc) static void SerializeSession(FSerializer& arc)
{ {
// Only Exhumed still depends in indexed sounds. // Only Exhumed still depends in indexed sounds.
@ -103,6 +119,7 @@ static void SerializeSession(FSerializer& arc)
S_SerializeSounds(arc); S_SerializeSounds(arc);
SerializeAutomap(arc); SerializeAutomap(arc);
SerializeHud(arc); SerializeHud(arc);
SerializeGlobals(arc);
gi->SerializeGameState(arc); gi->SerializeGameState(arc);
} }

View file

@ -146,6 +146,7 @@ struct GameInterface : public ::GameInterface
void StartSoundEngine() override; void StartSoundEngine() override;
void reapplyInputBits(InputPacket* const input) override { input->actions |= gPlayer[myconnectindex].input.actions & (~(SB_BUTTON_MASK | SB_RUN | SB_WEAPONMASK_BITS) | SB_CENTERVIEW); } void reapplyInputBits(InputPacket* const input) override { input->actions |= gPlayer[myconnectindex].input.actions & (~(SB_BUTTON_MASK | SB_RUN | SB_WEAPONMASK_BITS) | SB_CENTERVIEW); }
void doPlayerMovement(const float scaleAdjust) override { gameInput.processMovement(&gPlayer[myconnectindex].Angles, scaleAdjust); } void doPlayerMovement(const float scaleAdjust) override { gameInput.processMovement(&gPlayer[myconnectindex].Angles, scaleAdjust); }
unsigned getCrouchState() override;
GameStats getStats() override; GameStats getStats() override;
}; };

View file

@ -901,7 +901,6 @@ void playerStart(int nPlayer, int bNewLevel)
#endif #endif
pPlayer->hand = 0; pPlayer->hand = 0;
pPlayer->nWaterPal = 0; pPlayer->nWaterPal = 0;
pPlayer->crouch_toggle = false;
playerResetPowerUps(pPlayer); playerResetPowerUps(pPlayer);
if (nPlayer == myconnectindex) if (nPlayer == myconnectindex)
@ -1500,6 +1499,18 @@ int ActionScan(PLAYER* pPlayer, HitInfo* out)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
unsigned GameInterface::getCrouchState()
{
const bool swimming = gPlayer[myconnectindex].posture == kPostureSwim;
return (CS_CANCROUCH * !swimming) | (CS_DISABLETOGGLE * swimming);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void ProcessInput(PLAYER* pPlayer) void ProcessInput(PLAYER* pPlayer)
{ {
enum enum
@ -1583,8 +1594,6 @@ void ProcessInput(PLAYER* pPlayer)
if (!(pInput->actions & SB_JUMP)) if (!(pInput->actions & SB_JUMP))
pPlayer->cantJump = 0; pPlayer->cantJump = 0;
processCrouchToggle(pPlayer->crouch_toggle, pInput->actions, pPlayer->posture != kPostureSwim, pPlayer->posture == kPostureSwim);
switch (pPlayer->posture) { switch (pPlayer->posture) {
case kPostureSwim: case kPostureSwim:
{ {
@ -2482,7 +2491,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PLAYER& w, PLAYER*
("quakeeffect", w.quakeEffect) ("quakeeffect", w.quakeEffect)
("player_par", w.player_par) ("player_par", w.player_par)
("waterpal", w.nWaterPal) ("waterpal", w.nWaterPal)
("crouch_toggle", w.crouch_toggle)
.Array("posturedata", &w.pPosture[0][0], &gPostureDefaults[0][0], kModeMax * kPostureMax) // only save actual changes in this. .Array("posturedata", &w.pPosture[0][0], &gPostureDefaults[0][0], kModeMax * kPostureMax) // only save actual changes in this.
.EndObject(); .EndObject();
} }

View file

@ -178,7 +178,6 @@ struct PLAYER
int quakeEffect; int quakeEffect;
int player_par; int player_par;
int nWaterPal; int nWaterPal;
bool crouch_toggle;
POSTURE pPosture[kModeMax][kPostureMax]; POSTURE pPosture[kModeMax][kPostureMax];
}; };

View file

@ -42,6 +42,7 @@ struct GameInterface : public ::GameInterface
void DrawPlayerSprite(const DVector2& origin, bool onteam) override; void DrawPlayerSprite(const DVector2& origin, bool onteam) override;
void reapplyInputBits(InputPacket* const input) override { input->actions |= ps[myconnectindex].sync.actions & SB_CENTERVIEW; } void reapplyInputBits(InputPacket* const input) override { input->actions |= ps[myconnectindex].sync.actions & SB_CENTERVIEW; }
void doPlayerMovement(const float scaleAdjust) override; void doPlayerMovement(const float scaleAdjust) override;
unsigned getCrouchState() override;
void UpdateSounds() override; void UpdateSounds() override;
void Startup() override; void Startup() override;
void DrawBackground() override; void DrawBackground() override;

View file

@ -67,13 +67,6 @@ void hud_input(int plnum)
// Backup weapon here as hud_input() is the first function where any one of the weapon variables can change. // Backup weapon here as hud_input() is the first function where any one of the weapon variables can change.
p->backupweapon(); p->backupweapon();
// Set-up crouch bools.
const int sectorLotag = p->insector() ? p->cursector->lotag : 0;
const bool crouchable = sectorLotag != ST_2_UNDERWATER && (sectorLotag != ST_1_ABOVE_WATER || p->spritebridge) && !p->jetpack_on;
const bool disableToggle = p->jetpack_on || (!crouchable && p->on_ground) || (isRRRA() && (p->OnMotorcycle || p->OnBoat));
processCrouchToggle(p->crouch_toggle, p->sync.actions, crouchable, disableToggle);
if (isRR() && (p->sync.actions & SB_CROUCH)) p->sync.actions &= ~SB_JUMP; if (isRR() && (p->sync.actions & SB_CROUCH)) p->sync.actions &= ~SB_JUMP;
if ((isRR() && p->drink_amt > 88)) if ((isRR() && p->drink_amt > 88))
@ -495,6 +488,21 @@ void hud_input(int plnum)
} }
} }
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
unsigned GameInterface::getCrouchState()
{
const auto p = &ps[myconnectindex];
const int sectorLotag = p->insector() ? p->cursector->lotag : 0;
const int crouchable = sectorLotag != ST_2_UNDERWATER && (sectorLotag != ST_1_ABOVE_WATER || p->spritebridge) && !p->jetpack_on;
const int disableToggle = (!crouchable && p->on_ground) || p->jetpack_on || (isRRRA() && (p->OnMotorcycle || p->OnBoat));
return (CS_CANCROUCH * crouchable) | (CS_DISABLETOGGLE * disableToggle);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// External entry point // External entry point

View file

@ -90,7 +90,6 @@ void resetplayerstats(int snum)
p = &ps[snum]; p = &ps[snum];
gFullMap = 0; gFullMap = 0;
p->crouch_toggle = 0;
p->dead_flag = 0; p->dead_flag = 0;
p->wackedbyactor = nullptr; p->wackedbyactor = nullptr;
p->falling_counter = 0; p->falling_counter = 0;

View file

@ -269,7 +269,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
.Array("frags", w.frags, MAXPLAYERS) .Array("frags", w.frags, MAXPLAYERS)
("uservars", w.uservars) ("uservars", w.uservars)
("fistsign", w.fistsign) ("fistsign", w.fistsign)
("crouch_toggle", w.crouch_toggle)
.EndObject(); .EndObject();
w.invdisptime = 0; w.invdisptime = 0;

View file

@ -350,8 +350,6 @@ struct player_struct
TArray<GameVarValue> uservars; TArray<GameVarValue> uservars;
bool crouch_toggle;
// input stuff. // input stuff.
InputPacket sync; InputPacket sync;

View file

@ -242,6 +242,7 @@ struct GameInterface : public ::GameInterface
void StartSoundEngine() override; void StartSoundEngine() override;
void reapplyInputBits(InputPacket* const input) override { input->actions |= PlayerList[nLocalPlayer].input.actions & SB_CENTERVIEW; } void reapplyInputBits(InputPacket* const input) override { input->actions |= PlayerList[nLocalPlayer].input.actions & SB_CENTERVIEW; }
void doPlayerMovement(const float scaleAdjust) override { gameInput.processMovement(&PlayerList[nLocalPlayer].Angles, scaleAdjust); } void doPlayerMovement(const float scaleAdjust) override { gameInput.processMovement(&PlayerList[nLocalPlayer].Angles, scaleAdjust); }
unsigned getCrouchState() override;
::GameStats getStats() override; ::GameStats getStats() override;
}; };

View file

@ -309,7 +309,6 @@ void RestartPlayer(int nPlayer)
pPlayer->nQuake = 0; pPlayer->nQuake = 0;
pPlayer->nTemperature = 0; pPlayer->nTemperature = 0;
pPlayer->nStandHeight = GetActorHeight(pPlayerActor); pPlayer->nStandHeight = GetActorHeight(pPlayerActor);
pPlayer->crouch_toggle = false;
SetTorch(nPlayer, 0); SetTorch(nPlayer, 0);
if (nNetPlayerCount) if (nNetPlayerCount)
@ -1224,12 +1223,24 @@ static void updatePlayerWeapon(Player* const pPlayer)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater) unsigned GameInterface::getCrouchState()
{
const bool swimming = PlayerList[nLocalPlayer].bUnderwater;
return (CS_CANCROUCH * !swimming) | (CS_DISABLETOGGLE * swimming);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static void updatePlayerAction(Player* const pPlayer)
{ {
const auto pPlayerActor = pPlayer->pActor; const auto pPlayerActor = pPlayer->pActor;
const auto pInput = &pPlayer->input; const auto pInput = &pPlayer->input;
const auto kbdDir = !!(pInput->actions & SB_CROUCH) - !!(pInput->actions & SB_JUMP); const auto kbdDir = !!(pInput->actions & SB_CROUCH) - !!(pInput->actions & SB_JUMP);
const double dist = bUnderwater ? 8 : 14; const double dist = pPlayer->bUnderwater ? 8 : 14;
const double velZ = clamp(dist * kbdDir - dist * pInput->uvel, -dist, dist); const double velZ = clamp(dist * kbdDir - dist * pInput->uvel, -dist, dist);
int nextAction = pPlayerActor->nAction; int nextAction = pPlayerActor->nAction;
@ -1240,11 +1251,9 @@ static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater)
if (!pPlayer->bIsMummified) if (!pPlayer->bIsMummified)
{ {
processCrouchToggle(pPlayer->crouch_toggle, pInput->actions, !bUnderwater, bUnderwater);
if (velZ < 0) if (velZ < 0)
{ {
if (bUnderwater) if (pPlayer->bUnderwater)
{ {
pPlayerActor->vel.Z = velZ; pPlayerActor->vel.Z = velZ;
nextAction = 10; nextAction = 10;
@ -1258,7 +1267,7 @@ static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater)
} }
else if (velZ > 0) else if (velZ > 0)
{ {
if (bUnderwater) if (pPlayer->bUnderwater)
{ {
pPlayerActor->vel.Z = velZ; pPlayerActor->vel.Z = velZ;
nextAction = 10; nextAction = 10;
@ -1292,7 +1301,7 @@ static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater)
scaleViewZ(nActionEyeLevel[pPlayerActor->nAction]); scaleViewZ(nActionEyeLevel[pPlayerActor->nAction]);
} }
if (bUnderwater) if (pPlayer->bUnderwater)
{ {
nextAction = 10 - (pPlayer->totalvel <= 0.0625); nextAction = 10 - (pPlayer->totalvel <= 0.0625);
} }
@ -1302,7 +1311,7 @@ static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater)
} }
else if (pPlayer->totalvel <= 0.0625) else if (pPlayer->totalvel <= 0.0625)
{ {
nextAction = bUnderwater; nextAction = pPlayer->bUnderwater;
} }
else if (pPlayer->totalvel <= 1.875) else if (pPlayer->totalvel <= 1.875)
{ {
@ -1316,7 +1325,7 @@ static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater)
if (!bTallerThanSector && (pInput->actions & SB_FIRE)) // was var_38 if (!bTallerThanSector && (pInput->actions & SB_FIRE)) // was var_38
{ {
if (bUnderwater) if (pPlayer->bUnderwater)
{ {
nextAction = 11; nextAction = 11;
} }
@ -1649,7 +1658,7 @@ static void updatePlayerDoppleActor(Player* const pPlayer)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void updatePlayerViewSector(Player* const pPlayer, const Collision& nMove, const DVector3& spr_vel, const bool bUnderwater) static void updatePlayerViewSector(Player* const pPlayer, const Collision& nMove, const DVector3& spr_vel)
{ {
const auto pPlayerActor = pPlayer->pActor; const auto pPlayerActor = pPlayer->pActor;
const auto pPlayerSect = pPlayerActor->sector(); const auto pPlayerSect = pPlayerActor->sector();
@ -1657,7 +1666,7 @@ static void updatePlayerViewSector(Player* const pPlayer, const Collision& nMove
const auto pViewSect = bPlayerBelowCeil && pPlayerSect->pAbove ? pPlayerSect->pAbove : pPlayerSect; const auto pViewSect = bPlayerBelowCeil && pPlayerSect->pAbove ? pPlayerSect->pAbove : pPlayerSect;
// Do underwater sector check // Do underwater sector check
if (bUnderwater && pViewSect != pPlayerSect && nMove.type == kHitWall) if (pPlayer->bUnderwater && pViewSect != pPlayerSect && nMove.type == kHitWall)
{ {
const auto pos = pPlayerActor->spr.pos; const auto pos = pPlayerActor->spr.pos;
const auto fz = pViewSect->floorz - 20; const auto fz = pViewSect->floorz - 20;
@ -1820,9 +1829,7 @@ static bool doPlayerInput(Player* const pPlayer)
} }
const auto pPlayerSect = pPlayerActor->sector(); const auto pPlayerSect = pPlayerActor->sector();
const bool bUnderwater = pPlayerSect->Flag & kSectUnderwater; if ((pPlayer->bUnderwater = pPlayerSect->Flag & kSectUnderwater))
if (bUnderwater)
pPlayer->nThrust *= 0.5; pPlayer->nThrust *= 0.5;
// Trigger Ramses? // Trigger Ramses?
@ -1854,11 +1861,11 @@ static bool doPlayerInput(Player* const pPlayer)
// Most-move updates. Input bit funcs are here because // Most-move updates. Input bit funcs are here because
// updatePlayerAction() needs access to bUnderwater. // updatePlayerAction() needs access to bUnderwater.
updatePlayerViewSector(pPlayer, nMove, spr_vel, bUnderwater); updatePlayerViewSector(pPlayer, nMove, spr_vel);
updatePlayerFloorActor(pPlayer); updatePlayerFloorActor(pPlayer);
updatePlayerInventory(pPlayer); updatePlayerInventory(pPlayer);
updatePlayerWeapon(pPlayer); updatePlayerWeapon(pPlayer);
updatePlayerAction(pPlayer, bUnderwater); updatePlayerAction(pPlayer);
return true; return true;
} }
@ -2144,7 +2151,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Player& w, Player*
("save", w.sPlayerSave) ("save", w.sPlayerSave)
("totalvel", w.totalvel) ("totalvel", w.totalvel)
("grenade", w.pPlayerGrenade) ("grenade", w.pPlayerGrenade)
("crouch_toggle", w.crouch_toggle) ("bUnderwater", w.bUnderwater)
.EndObject(); .EndObject();
} }

View file

@ -103,7 +103,7 @@ struct Player
double nIdxBobZ; double nIdxBobZ;
double nPrevWeapBob; double nPrevWeapBob;
double nWeapBob; double nWeapBob;
bool crouch_toggle; bool bUnderwater;
bool bTouchFloor; bool bTouchFloor;
bool bJumping; bool bJumping;
bool bRebound; bool bRebound;

View file

@ -548,7 +548,6 @@ enum
PF_DEAD = (BIT(1)), PF_DEAD = (BIT(1)),
PF_JUMPING = (BIT(2)), PF_JUMPING = (BIT(2)),
PF_FALLING = (BIT(3)), PF_FALLING = (BIT(3)),
PF_LOCK_CRAWL = (BIT(4)),
PF_PLAYER_MOVED = (BIT(7)), PF_PLAYER_MOVED = (BIT(7)),
PF_PLAYER_RIDING = (BIT(8)), PF_PLAYER_RIDING = (BIT(8)),
PF_RECOIL = (BIT(10)), PF_RECOIL = (BIT(10)),
@ -1902,6 +1901,7 @@ struct GameInterface : public ::GameInterface
void ExitFromMenu() override; void ExitFromMenu() override;
int GetCurrentSkill() override; int GetCurrentSkill() override;
void StartSoundEngine() override; void StartSoundEngine() override;
unsigned getCrouchState() override;
void reapplyInputBits(InputPacket* const input) override { input->actions |= Player[myconnectindex].input.actions & SB_CENTERVIEW; } void reapplyInputBits(InputPacket* const input) override { input->actions |= Player[myconnectindex].input.actions & SB_CENTERVIEW; }
void doPlayerMovement(const float scaleAdjust) override void doPlayerMovement(const float scaleAdjust) override
{ {

View file

@ -2664,7 +2664,6 @@ void DoPlayerBeginJump(PLAYER* pp)
pp->Flags |= (PF_JUMPING); pp->Flags |= (PF_JUMPING);
pp->Flags &= ~(PF_FALLING); pp->Flags &= ~(PF_FALLING);
pp->Flags &= ~(PF_CRAWLING); pp->Flags &= ~(PF_CRAWLING);
pp->Flags &= ~(PF_LOCK_CRAWL);
pp->p_floor_dist = PLAYER_JUMP_FLOOR_DIST; pp->p_floor_dist = PLAYER_JUMP_FLOOR_DIST;
pp->p_ceiling_dist = PLAYER_JUMP_CEILING_DIST; pp->p_ceiling_dist = PLAYER_JUMP_CEILING_DIST;
@ -2698,7 +2697,7 @@ void DoPlayerBeginForceJump(PLAYER* pp)
DSWActor* plActor = pp->actor; DSWActor* plActor = pp->actor;
pp->Flags |= (PF_JUMPING); pp->Flags |= (PF_JUMPING);
pp->Flags &= ~(PF_FALLING|PF_CRAWLING|PF_CLIMBING|PF_LOCK_CRAWL); pp->Flags &= ~(PF_FALLING|PF_CRAWLING|PF_CLIMBING);
pp->JumpDuration = MAX_JUMP_DURATION; pp->JumpDuration = MAX_JUMP_DURATION;
pp->DoPlayerAction = DoPlayerForceJump; pp->DoPlayerAction = DoPlayerForceJump;
@ -2877,7 +2876,6 @@ void DoPlayerBeginFall(PLAYER* pp)
pp->Flags |= (PF_FALLING); pp->Flags |= (PF_FALLING);
pp->Flags &= ~(PF_JUMPING); pp->Flags &= ~(PF_JUMPING);
pp->Flags &= ~(PF_CRAWLING); pp->Flags &= ~(PF_CRAWLING);
pp->Flags &= ~(PF_LOCK_CRAWL);
pp->p_floor_dist = PLAYER_FALL_FLOOR_DIST; pp->p_floor_dist = PLAYER_FALL_FLOOR_DIST;
pp->p_ceiling_dist = PLAYER_FALL_CEILING_DIST; pp->p_ceiling_dist = PLAYER_FALL_CEILING_DIST;
@ -3084,7 +3082,6 @@ void DoPlayerBeginClimb(PLAYER* pp)
pp->Flags &= ~(PF_JUMPING|PF_FALLING); pp->Flags &= ~(PF_JUMPING|PF_FALLING);
pp->Flags &= ~(PF_CRAWLING); pp->Flags &= ~(PF_CRAWLING);
pp->Flags &= ~(PF_LOCK_CRAWL);
pp->DoPlayerAction = DoPlayerClimb; pp->DoPlayerAction = DoPlayerClimb;
@ -3412,33 +3409,7 @@ void DoPlayerCrawl(PLAYER* pp)
return; return;
} }
if (pp->Flags & PF_LOCK_CRAWL) if ((!(pp->input.actions & SB_CROUCH) || pp->input.uvel > 0) && abs(pp->loz - pp->hiz) >= PLAYER_STANDING_ROOM)
{
if (pp->input.actions & SB_CROUCH_LOCK)
{
if ((pp->KeyPressBits & SB_CROUCH_LOCK) && abs(pp->loz - pp->hiz) >= PLAYER_STANDING_ROOM)
{
pp->KeyPressBits &= ~SB_CROUCH_LOCK;
pp->Flags &= ~PF_CRAWLING;
DoPlayerBeginRun(pp);
return;
}
}
else
{
pp->KeyPressBits |= SB_CROUCH_LOCK;
}
// Jump to get up
if ((pp->input.actions & (SB_JUMP|SB_CROUCH)) && abs(pp->loz - pp->hiz) >= PLAYER_STANDING_ROOM)
{
pp->Flags &= ~PF_CRAWLING;
DoPlayerBeginRun(pp);
return;
}
}
else if (!(pp->input.actions & SB_CROUCH) && pp->input.uvel >= 0 && abs(pp->loz - pp->hiz) >= PLAYER_STANDING_ROOM)
{ {
// Let off of crawl to get up // Let off of crawl to get up
pp->Flags &= ~PF_CRAWLING; pp->Flags &= ~PF_CRAWLING;
@ -4180,7 +4151,6 @@ void DoPlayerBeginDive(PLAYER* pp)
pp->Flags &= ~(PF_JUMPING | PF_FALLING); pp->Flags &= ~(PF_JUMPING | PF_FALLING);
pp->Flags &= ~(PF_CRAWLING); pp->Flags &= ~(PF_CRAWLING);
pp->Flags &= ~(PF_LOCK_CRAWL);
pp->friction = PLAYER_DIVE_FRICTION; pp->friction = PLAYER_DIVE_FRICTION;
pp->p_ceiling_dist = PLAYER_DIVE_CEILING_DIST; pp->p_ceiling_dist = PLAYER_DIVE_CEILING_DIST;
@ -4995,7 +4965,7 @@ void DoPlayerBeginOperate(PLAYER* pp)
calcSlope(pp->cursector, pp->actor->getPosWithOffsetZ(), &cz, &fz); calcSlope(pp->cursector, pp->actor->getPosWithOffsetZ(), &cz, &fz);
pp->posZset(fz - PLAYER_HEIGHTF); pp->posZset(fz - PLAYER_HEIGHTF);
pp->Flags &= ~(PF_CRAWLING|PF_JUMPING|PF_FALLING|PF_LOCK_CRAWL); pp->Flags &= ~(PF_CRAWLING|PF_JUMPING|PF_FALLING);
DoPlayerOperateMatch(pp, true); DoPlayerOperateMatch(pp, true);
@ -5085,7 +5055,7 @@ void DoPlayerBeginRemoteOperate(PLAYER* pp, SECTOR_OBJECT* sop)
calcSlope(pp->cursector, pp->actor->getPosWithOffsetZ(), &cz, &fz); calcSlope(pp->cursector, pp->actor->getPosWithOffsetZ(), &cz, &fz);
pp->posZset(fz - PLAYER_HEIGHTF); pp->posZset(fz - PLAYER_HEIGHTF);
pp->Flags &= ~(PF_CRAWLING|PF_JUMPING|PF_FALLING|PF_LOCK_CRAWL); pp->Flags &= ~(PF_CRAWLING|PF_JUMPING|PF_FALLING);
DoPlayerOperateMatch(pp, true); DoPlayerOperateMatch(pp, true);
@ -5573,7 +5543,7 @@ void DoPlayerBeginDie(PLAYER* pp)
if (pp->Flags & (PF_DIVING)) if (pp->Flags & (PF_DIVING))
pp->DeathType = PLAYER_DEATH_DROWN; pp->DeathType = PLAYER_DEATH_DROWN;
pp->Flags &= ~(PF_JUMPING|PF_FALLING|PF_DIVING|PF_FLYING|PF_CLIMBING|PF_CRAWLING|PF_LOCK_CRAWL); pp->Flags &= ~(PF_JUMPING|PF_FALLING|PF_DIVING|PF_FLYING|PF_CLIMBING|PF_CRAWLING);
ActorCoughItem(pp->actor); ActorCoughItem(pp->actor);
@ -6293,7 +6263,7 @@ void DoPlayerBeginRun(PLAYER* pp)
return; return;
} }
pp->Flags &= ~(PF_CRAWLING|PF_JUMPING|PF_FALLING|PF_LOCK_CRAWL|PF_CLIMBING); pp->Flags &= ~(PF_CRAWLING|PF_JUMPING|PF_FALLING|PF_CLIMBING);
if (pp->WadeDepth) if (pp->WadeDepth)
{ {
@ -6363,22 +6333,6 @@ void DoPlayerRun(PLAYER* pp)
pp->KeyPressBits |= SB_JUMP; pp->KeyPressBits |= SB_JUMP;
} }
// Crawl lock
if (pp->input.actions & SB_CROUCH_LOCK)
{
if (pp->KeyPressBits & SB_CROUCH_LOCK)
{
pp->KeyPressBits &= ~SB_CROUCH_LOCK;
pp->Flags |= PF_LOCK_CRAWL;
DoPlayerBeginCrawl(pp);
return;
}
}
else
{
pp->KeyPressBits |= SB_CROUCH_LOCK;
}
if (PlayerFlyKey()) if (PlayerFlyKey())
{ {
DoPlayerBeginFly(pp); DoPlayerBeginFly(pp);
@ -6471,6 +6425,19 @@ void DoPlayerRun(PLAYER* pp)
DoPlayerHeight(pp); DoPlayerHeight(pp);
} }
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
unsigned GameInterface::getCrouchState()
{
const auto pp = &Player[myconnectindex];
const bool crouchable = true;
const bool disableToggle = (pp->Flags & (PF_JUMPING|PF_FALLING|PF_CLIMBING|PF_DIVING|PF_DEAD)) || pp->sop;
return (CS_CANCROUCH * crouchable) | (CS_DISABLETOGGLE * disableToggle);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //

View file

@ -144,11 +144,10 @@ struct Duke native
SB_LOOK_UP = SB_AIM_UP|SB_CENTERVIEW, SB_LOOK_UP = SB_AIM_UP|SB_CENTERVIEW,
SB_LOOK_DOWN = SB_AIM_DOWN|SB_CENTERVIEW, SB_LOOK_DOWN = SB_AIM_DOWN|SB_CENTERVIEW,
SB_CROUCH = 1 << 25, SB_CROUCH = 1 << 25,
SB_CROUCH_LOCK = 1 << 26, SB_RUN = 1 << 26,
SB_RUN = 1 << 27, SB_JUMP = 1 << 27,
SB_JUMP = 1 << 28, SB_FIRE = 1 << 28,
SB_FIRE = 1 << 29, SB_ALTFIRE = 1 << 29,
SB_ALTFIRE = 1 << 30,
SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits
SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1), SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1),