- 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{};
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.
@ -285,6 +260,7 @@ void GameInput::processInputBits()
else dpad_lock = 0;
gi->reapplyInputBits(&inputBuffer);
const auto crouchState = gi->getCrouchState();
inputBuffer.actions |= ActionsToSend;
ActionsToSend = 0;
@ -301,21 +277,25 @@ void GameInput::processInputBits()
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))
joyAxes[JOYAXIS_Forward] = 0;
if (buttonMap.ButtonDown(gamefunc_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))
inputBuffer.actions |= SB_FIRE;
@ -327,6 +307,7 @@ void GameInput::processInputBits()
if (isBlood() || isExhumed()) buttonMap.ClearButton(gamefunc_Open);
inputBuffer.actions |= SB_OPEN;
}
if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)))
inputBuffer.actions |= SB_RUN;

View file

@ -3,6 +3,12 @@
#include "serializer.h"
#include "gamefuncs.h"
enum : unsigned
{
CS_CANCROUCH = 1,
CS_DISABLETOGGLE = 2,
};
inline double getTicrateScale(const double value)
{
return value / GameTicRate;
@ -173,5 +179,4 @@ extern GameInput gameInput;
class FSerializer;
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.));

View file

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

View file

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

View file

@ -72,6 +72,7 @@
void WriteSavePic(FileWriter* file, int width, int height);
extern bool crouch_toggle;
extern FString savename;
extern FString BackupSaveGame;
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)
{
// Only Exhumed still depends in indexed sounds.
@ -103,6 +119,7 @@ static void SerializeSession(FSerializer& arc)
S_SerializeSounds(arc);
SerializeAutomap(arc);
SerializeHud(arc);
SerializeGlobals(arc);
gi->SerializeGameState(arc);
}

View file

@ -146,6 +146,7 @@ struct GameInterface : public ::GameInterface
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 doPlayerMovement(const float scaleAdjust) override { gameInput.processMovement(&gPlayer[myconnectindex].Angles, scaleAdjust); }
unsigned getCrouchState() override;
GameStats getStats() override;
};

View file

@ -901,7 +901,6 @@ void playerStart(int nPlayer, int bNewLevel)
#endif
pPlayer->hand = 0;
pPlayer->nWaterPal = 0;
pPlayer->crouch_toggle = false;
playerResetPowerUps(pPlayer);
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)
{
enum
@ -1583,8 +1594,6 @@ void ProcessInput(PLAYER* pPlayer)
if (!(pInput->actions & SB_JUMP))
pPlayer->cantJump = 0;
processCrouchToggle(pPlayer->crouch_toggle, pInput->actions, pPlayer->posture != kPostureSwim, pPlayer->posture == kPostureSwim);
switch (pPlayer->posture) {
case kPostureSwim:
{
@ -2482,7 +2491,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PLAYER& w, PLAYER*
("quakeeffect", w.quakeEffect)
("player_par", w.player_par)
("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.
.EndObject();
}

View file

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

View file

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

View file

@ -90,7 +90,6 @@ void resetplayerstats(int snum)
p = &ps[snum];
gFullMap = 0;
p->crouch_toggle = 0;
p->dead_flag = 0;
p->wackedbyactor = nullptr;
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)
("uservars", w.uservars)
("fistsign", w.fistsign)
("crouch_toggle", w.crouch_toggle)
.EndObject();
w.invdisptime = 0;

View file

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

View file

@ -242,6 +242,7 @@ struct GameInterface : public ::GameInterface
void StartSoundEngine() override;
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); }
unsigned getCrouchState() override;
::GameStats getStats() override;
};

View file

@ -309,7 +309,6 @@ void RestartPlayer(int nPlayer)
pPlayer->nQuake = 0;
pPlayer->nTemperature = 0;
pPlayer->nStandHeight = GetActorHeight(pPlayerActor);
pPlayer->crouch_toggle = false;
SetTorch(nPlayer, 0);
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 pInput = &pPlayer->input;
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);
int nextAction = pPlayerActor->nAction;
@ -1240,11 +1251,9 @@ static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater)
if (!pPlayer->bIsMummified)
{
processCrouchToggle(pPlayer->crouch_toggle, pInput->actions, !bUnderwater, bUnderwater);
if (velZ < 0)
{
if (bUnderwater)
if (pPlayer->bUnderwater)
{
pPlayerActor->vel.Z = velZ;
nextAction = 10;
@ -1258,7 +1267,7 @@ static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater)
}
else if (velZ > 0)
{
if (bUnderwater)
if (pPlayer->bUnderwater)
{
pPlayerActor->vel.Z = velZ;
nextAction = 10;
@ -1292,7 +1301,7 @@ static void updatePlayerAction(Player* const pPlayer, const bool bUnderwater)
scaleViewZ(nActionEyeLevel[pPlayerActor->nAction]);
}
if (bUnderwater)
if (pPlayer->bUnderwater)
{
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)
{
nextAction = bUnderwater;
nextAction = pPlayer->bUnderwater;
}
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 (bUnderwater)
if (pPlayer->bUnderwater)
{
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 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;
// 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 fz = pViewSect->floorz - 20;
@ -1820,9 +1829,7 @@ static bool doPlayerInput(Player* const pPlayer)
}
const auto pPlayerSect = pPlayerActor->sector();
const bool bUnderwater = pPlayerSect->Flag & kSectUnderwater;
if (bUnderwater)
if ((pPlayer->bUnderwater = pPlayerSect->Flag & kSectUnderwater))
pPlayer->nThrust *= 0.5;
// Trigger Ramses?
@ -1854,11 +1861,11 @@ static bool doPlayerInput(Player* const pPlayer)
// Most-move updates. Input bit funcs are here because
// updatePlayerAction() needs access to bUnderwater.
updatePlayerViewSector(pPlayer, nMove, spr_vel, bUnderwater);
updatePlayerViewSector(pPlayer, nMove, spr_vel);
updatePlayerFloorActor(pPlayer);
updatePlayerInventory(pPlayer);
updatePlayerWeapon(pPlayer);
updatePlayerAction(pPlayer, bUnderwater);
updatePlayerAction(pPlayer);
return true;
}
@ -2144,7 +2151,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, Player& w, Player*
("save", w.sPlayerSave)
("totalvel", w.totalvel)
("grenade", w.pPlayerGrenade)
("crouch_toggle", w.crouch_toggle)
("bUnderwater", w.bUnderwater)
.EndObject();
}

