diff --git a/src/d_player.h b/src/d_player.h index edc611a69e..7c20b85dd0 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -567,8 +567,6 @@ inline bool AActor::IsNoClip2() const return false; } -#define CROUCHSPEED (1./12) - bool P_IsPlayerTotallyFrozen(const player_t *player); #endif // __D_PLAYER_H__ diff --git a/src/g_level.cpp b/src/g_level.cpp index d9d28b72f1..7d1cf41698 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1464,6 +1464,12 @@ bool FLevelLocals::IsCrouchingAllowed() const return !(flags & LEVEL_CROUCH_NO); } +DEFINE_ACTION_FUNCTION(FLevelLocals, IsCrouchingAllowed) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + ACTION_RETURN_BOOL(self->IsCrouchingAllowed()); +} + //========================================================================== // // diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 12130c2b1c..3c423bbf2e 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -3270,6 +3270,14 @@ void P_CheckFakeFloorTriggers (AActor *mo, double oldz, bool oldz_has_viewheight } } +DEFINE_ACTION_FUNCTION(AActor, CheckFakeFloorTriggers) +{ + PARAM_SELF_PROLOGUE(AActor); + PARAM_FLOAT(oldz); + PARAM_BOOL_DEF(oldz_has_viewh); + P_CheckFakeFloorTriggers(self, oldz, oldz_has_viewh); + return 0; +} //=========================================================================== // // PlayerLandedOnThing diff --git a/src/p_user.cpp b/src/p_user.cpp index 5e3958bafc..ff22ae7ea1 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -2520,200 +2520,6 @@ void P_DeathThink (player_t *player) } } -//---------------------------------------------------------------------------- -// -// PROC P_CrouchMove -// -//---------------------------------------------------------------------------- - -void P_CrouchMove(player_t * player, int direction) -{ - double defaultheight = player->mo->FullHeight; - double savedheight = player->mo->Height; - double crouchspeed = direction * CROUCHSPEED; - double oldheight = player->viewheight; - - player->crouchdir = (signed char) direction; - player->crouchfactor += crouchspeed; - - // check whether the move is ok - player->mo->Height = defaultheight * player->crouchfactor; - if (!P_TryMove(player->mo, player->mo->Pos(), false, NULL)) - { - player->mo->Height = savedheight; - if (direction > 0) - { - // doesn't fit - player->crouchfactor -= crouchspeed; - return; - } - } - player->mo->Height = savedheight; - - player->crouchfactor = clamp(player->crouchfactor, 0.5, 1.); - player->viewheight = player->mo->ViewHeight * player->crouchfactor; - player->crouchviewdelta = player->viewheight - player->mo->ViewHeight; - - // Check for eyes going above/below fake floor due to crouching motion. - P_CheckFakeFloorTriggers(player->mo, player->mo->Z() + oldheight, true); -} - -//---------------------------------------------------------------------------- -// -// PROC P_CheckFOV -// -//---------------------------------------------------------------------------- - -void P_CheckFOV(player_t *player) -{ - // [RH] Zoom the player's FOV - float desired = player->DesiredFOV; - // Adjust FOV using on the currently held weapon. - if (player->playerstate != PST_DEAD && // No adjustment while dead. - player->ReadyWeapon != NULL && // No adjustment if no weapon. - player->ReadyWeapon->FOVScale != 0) // No adjustment if the adjustment is zero. - { - // A negative scale is used to prevent G_AddViewAngle/G_AddViewPitch - // from scaling with the FOV scale. - desired *= fabsf(player->ReadyWeapon->FOVScale); - } - if (player->FOV != desired) - { - if (fabsf(player->FOV - desired) < 7.f) - { - player->FOV = desired; - } - else - { - float zoom = MAX(7.f, fabsf(player->FOV - desired) * 0.025f); - if (player->FOV > desired) - { - player->FOV = player->FOV - zoom; - } - else - { - player->FOV = player->FOV + zoom; - } - } - } -} - -//---------------------------------------------------------------------------- -// -// PROC P_CheckCheats -// -//---------------------------------------------------------------------------- - -void P_CheckCheats(player_t *player) -{ - // No-clip cheat - if ((player->cheats & (CF_NOCLIP | CF_NOCLIP2)) == CF_NOCLIP2) - { // No noclip2 without noclip - player->cheats &= ~CF_NOCLIP2; - } - if (player->cheats & (CF_NOCLIP | CF_NOCLIP2) || (player->mo->GetDefault()->flags & MF_NOCLIP)) - { - player->mo->flags |= MF_NOCLIP; - } - else - { - player->mo->flags &= ~MF_NOCLIP; - } - if (player->cheats & CF_NOCLIP2) - { - player->mo->flags |= MF_NOGRAVITY; - } - else if (!(player->mo->flags2 & MF2_FLY) && !(player->mo->GetDefault()->flags & MF_NOGRAVITY)) - { - player->mo->flags &= ~MF_NOGRAVITY; - } -} - - -//---------------------------------------------------------------------------- -// -// PROC P_CheckFrozen -// -//---------------------------------------------------------------------------- - -bool P_CheckFrozen(player_t *player) -{ - auto cmd = &player->cmd; - bool totallyfrozen = P_IsPlayerTotallyFrozen(player); - - // [RH] Being totally frozen zeros out most input parameters. - if (totallyfrozen) - { - if (gamestate == GS_TITLELEVEL) - { - cmd->ucmd.buttons = 0; - } - else - { - cmd->ucmd.buttons &= BT_USE; - } - cmd->ucmd.pitch = 0; - cmd->ucmd.yaw = 0; - cmd->ucmd.roll = 0; - cmd->ucmd.forwardmove = 0; - cmd->ucmd.sidemove = 0; - cmd->ucmd.upmove = 0; - player->turnticks = 0; - } - else if (player->cheats & CF_FROZEN) - { - cmd->ucmd.forwardmove = 0; - cmd->ucmd.sidemove = 0; - cmd->ucmd.upmove = 0; - } - return totallyfrozen; -} - -//---------------------------------------------------------------------------- -// -// PROC P_CheckCrouch -// -//---------------------------------------------------------------------------- - -void P_CheckCrouch(player_t *player, bool totallyfrozen) -{ - if (player->cmd.ucmd.buttons & BT_JUMP) - { - player->cmd.ucmd.buttons &= ~BT_CROUCH; - } - if (player->CanCrouch() && player->health > 0 && level.IsCrouchingAllowed()) - { - if (!totallyfrozen) - { - int crouchdir = player->crouching; - - if (crouchdir == 0) - { - crouchdir = (player->cmd.ucmd.buttons & BT_CROUCH) ? -1 : 1; - } - else if (player->cmd.ucmd.buttons & BT_CROUCH) - { - player->crouching = 0; - } - if (crouchdir == 1 && player->crouchfactor < 1 && - player->mo->Top() < player->mo->ceilingz) - { - P_CrouchMove(player, 1); - } - else if (crouchdir == -1 && player->crouchfactor > 0.5) - { - P_CrouchMove(player, -1); - } - } - } - else - { - player->Uncrouch(); - } - - player->crouchoffset = -(player->mo->ViewHeight) * (1 - player->crouchfactor); -} - //---------------------------------------------------------------------------- // // PROC P_CheckMusicChange @@ -3069,30 +2875,6 @@ void P_HandleMovement(player_t *player) } -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckFOV) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckFOV(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckCheats) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckCheats(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckFrozen) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - ACTION_RETURN_BOOL(P_CheckFrozen(self->player)); -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckCrouch) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - PARAM_BOOL(totally); - P_CheckCrouch(self->player, totally); - return 0; -} DEFINE_ACTION_FUNCTION(APlayerPawn, CheckMusicChange) { PARAM_SELF_PROLOGUE(APlayerPawn); diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 9b7836d171..961168922d 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -540,6 +540,7 @@ class Actor : Thinker native native void SetXYZ(vector3 newpos); native Actor GetPointer(int aaptr); native double BulletSlope(out FTranslatedLineTarget pLineTarget = null, int aimflags = 0); + native void CheckFakeFloorTriggers (double oldz, bool oldz_has_viewheight = false); native bool CheckMissileSpawn(double maxdist); native bool CheckPosition(Vector2 pos, bool actorsonly = false, FCheckPosition tm = null); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 7b920f524c..ec72249099 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -530,6 +530,7 @@ struct LevelLocals native native static void RemoveAllBots(bool fromlist); native void SetInterMusic(String nextmap); native String FormatMapName(int mapnamecolor); + native bool IsCrouchingAllowed() const; String TimeFormatted(bool totals = false) { diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 31aa40ad05..1ab9cd06ed 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -12,6 +12,7 @@ struct UserCmd native class PlayerPawn : Actor native { + const CROUCHSPEED = (1./12); native int crouchsprite; native int MaxHealth; @@ -215,16 +216,211 @@ class PlayerPawn : Actor native return -1, -1; } + //---------------------------------------------------------------------------- + // + // PROC P_CheckFOV + // + //---------------------------------------------------------------------------- + + virtual void CheckFOV() + { + let player = self.player; + + // [RH] Zoom the player's FOV + float desired = player.DesiredFOV; + // Adjust FOV using on the currently held weapon. + if (player.playerstate != PST_DEAD && // No adjustment while dead. + player.ReadyWeapon != NULL && // No adjustment if no weapon. + player.ReadyWeapon.FOVScale != 0) // No adjustment if the adjustment is zero. + { + // A negative scale is used to prevent G_AddViewAngle/G_AddViewPitch + // from scaling with the FOV scale. + desired *= abs(player.ReadyWeapon.FOVScale); + } + if (player.FOV != desired) + { + if (abs(player.FOV - desired) < 7.) + { + player.FOV = desired; + } + else + { + float zoom = MAX(7., abs(player.FOV - desired) * 0.025); + if (player.FOV > desired) + { + player.FOV = player.FOV - zoom; + } + else + { + player.FOV = player.FOV + zoom; + } + } + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckCheats + // + //---------------------------------------------------------------------------- + + virtual void CheckCheats() + { + let player = self.player; + // No-clip cheat + if ((player.cheats & (CF_NOCLIP | CF_NOCLIP2)) == CF_NOCLIP2) + { // No noclip2 without noclip + player.cheats &= ~CF_NOCLIP2; + } + bNoClip = (player.cheats & (CF_NOCLIP | CF_NOCLIP2) || Default.bNoClip); + if (player.cheats & CF_NOCLIP2) + { + bNoGravity = true; + } + else if (!bFly && !Default.bNoGravity) + { + bNoGravity = false; + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckFrozen + // + //---------------------------------------------------------------------------- + + virtual bool CheckFrozen() + { + let player = self.player; + UserCmd cmd = player.cmd; + bool totallyfrozen = player.IsTotallyFrozen(); + + // [RH] Being totally frozen zeros out most input parameters. + if (totallyfrozen) + { + if (gamestate == GS_TITLELEVEL) + { + cmd.buttons = 0; + } + else + { + cmd.buttons &= BT_USE; + } + cmd.pitch = 0; + cmd.yaw = 0; + cmd.roll = 0; + cmd.forwardmove = 0; + cmd.sidemove = 0; + cmd.upmove = 0; + player.turnticks = 0; + } + else if (player.cheats & CF_FROZEN) + { + cmd.forwardmove = 0; + cmd.sidemove = 0; + cmd.upmove = 0; + } + return totallyfrozen; + } + + virtual bool CanCrouch() const + { + return player.morphTics == 0 || bCrouchableMorph; + } + + //---------------------------------------------------------------------------- + // + // PROC P_CrouchMove + // + //---------------------------------------------------------------------------- + + virtual void CrouchMove(int direction) + { + let player = self.player; + + double defaultheight = FullHeight; + double savedheight = Height; + double crouchspeed = direction * CROUCHSPEED; + double oldheight = player.viewheight; + + player.crouchdir = direction; + player.crouchfactor += crouchspeed; + + // check whether the move is ok + Height = defaultheight * player.crouchfactor; + if (!TryMove(Pos.XY, false, NULL)) + { + Height = savedheight; + if (direction > 0) + { + // doesn't fit + player.crouchfactor -= crouchspeed; + return; + } + } + Height = savedheight; + + player.crouchfactor = clamp(player.crouchfactor, 0.5, 1.); + player.viewheight = ViewHeight * player.crouchfactor; + player.crouchviewdelta = player.viewheight - ViewHeight; + + // Check for eyes going above/below fake floor due to crouching motion. + CheckFakeFloorTriggers(pos.Z + oldheight, true); + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckCrouch + // + //---------------------------------------------------------------------------- + + virtual void CheckCrouch(bool totallyfrozen) + { + let player = self.player; + UserCmd cmd = player.cmd; + + if (cmd.buttons & BT_JUMP) + { + cmd.buttons &= ~BT_CROUCH; + } + if (CanCrouch() && player.health > 0 && level.IsCrouchingAllowed()) + { + if (!totallyfrozen) + { + int crouchdir = player.crouching; + + if (crouchdir == 0) + { + crouchdir = (cmd.buttons & BT_CROUCH) ? -1 : 1; + } + else if (cmd.buttons & BT_CROUCH) + { + player.crouching = 0; + } + if (crouchdir == 1 && player.crouchfactor < 1 && pos.Z + height < ceilingz) + { + CrouchMove(1); + } + else if (crouchdir == -1 && player.crouchfactor > 0.5) + { + CrouchMove(-1); + } + } + } + else + { + player.Uncrouch(); + } + + player.crouchoffset = -(ViewHeight) * (1 - player.crouchfactor); + } + //---------------------------------------------------------------------------- // // PROC P_PlayerThink // //---------------------------------------------------------------------------- - native void CheckFOV(); - native void CheckCheats(); - native bool CheckFrozen(); - native void CheckCrouch(bool totallyfrozen); native void CheckMusicChange(); native void DeathThink (); native void CheckPitch(); @@ -512,7 +708,29 @@ struct PlayerInfo native play // this is what internally is known as player_t native void SetFOV(float fov); native clearscope bool HasWeaponsInSlot(int slot) const; native void TickPSprites(); + + bool IsTotallyFrozen() + { + return + gamestate == GS_TITLELEVEL || + (cheats & CF_TOTALLYFROZEN) || + (level.frozen && timefreezer == 0); + } + + void Uncrouch() + { + if (crouchfactor != 1) + { + crouchfactor = 1; + crouchoffset = 0; + crouchdir = 0; + crouching = 0; + crouchviewdelta = 0; + viewheight = mo.ViewHeight; + } + } + clearscope int fragSum () const { int i;