From abee2805cb31a129947f839099db78777e3026fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 1 May 2017 00:25:21 +0200 Subject: [PATCH] - the last scriptified bits of P_PlayerThink. --- src/d_player.h | 3 - src/g_level.cpp | 15 + src/p_user.cpp | 668 +----------------------- src/r_utility.cpp | 1 + wadsrc/static/zscript/actor.txt | 2 + wadsrc/static/zscript/base.txt | 4 + wadsrc/static/zscript/shared/player.txt | 566 +++++++++++++++++++- 7 files changed, 591 insertions(+), 668 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 7c20b85dd..011335a85 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -97,8 +97,6 @@ public: bool ResetAirSupply (bool playgasp = true); int GetMaxHealth(bool withupgrades = false) const; - void TweakSpeeds (double &forwardmove, double &sidemove); - void MorphPlayerThink (); void ActivateMorphWeapon (); AWeapon *PickNewWeapon (PClassActor *ammotype); AWeapon *BestWeapon (PClassActor *ammotype); @@ -111,7 +109,6 @@ public: // These are virtual on the script side only. void PlayIdle(); - void PlayRunning(); void PlayAttacking (); void PlayAttacking2 (); diff --git a/src/g_level.cpp b/src/g_level.cpp index 7d1cf4169..ec48fd939 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1450,6 +1450,13 @@ bool FLevelLocals::IsJumpingAllowed() const return !(flags & LEVEL_JUMP_NO); } +DEFINE_ACTION_FUNCTION(FLevelLocals, IsJumpingAllowed) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + ACTION_RETURN_BOOL(self->IsJumpingAllowed()); +} + + //========================================================================== // // @@ -1484,6 +1491,13 @@ bool FLevelLocals::IsFreelookAllowed() const return !(flags & LEVEL_FREELOOK_NO); } +DEFINE_ACTION_FUNCTION(FLevelLocals, IsFreelookAllowed) +{ + PARAM_SELF_STRUCT_PROLOGUE(FLevelLocals); + ACTION_RETURN_BOOL(self->IsFreelookAllowed()); +} + + //========================================================================== // // @@ -1938,6 +1952,7 @@ DEFINE_FIELD_BIT(FLevelLocals, flags2, missilesactivateimpact, LEVEL2_MISSILESAC DEFINE_FIELD_BIT(FLevelLocals, flags2, monsterfallingdamage, LEVEL2_MONSTERFALLINGDAMAGE) DEFINE_FIELD_BIT(FLevelLocals, flags2, checkswitchrange, LEVEL2_CHECKSWITCHRANGE) DEFINE_FIELD_BIT(FLevelLocals, flags2, polygrind, LEVEL2_POLYGRIND) +DEFINE_FIELD_BIT(FLevelLocals, flags2, allowrespawn, LEVEL2_ALLOWRESPAWN) DEFINE_FIELD_BIT(FLevelLocals, flags2, nomonsters, LEVEL2_NOMONSTERS) DEFINE_FIELD_BIT(FLevelLocals, flags2, frozen, LEVEL2_FROZEN) DEFINE_FIELD_BIT(FLevelLocals, flags2, infinite_flight, LEVEL2_INFINITE_FLIGHT) diff --git a/src/p_user.cpp b/src/p_user.cpp index ff22ae7ea..e2d803afb 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -102,9 +102,6 @@ static FRandom pr_skullpop ("SkullPop"); -// [RH] # of ticks to complete a turn180 -#define TURN180_TICKS ((TICRATE / 4) + 1) - // [SP] Allows respawn in single player CVAR(Bool, sv_singleplayerrespawn, false, CVAR_SERVERINFO | CVAR_LATCH) @@ -1544,15 +1541,6 @@ void APlayerPawn::PlayIdle () } } -void APlayerPawn::PlayRunning () -{ - IFVIRTUAL(APlayerPawn, PlayRunning) - { - VMValue params[1] = { (DObject*)this }; - VMCall(func, params, 1, nullptr, 0); - } -} - void APlayerPawn::PlayAttacking () { IFVIRTUAL(APlayerPawn, PlayAttacking) @@ -1660,15 +1648,6 @@ void APlayerPawn::GiveDefaultInventory () } } -void APlayerPawn::MorphPlayerThink () -{ - IFVIRTUAL(APlayerPawn, MorphPlayerThink) - { - VMValue params[1] = { (DObject*)this }; - VMCall(func, params, 1, nullptr, 0); - } -} - void APlayerPawn::ActivateMorphWeapon () { PClassActor *morphweapon = PClass::FindActor (MorphWeapon); @@ -1790,48 +1769,6 @@ void APlayerPawn::Die (AActor *source, AActor *inflictor, int dmgflags) } } -//=========================================================================== -// -// APlayerPawn :: TweakSpeeds -// -//=========================================================================== - -void APlayerPawn::TweakSpeeds (double &forward, double &side) -{ - // Strife's player can't run when its health is below 10 - if (health <= RunHealth) - { - forward = clamp(forward, -0x1900, 0x1900); - side = clamp(side, -0x1800, 0x1800); - } - - // [GRB] - if (fabs(forward) < 0x3200) - { - forward *= ForwardMove1; - } - else - { - forward *= ForwardMove2; - } - - if (fabs(side) < 0x2800) - { - side *= SideMove1; - } - else - { - side *= SideMove2; - } - - if (!player->morphTics && Inventory != NULL) - { - double factor = Inventory->GetSpeedFactor (); - forward *= factor; - side *= factor; - } -} - //=========================================================================== // // A_PlayerScream @@ -2029,57 +1966,6 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, DVector2 &scale) } } -/* -================== -= -= P_Thrust -= -= moves the given origin along a given angle -= -================== -*/ - -void P_SideThrust (player_t *player, DAngle angle, double move) -{ - player->mo->Thrust(angle-90, move); -} - -void P_ForwardThrust (player_t *player, DAngle angle, double move) -{ - if ((player->mo->waterlevel || (player->mo->flags & MF_NOGRAVITY)) - && player->mo->Angles.Pitch != 0) - { - double zpush = move * player->mo->Angles.Pitch.Sin(); - if (player->mo->waterlevel && player->mo->waterlevel < 2 && zpush < 0) - zpush = 0; - player->mo->Vel.Z -= zpush; - move *= player->mo->Angles.Pitch.Cos(); - } - player->mo->Thrust(angle, move); -} - -// -// P_Bob -// Same as P_Thrust, but only affects bobbing. -// -// killough 10/98: We apply thrust separately between the real physical player -// and the part which affects bobbing. This way, bobbing only comes from player -// motion, nothing external, avoiding many problems, e.g. bobbing should not -// occur on conveyors, unless the player walks on one, and bobbing should be -// reduced at a regular rate, even on ice (where the player coasts). -// - -void P_Bob (player_t *player, DAngle angle, double move, bool forward) -{ - if (forward - && (player->mo->waterlevel || (player->mo->flags & MF_NOGRAVITY)) - && player->mo->Angles.Pitch != 0) - { - move *= player->mo->Angles.Pitch.Cos(); - } - player->Vel += angle.ToVector(move); -} - /* ================== = @@ -2205,115 +2091,19 @@ void P_CalcHeight (player_t *player) } } -/* -================= -= -= P_MovePlayer -= -================= -*/ +DEFINE_ACTION_FUNCTION(APlayerPawn, CalcHeight) +{ + PARAM_SELF_PROLOGUE(APlayerPawn); + P_CalcHeight(self->player); + return 0; +} + CUSTOM_CVAR (Float, sv_aircontrol, 0.00390625f, CVAR_SERVERINFO|CVAR_NOSAVE) { level.aircontrol = self; G_AirControlChanged (); } -void P_MovePlayer (player_t *player) -{ - ticcmd_t *cmd = &player->cmd; - APlayerPawn *mo = player->mo; - - // [RH] 180-degree turn overrides all other yaws - if (player->turnticks) - { - player->turnticks--; - mo->Angles.Yaw += (180. / TURN180_TICKS); - } - else - { - mo->Angles.Yaw += cmd->ucmd.yaw * (360./65536.); - } - - player->onground = (mo->Z() <= mo->floorz) || (mo->flags2 & MF2_ONMOBJ) || (mo->BounceFlags & BOUNCE_MBF) || (player->cheats & CF_NOCLIP2); - - // killough 10/98: - // - // We must apply thrust to the player and bobbing separately, to avoid - // anomalies. The thrust applied to bobbing is always the same strength on - // ice, because the player still "works just as hard" to move, while the - // thrust applied to the movement varies with 'movefactor'. - - if (cmd->ucmd.forwardmove | cmd->ucmd.sidemove) - { - double forwardmove, sidemove; - double bobfactor; - double friction, movefactor; - double fm, sm; - - movefactor = P_GetMoveFactor (mo, &friction); - bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR; - if (!player->onground && !(player->mo->flags & MF_NOGRAVITY) && !player->mo->waterlevel) - { - // [RH] allow very limited movement if not on ground. - movefactor *= level.aircontrol; - bobfactor*= level.aircontrol; - } - - fm = cmd->ucmd.forwardmove; - sm = cmd->ucmd.sidemove; - mo->TweakSpeeds (fm, sm); - fm *= player->mo->Speed / 256; - sm *= player->mo->Speed / 256; - - // When crouching, speed and bobbing have to be reduced - if (player->CanCrouch() && player->crouchfactor != 1) - { - fm *= player->crouchfactor; - sm *= player->crouchfactor; - bobfactor *= player->crouchfactor; - } - - forwardmove = fm * movefactor * (35 / TICRATE); - sidemove = sm * movefactor * (35 / TICRATE); - - if (forwardmove) - { - P_Bob(player, mo->Angles.Yaw, cmd->ucmd.forwardmove * bobfactor / 256., true); - P_ForwardThrust(player, mo->Angles.Yaw, forwardmove); - } - if (sidemove) - { - P_Bob(player, mo->Angles.Yaw - 90, cmd->ucmd.sidemove * bobfactor / 256., false); - P_SideThrust(player, mo->Angles.Yaw, sidemove); - } - - if (debugfile) - { - fprintf (debugfile, "move player for pl %d%c: (%f,%f,%f) (%f,%f) %f %f w%d [", int(player-players), - player->cheats&CF_PREDICTING?'p':' ', - player->mo->X(), player->mo->Y(), player->mo->Z(),forwardmove, sidemove, movefactor, friction, player->mo->waterlevel); - msecnode_t *n = player->mo->touching_sectorlist; - while (n != NULL) - { - fprintf (debugfile, "%d ", n->m_sector->sectornum); - n = n->m_tnext; - } - fprintf (debugfile, "]\n"); - } - - if (!(player->cheats & CF_PREDICTING) && (forwardmove != 0 || sidemove != 0)) - { - player->mo->PlayRunning (); - } - - if (player->cheats & CF_REVERTPLEASE) - { - player->cheats &= ~CF_REVERTPLEASE; - player->camera = player->mo; - } - } -} - //========================================================================== // // P_FallingDamage @@ -2409,117 +2199,6 @@ void P_FallingDamage (AActor *actor) P_DamageMobj (actor, NULL, NULL, damage, NAME_Falling); } -//========================================================================== -// -// P_DeathThink -// -//========================================================================== - -void P_DeathThink (player_t *player) -{ - int dir; - DAngle delta; - - player->Uncrouch(); - player->TickPSprites(); - - player->onground = (player->mo->Z() <= player->mo->floorz); - if (player->mo->IsKindOf (PClass::FindActor("PlayerChunk"))) - { // Flying bloody skull or flying ice chunk - player->viewheight = 6; - player->deltaviewheight = 0; - if (player->onground) - { - if (player->mo->Angles.Pitch > -19.) - { - DAngle lookDelta = (-19. - player->mo->Angles.Pitch) / 8; - player->mo->Angles.Pitch += lookDelta; - } - } - } - else if (!(player->mo->flags & MF_ICECORPSE)) - { // Fall to ground (if not frozen) - player->deltaviewheight = 0; - if (player->viewheight > 6) - { - player->viewheight -= 1; - } - if (player->viewheight < 6) - { - player->viewheight = 6; - } - if (player->mo->Angles.Pitch < 0) - { - player->mo->Angles.Pitch += 3; - } - else if (player->mo->Angles.Pitch > 0) - { - player->mo->Angles.Pitch -= 3; - } - if (fabs(player->mo->Angles.Pitch) < 3) - { - player->mo->Angles.Pitch = 0.; - } - } - P_CalcHeight (player); - - if (player->attacker && player->attacker != player->mo) - { // Watch killer - dir = P_FaceMobj (player->mo, player->attacker, &delta); - if (delta < 10) - { // Looking at killer, so fade damage and poison counters - if (player->damagecount) - { - player->damagecount--; - } - if (player->poisoncount) - { - player->poisoncount--; - } - } - delta /= 8; - if (delta > 5.) - { - delta = 5.; - } - if (dir) - { // Turn clockwise - player->mo->Angles.Yaw += delta; - } - else - { // Turn counter clockwise - player->mo->Angles.Yaw -= delta; - } - } - else - { - if (player->damagecount) - { - player->damagecount--; - } - if (player->poisoncount) - { - player->poisoncount--; - } - } - - if ((player->cmd.ucmd.buttons & BT_USE || - ((multiplayer || alwaysapplydmflags) && (dmflags & DF_FORCE_RESPAWN))) && !(dmflags2 & DF2_NO_RESPAWN)) - { - if (level.time >= player->respawn_time || ((player->cmd.ucmd.buttons & BT_USE) && player->Bot == NULL)) - { - player->cls = NULL; // Force a new class if the player is using a random class - player->playerstate = - (multiplayer || (level.flags2 & LEVEL2_ALLOWRESPAWN) || sv_singleplayerrespawn) - ? PST_REBORN : PST_ENTER; - if (player->mo->special1 > 2) - { - player->mo->special1 = 0; - } - } - } -} - //---------------------------------------------------------------------------- // // PROC P_CheckMusicChange @@ -2554,154 +2233,13 @@ void P_CheckMusicChange(player_t *player) } } -//---------------------------------------------------------------------------- -// -// PROC P_CheckPitch -// -//---------------------------------------------------------------------------- - -void P_CheckPitch(player_t *player) +DEFINE_ACTION_FUNCTION(APlayerPawn, CheckMusicChange) { - // [RH] Look up/down stuff - if (!level.IsFreelookAllowed()) - { - player->mo->Angles.Pitch = 0.; - } - else - { - // The player's view pitch is clamped between -32 and +56 degrees, - // which translates to about half a screen height up and (more than) - // one full screen height down from straight ahead when view panning - // is used. - int clook = player->cmd.ucmd.pitch; - if (clook != 0) - { - if (clook == -32768) - { // center view - player->centering = true; - } - else if (!player->centering) - { - // no more overflows with floating point. Yay! :) - player->mo->Angles.Pitch = clamp(player->mo->Angles.Pitch - clook * (360. / 65536.), player->MinPitch, player->MaxPitch); - } - } - } - if (player->centering) - { - if (fabs(player->mo->Angles.Pitch) > 2.) - { - player->mo->Angles.Pitch *= (2. / 3.); - } - else - { - player->mo->Angles.Pitch = 0.; - player->centering = false; - if (player - players == consoleplayer) - { - LocalViewPitch = 0; - } - } - } + PARAM_SELF_PROLOGUE(APlayerPawn); + P_CheckMusicChange(self->player); + return 0; } -//---------------------------------------------------------------------------- -// -// PROC P_CheckJump -// -//---------------------------------------------------------------------------- - -void P_CheckJump(player_t *player) -{ - // [RH] check for jump - if (player->cmd.ucmd.buttons & BT_JUMP) - { - if (player->crouchoffset != 0) - { - // Jumping while crouching will force an un-crouch but not jump - player->crouching = 1; - } - else if (player->mo->waterlevel >= 2) - { - player->mo->Vel.Z = 4 * player->mo->Speed; - } - else if (player->mo->flags & MF_NOGRAVITY) - { - player->mo->Vel.Z = 3.; - } - else if (level.IsJumpingAllowed() && player->onground && player->jumpTics == 0) - { - double jumpvelz = player->mo->JumpZ * 35 / TICRATE; - double jumpfac = 0; - - // [BC] If the player has the high jump power, double his jump velocity. - // (actually, pick the best factors from all active items.) - for (auto p = player->mo->Inventory; p != nullptr; p = p->Inventory) - { - if (p->IsKindOf(NAME_PowerHighJump)) - { - double f = p->FloatVar(NAME_Strength); - if (f > jumpfac) jumpfac = f; - } - } - if (jumpfac > 0) jumpvelz *= jumpfac; - - player->mo->Vel.Z += jumpvelz; - player->mo->flags2 &= ~MF2_ONMOBJ; - player->jumpTics = -1; - if (!(player->cheats & CF_PREDICTING)) - S_Sound(player->mo, CHAN_BODY, "*jump", 1, ATTN_NORM); - } - } -} - -//---------------------------------------------------------------------------- -// -// PROC P_CheckMoveUpDown -// -//---------------------------------------------------------------------------- - -void P_CheckMoveUpDown(player_t *player) -{ - auto cmd = &player->cmd; - - if (cmd->ucmd.upmove == -32768) - { // Only land if in the air - if ((player->mo->flags & MF_NOGRAVITY) && player->mo->waterlevel < 2) - { - //player->mo->flags2 &= ~MF2_FLY; - player->mo->flags &= ~MF_NOGRAVITY; - } - } - else if (cmd->ucmd.upmove != 0) - { - // Clamp the speed to some reasonable maximum. - cmd->ucmd.upmove = clamp(cmd->ucmd.upmove, -0x300, 0x300); - if (player->mo->waterlevel >= 2 || (player->mo->flags2 & MF2_FLY) || (player->cheats & CF_NOCLIP2)) - { - player->mo->Vel.Z = player->mo->Speed * cmd->ucmd.upmove / 128.; - if (player->mo->waterlevel < 2 && !(player->mo->flags & MF_NOGRAVITY)) - { - player->mo->flags2 |= MF2_FLY; - player->mo->flags |= MF_NOGRAVITY; - if ((player->mo->Vel.Z <= -39) && !(player->cheats & CF_PREDICTING)) - { // Stop falling scream - S_StopSound(player->mo, CHAN_VOICE); - } - } - } - else if (cmd->ucmd.upmove > 0 && !(player->cheats & CF_PREDICTING)) - { - AInventory *fly = player->mo->FindInventory(NAME_ArtiFly); - if (fly != NULL) - { - player->mo->UseInventory(fly); - } - } - } -} - - //---------------------------------------------------------------------------- // // PROC P_CheckEnviroment @@ -2731,6 +2269,13 @@ void P_CheckEnvironment(player_t *player) } } +DEFINE_ACTION_FUNCTION(APlayerPawn, CheckEnvironment) +{ + PARAM_SELF_PROLOGUE(APlayerPawn); + P_CheckEnvironment(self->player); + return 0; +} + //---------------------------------------------------------------------------- // // PROC P_CheckUse @@ -2757,190 +2302,13 @@ void P_CheckUse(player_t *player) } } -//---------------------------------------------------------------------------- -// -// PROC P_CheckUndoMorph -// -//---------------------------------------------------------------------------- -void P_CheckUndoMorph(player_t *player) -{ - // Morph counter - if (player->morphTics) - { - if (player->chickenPeck) - { // Chicken attack counter - player->chickenPeck -= 3; - } - if (!--player->morphTics) - { // Attempt to undo the chicken/pig - P_UndoPlayerMorph(player, player, MORPH_UNDOBYTIMEOUT); - } - } -} - -//---------------------------------------------------------------------------- -// -// PROC P_CheckPoison -// -//---------------------------------------------------------------------------- - -void P_CheckPoison(player_t *player) -{ - if (player->poisoncount && !(level.time & 15)) - { - player->poisoncount -= 5; - if (player->poisoncount < 0) - { - player->poisoncount = 0; - } - P_PoisonDamage(player, player->poisoner, 1, true); - } -} - -//---------------------------------------------------------------------------- -// -// PROC P_CheckDegeneration -// -//---------------------------------------------------------------------------- - -void P_CheckDegeneration(player_t *player) -{ - // Apply degeneration. - if (dmflags2 & DF2_YES_DEGENERATION) - { - int maxhealth = player->mo->GetMaxHealth(true); - if ((level.time % TICRATE) == 0 && player->health > maxhealth) - { - if (player->health - 5 < maxhealth) - player->health = maxhealth; - else - player->health--; - - player->mo->health = player->health; - } - } -} - -//---------------------------------------------------------------------------- -// -// PROC P_CheckAirSupply -// -//---------------------------------------------------------------------------- - -void P_CheckAirSupply(player_t *player) -{ - // Handle air supply - //if (level.airsupply > 0) - { - if (player->mo->waterlevel < 3 || - (player->mo->flags2 & MF2_INVULNERABLE) || - (player->cheats & (CF_GODMODE | CF_NOCLIP2)) || - (player->cheats & CF_GODMODE2)) - { - player->mo->ResetAirSupply(); - } - else if (player->air_finished <= level.time && !(level.time & 31)) - { - P_DamageMobj(player->mo, NULL, NULL, 2 + ((level.time - player->air_finished) / TICRATE), NAME_Drowning); - } - } -} - -//---------------------------------------------------------------------------- -// -// PROC P_HandleMovement -// -//---------------------------------------------------------------------------- - -void P_HandleMovement(player_t *player) -{ - // [RH] Check for fast turn around - if (player->cmd.ucmd.buttons & BT_TURN180 && !(player->oldbuttons & BT_TURN180)) - { - player->turnticks = TURN180_TICKS; - } - - // Handle movement - if (player->mo->reactiontime) - { // Player is frozen - player->mo->reactiontime--; - } - else - { - P_MovePlayer(player); - P_CheckJump(player); - P_CheckMoveUpDown(player); - } -} - - -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckMusicChange) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckMusicChange(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, DeathThink) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_DeathThink(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckPitch) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckPitch(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, HandleMovement) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_HandleMovement(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CalcHeight) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CalcHeight(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckEnvironment) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckEnvironment(self->player); - return 0; -} DEFINE_ACTION_FUNCTION(APlayerPawn, CheckUse) { PARAM_SELF_PROLOGUE(APlayerPawn); P_CheckUse(self->player); return 0; } -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckUndoMorph) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckUndoMorph(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckPoison) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckPoison(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckDegeneration) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckDegeneration(self->player); - return 0; -} -DEFINE_ACTION_FUNCTION(APlayerPawn, CheckAirSupply) -{ - PARAM_SELF_PROLOGUE(APlayerPawn); - P_CheckAirSupply(self->player); - return 0; -} //---------------------------------------------------------------------------- // diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 7a90a03ec..9aa8b4cb0 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -154,6 +154,7 @@ FCanvasTextureInfo *FCanvasTextureInfo::List; DVector3a view; DAngle viewpitch; +DEFINE_GLOBAL(LocalViewPitch); // CODE -------------------------------------------------------------------- static void R_Shutdown (); diff --git a/wadsrc/static/zscript/actor.txt b/wadsrc/static/zscript/actor.txt index 961168922..2abd552c9 100644 --- a/wadsrc/static/zscript/actor.txt +++ b/wadsrc/static/zscript/actor.txt @@ -44,6 +44,8 @@ class Actor : Thinker native const TELEFRAG_DAMAGE = 1000000; const MinVel = 1./65536; const LARGE_MASS = 10000000; // not INT_MAX on purpose + const ORIG_FRICTION = (0xE800/65536.); // original value + const ORIG_FRICTION_FACTOR = (2048/65536.); // original value // flags are not defined here, the native fields for those get synthesized from the internal tables. diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index ec7224909..d6f7f318e 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -42,6 +42,7 @@ struct _ native // These are the global variables, the struct is only here to av native readonly int Net_Arbitrator; native ui BaseStatusBar StatusBar; native readonly Weapon WP_NOCHANGE; + native int LocalViewPitch; } @@ -513,6 +514,7 @@ struct LevelLocals native native readonly bool checkswitchrange; native readonly bool polygrind; native readonly bool nomonsters; + native readonly bool allowrespawn; native bool frozen; native readonly bool infinite_flight; native readonly bool no_dlg_freeze; @@ -530,7 +532,9 @@ struct LevelLocals native native static void RemoveAllBots(bool fromlist); native void SetInterMusic(String nextmap); native String FormatMapName(int mapnamecolor); + native bool IsJumpingAllowed() const; native bool IsCrouchingAllowed() const; + native bool IsFreelookAllowed() const; String TimeFormatted(bool totals = false) { diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 1ab9cd06e..1caf03c8e 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -13,6 +13,8 @@ struct UserCmd native class PlayerPawn : Actor native { const CROUCHSPEED = (1./12); + // [RH] # of ticks to complete a turn180 + const TURN180_TICKS = ((TICRATE / 4) + 1); native int crouchsprite; native int MaxHealth; @@ -216,6 +218,107 @@ class PlayerPawn : Actor native return -1, -1; } + //========================================================================== + // + // P_DeathThink + // + //========================================================================== + + virtual void DeathThink () + { + let player = self.player; + int dir; + double delta; + + player.Uncrouch(); + player.TickPSprites(); + + player.onground = (pos.Z <= floorz); + if (self is "PlayerChunk") + { // Flying bloody skull or flying ice chunk + player.viewheight = 6; + player.deltaviewheight = 0; + if (player.onground) + { + if (Pitch > -19.) + { + double lookDelta = (-19. - Pitch) / 8; + Pitch += lookDelta; + } + } + } + else if (!bIceCorpse) + { // Fall to ground (if not frozen) + player.deltaviewheight = 0; + if (player.viewheight > 6) + { + player.viewheight -= 1; + } + if (player.viewheight < 6) + { + player.viewheight = 6; + } + if (Pitch < 0) + { + Pitch += 3; + } + else if (Pitch > 0) + { + Pitch -= 3; + } + if (abs(Pitch) < 3) + { + Pitch = 0.; + } + } + CalcHeight (); + + if (player.attacker && player.attacker != self) + { // Watch killer + double diff = deltaangle(angle, AngleTo(player.attacker)); + double delta = abs(diff); + + if (delta < 10) + { // Looking at killer, so fade damage and poison counters + if (player.damagecount) + { + player.damagecount--; + } + if (player.poisoncount) + { + player.poisoncount--; + } + } + delta /= 8; + Angle += clamp(diff, -5., 5.); + } + else + { + if (player.damagecount) + { + player.damagecount--; + } + if (player.poisoncount) + { + player.poisoncount--; + } + } + + if ((player.cmd.buttons & BT_USE || + ((multiplayer || alwaysapplydmflags) && sv_forcerespawn)) && !sv_norespawn) + { + if (level.time >= player.respawn_time || ((player.cmd.buttons & BT_USE) && player.Bot == NULL)) + { + player.cls = NULL; // Force a new class if the player is using a random class + player.playerstate = (multiplayer || (level.AllowRespawn) || sv_singleplayerrespawn)? PST_REBORN : PST_ENTER; + if (special1 > 2) + { + special1 = 0; + } + } + } + } + //---------------------------------------------------------------------------- // // PROC P_CheckFOV @@ -415,26 +518,455 @@ class PlayerPawn : Actor native player.crouchoffset = -(ViewHeight) * (1 - player.crouchfactor); } + //---------------------------------------------------------------------------- + // + // P_Thrust + // + // moves the given origin along a given angle + // + //---------------------------------------------------------------------------- + + void ForwardThrust (double move, double angle) + { + if ((waterlevel || bNoGravity) && Pitch != 0) + { + double zpush = move * sin(Pitch); + if (waterlevel && waterlevel < 2 && zpush < 0) zpush = 0; + Vel.Z -= zpush; + move *= cos(Pitch); + } + Thrust(move); + } + + //---------------------------------------------------------------------------- + // + // P_Bob + // Same as P_Thrust, but only affects bobbing. + // + // killough 10/98: We apply thrust separately between the real physical player + // and the part which affects bobbing. This way, bobbing only comes from player + // motion, nothing external, avoiding many problems, e.g. bobbing should not + // occur on conveyors, unless the player walks on one, and bobbing should be + // reduced at a regular rate, even on ice (where the player coasts). + // + //---------------------------------------------------------------------------- + + void Bob (double angle, double move, bool forward) + { + if (forward && (waterlevel || bNoGravity) && Pitch != 0) + { + move *= cos(Pitch); + } + player.Vel += AngleToVector(angle, move); + } + + //=========================================================================== + // + // APlayerPawn :: TweakSpeeds + // + //=========================================================================== + + double, double TweakSpeeds (double forward, double side) + { + // Strife's player can't run when its health is below 10 + if (health <= RunHealth) + { + forward = clamp(forward, -0x1900, 0x1900); + side = clamp(side, -0x1800, 0x1800); + } + + // [GRB] + if (abs(forward) < 0x3200) + { + forward *= ForwardMove1; + } + else + { + forward *= ForwardMove2; + } + + if (abs(side) < 0x2800) + { + side *= SideMove1; + } + else + { + side *= SideMove2; + } + + if (!player.morphTics && Inv != NULL) + { + double factor = Inv.GetSpeedFactor (); + forward *= factor; + side *= factor; + } + return forward, side; + } + + //---------------------------------------------------------------------------- + // + // PROC P_MovePlayer + // + //---------------------------------------------------------------------------- + + virtual void MovePlayer () + { + let player = self.player; + UserCmd cmd = player.cmd; + + // [RH] 180-degree turn overrides all other yaws + if (player.turnticks) + { + player.turnticks--; + Angle += (180. / TURN180_TICKS); + } + else + { + Angle += cmd.yaw * (360./65536.); + } + + player.onground = (pos.z <= floorz) || bOnMobj || bMBFBouncer || (player.cheats & CF_NOCLIP2); + + // killough 10/98: + // + // We must apply thrust to the player and bobbing separately, to avoid + // anomalies. The thrust applied to bobbing is always the same strength on + // ice, because the player still "works just as hard" to move, while the + // thrust applied to the movement varies with 'movefactor'. + + if (cmd.forwardmove | cmd.sidemove) + { + double forwardmove, sidemove; + double bobfactor; + double friction, movefactor; + double fm, sm; + + [friction, movefactor] = GetFriction(); + bobfactor = friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR; + if (!player.onground && !bNoGravity && !waterlevel) + { + // [RH] allow very limited movement if not on ground. + movefactor *= level.aircontrol; + bobfactor*= level.aircontrol; + } + + fm = cmd.forwardmove; + sm = cmd.sidemove; + [fm, sm] = TweakSpeeds (fm, sm); + fm *= Speed / 256; + sm *= Speed / 256; + + // When crouching, speed and bobbing have to be reduced + if (CanCrouch() && player.crouchfactor != 1) + { + fm *= player.crouchfactor; + sm *= player.crouchfactor; + bobfactor *= player.crouchfactor; + } + + forwardmove = fm * movefactor * (35 / TICRATE); + sidemove = sm * movefactor * (35 / TICRATE); + + if (forwardmove) + { + Bob(Angle, cmd.forwardmove * bobfactor / 256., true); + ForwardThrust(forwardmove, Angle); + } + if (sidemove) + { + let a = Angle - 90; + Bob(a, cmd.sidemove * bobfactor / 256., false); + Thrust(sidemove, a); + } + + if (!(player.cheats & CF_PREDICTING) && (forwardmove != 0 || sidemove != 0)) + { + PlayRunning (); + } + + if (player.cheats & CF_REVERTPLEASE) + { + player.cheats &= ~CF_REVERTPLEASE; + player.camera = player.mo; + } + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckPitch + // + //---------------------------------------------------------------------------- + + virtual void CheckPitch() + { + let player = self.player; + // [RH] Look up/down stuff + if (!level.IsFreelookAllowed()) + { + Pitch = 0.; + } + else + { + // The player's view pitch is clamped between -32 and +56 degrees, + // which translates to about half a screen height up and (more than) + // one full screen height down from straight ahead when view panning + // is used. + int clook = player.cmd.pitch; + if (clook != 0) + { + if (clook == -32768) + { // center view + player.centering = true; + } + else if (!player.centering) + { + // no more overflows with floating point. Yay! :) + Pitch = clamp(Pitch - clook * (360. / 65536.), player.MinPitch, player.MaxPitch); + } + } + } + if (player.centering) + { + if (abs(Pitch) > 2.) + { + Pitch *= (2. / 3.); + } + else + { + Pitch = 0.; + player.centering = false; + if (PlayerNumber() == consoleplayer) + { + LocalViewPitch = 0; + } + } + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckJump + // + //---------------------------------------------------------------------------- + + virtual void CheckJump() + { + let player = self.player; + // [RH] check for jump + if (player.cmd.buttons & BT_JUMP) + { + if (player.crouchoffset != 0) + { + // Jumping while crouching will force an un-crouch but not jump + player.crouching = 1; + } + else if (waterlevel >= 2) + { + Vel.Z = 4 * Speed; + } + else if (bNoGravity) + { + Vel.Z = 3.; + } + else if (level.IsJumpingAllowed() && player.onground && player.jumpTics == 0) + { + double jumpvelz = JumpZ * 35 / TICRATE; + double jumpfac = 0; + + // [BC] If the player has the high jump power, double his jump velocity. + // (actually, pick the best factors from all active items.) + for (let p = Inv; p != null; p = p.Inv) + { + let pp = PowerHighJump(p); + if (pp) + { + double f = pp.Strength; + if (f > jumpfac) jumpfac = f; + } + } + if (jumpfac > 0) jumpvelz *= jumpfac; + + Vel.Z += jumpvelz; + bOnMobj = false; + player.jumpTics = -1; + if (!(player.cheats & CF_PREDICTING)) A_PlaySound("*jump", CHAN_BODY); + } + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckMoveUpDown + // + //---------------------------------------------------------------------------- + + virtual void CheckMoveUpDown() + { + let player = self.player; + UserCmd cmd = player.cmd; + + if (cmd.upmove == -32768) + { // Only land if in the air + if (bNoGravity && waterlevel < 2) + { + bNoGravity = false; + } + } + else if (cmd.upmove != 0) + { + // Clamp the speed to some reasonable maximum. + cmd.upmove = clamp(cmd.upmove, -0x300, 0x300); + if (waterlevel >= 2 || bFly || (player.cheats & CF_NOCLIP2)) + { + Vel.Z = Speed * cmd.upmove / 128.; + if (waterlevel < 2 && !bNoGravity) + { + bFly = true; + bNoGravity = true; + if ((Vel.Z <= -39) && !(player.cheats & CF_PREDICTING)) + { // Stop falling scream + A_StopSound(CHAN_VOICE); + } + } + } + else if (cmd.upmove > 0 && !(player.cheats & CF_PREDICTING)) + { + let fly = FindInventory("ArtiFly"); + if (fly != NULL) + { + UseInventory(fly); + } + } + } + } + + + //---------------------------------------------------------------------------- + // + // PROC P_HandleMovement + // + //---------------------------------------------------------------------------- + + virtual void HandleMovement() + { + let player = self.player; + // [RH] Check for fast turn around + if (player.cmd.buttons & BT_TURN180 && !(player.oldbuttons & BT_TURN180)) + { + player.turnticks = TURN180_TICKS; + } + + // Handle movement + if (reactiontime) + { // Player is frozen + reactiontime--; + } + else + { + MovePlayer(); + CheckJump(); + CheckMoveUpDown(); + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckUndoMorph + // + //---------------------------------------------------------------------------- + + virtual void CheckUndoMorph() + { + let player = self.player; + // Morph counter + if (player.morphTics) + { + if (player.chickenPeck) + { // Chicken attack counter + player.chickenPeck -= 3; + } + if (!--player.morphTics) + { // Attempt to undo the chicken/pig + player.UndoPlayerMorph(player, MRF_UNDOBYTIMEOUT); + } + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckPoison + // + //---------------------------------------------------------------------------- + + virtual void CheckPoison() + { + let player = self.player; + if (player.poisoncount && !(level.time & 15)) + { + player.poisoncount -= 5; + if (player.poisoncount < 0) + { + player.poisoncount = 0; + } + player.PoisonDamage(player.poisoner, 1, true); + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckDegeneration + // + //---------------------------------------------------------------------------- + + virtual void CheckDegeneration() + { + // Apply degeneration. + if (sv_degeneration) + { + let player = self.player; + int maxhealth = GetMaxHealth(true); + if ((level.time % TICRATE) == 0 && player.health > maxhealth) + { + if (player.health - 5 < maxhealth) + player.health = maxhealth; + else + player.health--; + + health = player.health; + } + } + } + + //---------------------------------------------------------------------------- + // + // PROC P_CheckAirSupply + // + //---------------------------------------------------------------------------- + + virtual void CheckAirSupply() + { + // Handle air supply + //if (level.airsupply > 0) + { + let player = self.player; + if (waterlevel < 3 || (bInvulnerable) || (player.cheats & (CF_GODMODE | CF_NOCLIP2)) || (player.cheats & CF_GODMODE2)) + { + ResetAirSupply(); + } + else if (player.air_finished <= level.time && !(level.time & 31)) + { + DamageMobj(NULL, NULL, 2 + ((level.time - player.air_finished) / TICRATE), 'Drowning'); + } + } + } + //---------------------------------------------------------------------------- // // PROC P_PlayerThink // //---------------------------------------------------------------------------- - native void CheckMusicChange(); - native void DeathThink (); - native void CheckPitch(); - native void HandleMovement(); - native void CalcHeight (); - native void CheckEnvironment(); - native void CheckUse(); - native void CheckUndoMorph(); - // Cycle psprites - native void CheckPoison(); - native void CheckDegeneration(); - native void CheckAirSupply(); - - virtual void PlayerThink() { let player = self.player; @@ -519,6 +1051,10 @@ class PlayerPawn : Actor native native bool ResetAirSupply (bool playgasp = false); native void CheckWeaponSwitch(class item); native clearscope static String GetPrintableDisplayName(Class cls); + native void CheckMusicChange(); + native void CalcHeight (); + native void CheckEnvironment(); + native void CheckUse(); } @@ -597,7 +1133,7 @@ struct PlayerInfo native play // this is what internally is known as player_t native uint8 playerstate; native readonly uint buttons; native uint original_oldbuttons; - native readonly Class cls; + native Class cls; native float DesiredFOV; native float FOV; native double viewz;