View file

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

View file

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

View file

@ -2664,7 +2664,6 @@ void DoPlayerBeginJump(PLAYER* pp)
pp->Flags |= (PF_JUMPING);
pp->Flags &= ~(PF_FALLING);
pp->Flags &= ~(PF_CRAWLING);
pp->Flags &= ~(PF_LOCK_CRAWL);
pp->p_floor_dist = PLAYER_JUMP_FLOOR_DIST;
pp->p_ceiling_dist = PLAYER_JUMP_CEILING_DIST;
@ -2698,7 +2697,7 @@ void DoPlayerBeginForceJump(PLAYER* pp)
DSWActor* plActor = pp->actor;
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->DoPlayerAction = DoPlayerForceJump;
@ -2877,7 +2876,6 @@ void DoPlayerBeginFall(PLAYER* pp)
pp->Flags |= (PF_FALLING);
pp->Flags &= ~(PF_JUMPING);
pp->Flags &= ~(PF_CRAWLING);
pp->Flags &= ~(PF_LOCK_CRAWL);
pp->p_floor_dist = PLAYER_FALL_FLOOR_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_CRAWLING);
pp->Flags &= ~(PF_LOCK_CRAWL);
pp->DoPlayerAction = DoPlayerClimb;
@ -3412,33 +3409,7 @@ void DoPlayerCrawl(PLAYER* pp)
return;
}
if (pp->Flags & PF_LOCK_CRAWL)
{
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)
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
pp->Flags &= ~PF_CRAWLING;
@ -4180,7 +4151,6 @@ void DoPlayerBeginDive(PLAYER* pp)
pp->Flags &= ~(PF_JUMPING | PF_FALLING);
pp->Flags &= ~(PF_CRAWLING);
pp->Flags &= ~(PF_LOCK_CRAWL);
pp->friction = PLAYER_DIVE_FRICTION;
pp->p_ceiling_dist = PLAYER_DIVE_CEILING_DIST;
@ -4995,7 +4965,7 @@ void DoPlayerBeginOperate(PLAYER* pp)
calcSlope(pp->cursector, pp->actor->getPosWithOffsetZ(), &cz, &fz);
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);
@ -5085,7 +5055,7 @@ void DoPlayerBeginRemoteOperate(PLAYER* pp, SECTOR_OBJECT* sop)
calcSlope(pp->cursector, pp->actor->getPosWithOffsetZ(), &cz, &fz);
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);
@ -5573,7 +5543,7 @@ void DoPlayerBeginDie(PLAYER* pp)
if (pp->Flags & (PF_DIVING))
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);
@ -6293,7 +6263,7 @@ void DoPlayerBeginRun(PLAYER* pp)
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)
{
@ -6363,22 +6333,6 @@ void DoPlayerRun(PLAYER* pp)
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())
{
DoPlayerBeginFly(pp);
@ -6471,6 +6425,19 @@ void DoPlayerRun(PLAYER* 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_DOWN = SB_AIM_DOWN|SB_CENTERVIEW,
SB_CROUCH = 1 << 25,
SB_CROUCH_LOCK = 1 << 26,
SB_RUN = 1 << 27,
SB_JUMP = 1 << 28,
SB_FIRE = 1 << 29,
SB_ALTFIRE = 1 << 30,
SB_RUN = 1 << 26,
SB_JUMP = 1 << 27,
SB_FIRE = 1 << 28,
SB_ALTFIRE = 1 << 29,
SB_WEAPONMASK_BITS = (15u * SB_FIRST_WEAPON_BIT), // Weapons take up 4 bits
SB_ITEMUSE_BITS = (127u * SB_ITEM_BIT_1),