From 34b7e5f435fd3e3a05cb81f6d2b3fb90ec709d71 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 25 Nov 2018 00:23:03 +0100 Subject: [PATCH] - scriptified P_BobWeapon as a virtual function on PlayerPawn. --- src/d_player.h | 1 + src/p_pspr.cpp | 103 +++------------------- src/p_user.cpp | 7 ++ src/scripting/vm/vm.h | 6 ++ wadsrc/static/zscript/constants.txt | 9 ++ wadsrc/static/zscript/shared/player.txt | 112 ++++++++++++++++++++++++ 6 files changed, 145 insertions(+), 93 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index ad6635c21..6099b57ae 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -151,6 +151,7 @@ public: // [SP] ViewBob Multiplier double ViewBob; + double curBob; // Former class properties that were moved into the object to get rid of the meta class. FName SoundClass; // Sound class diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 6634fb7b5..400b34d52 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -579,101 +579,17 @@ void P_BringUpWeapon (player_t *player) void P_BobWeapon (player_t *player, float *x, float *y, double ticfrac) { - static float curbob; - double xx[2], yy[2]; - - AWeapon *weapon; - float bobtarget; - - weapon = player->ReadyWeapon; - - if (weapon == nullptr || weapon->WeaponFlags & WIF_DONTBOB) + IFVIRTUALPTR(player->mo, APlayerPawn, BobWeapon) { - *x = *y = 0; + VMValue param[] = { player->mo, ticfrac }; + DVector2 result; + VMReturn ret(&result); + VMCall(func, param, 2, &ret, 1); + *x = (float)result.X; + *y = (float)result.Y; return; } - - // [XA] Get the current weapon's bob properties. - int bobstyle = weapon->BobStyle; - float BobSpeed = (weapon->BobSpeed * 128); - float Rangex = weapon->BobRangeX; - float Rangey = weapon->BobRangeY; - - for (int i = 0; i < 2; i++) - { - // Bob the weapon based on movement speed. ([SP] And user's bob speed setting) - FAngle angle = (BobSpeed * player->userinfo.GetWBobSpeed() * 35 / - TICRATE*(level.time - 1 + i)) * (360.f / 8192.f); - - // [RH] Smooth transitions between bobbing and not-bobbing frames. - // This also fixes the bug where you can "stick" a weapon off-center by - // shooting it when it's at the peak of its swing. - bobtarget = float((player->WeaponState & WF_WEAPONBOBBING) ? player->bob : 0.); - if (curbob != bobtarget) - { - if (fabsf(bobtarget - curbob) <= 1) - { - curbob = bobtarget; - } - else - { - float zoom = MAX(1.f, fabsf(curbob - bobtarget) / 40); - if (curbob > bobtarget) - { - curbob -= zoom; - } - else - { - curbob += zoom; - } - } - } - - if (curbob != 0) - { - //[SP] Added in decorate player.viewbob checks - float bobx = float(player->bob * Rangex * (float)player->mo->ViewBob); - float boby = float(player->bob * Rangey * (float)player->mo->ViewBob); - switch (bobstyle) - { - case AWeapon::BobNormal: - xx[i] = bobx * angle.Cos(); - yy[i] = boby * fabsf(angle.Sin()); - break; - - case AWeapon::BobInverse: - xx[i] = bobx*angle.Cos(); - yy[i] = boby * (1.f - fabsf(angle.Sin())); - break; - - case AWeapon::BobAlpha: - xx[i] = bobx * angle.Sin(); - yy[i] = boby * fabsf(angle.Sin()); - break; - - case AWeapon::BobInverseAlpha: - xx[i] = bobx * angle.Sin(); - yy[i] = boby * (1.f - fabsf(angle.Sin())); - break; - - case AWeapon::BobSmooth: - xx[i] = bobx*angle.Cos(); - yy[i] = 0.5f * (boby * (1.f - ((angle * 2).Cos()))); - break; - - case AWeapon::BobInverseSmooth: - xx[i] = bobx*angle.Cos(); - yy[i] = 0.5f * (boby * (1.f + ((angle * 2).Cos()))); - } - } - else - { - xx[i] = 0; - yy[i] = 0; - } - } - *x = (float)(xx[0] * (1. - ticfrac) + xx[1] * ticfrac); - *y = (float)(yy[0] * (1. - ticfrac) + yy[1] * ticfrac); + *x = *y = 0; } //============================================================================ @@ -1363,10 +1279,11 @@ float DPSprite::GetYAdjust(bool fullscreen) } else { - return StatusBar->GetDisplacement() * fYAd; + return (float)StatusBar->GetDisplacement() * fYAd; } } } + return 0; } //------------------------------------------------------------------------ diff --git a/src/p_user.cpp b/src/p_user.cpp index e75865fcd..50da7fe9a 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -780,6 +780,12 @@ DEFINE_ACTION_FUNCTION(_PlayerInfo, GetNoAutostartMap) ACTION_RETURN_INT(self->userinfo.GetNoAutostartMap()); } +DEFINE_ACTION_FUNCTION(_PlayerInfo, GetWBobSpeed) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_t); + ACTION_RETURN_FLOAT(self->userinfo.GetWBobSpeed()); +} + //=========================================================================== // @@ -2278,6 +2284,7 @@ DEFINE_FIELD(APlayerPawn, AirCapacity) DEFINE_FIELD(APlayerPawn, FlechetteType) DEFINE_FIELD(APlayerPawn, DamageFade) DEFINE_FIELD(APlayerPawn, ViewBob) +DEFINE_FIELD(APlayerPawn, curBob) DEFINE_FIELD(APlayerPawn, FullHeight) DEFINE_FIELD(APlayerPawn, SoundClass) DEFINE_FIELD(APlayerPawn, Face) diff --git a/src/scripting/vm/vm.h b/src/scripting/vm/vm.h index 030388efd..aabff3c2d 100644 --- a/src/scripting/vm/vm.h +++ b/src/scripting/vm/vm.h @@ -177,6 +177,11 @@ struct VMReturn Location = loc; RegType = REGT_FLOAT; } + void Vec2At(DVector2 *loc) + { + Location = loc; + RegType = REGT_FLOAT | REGT_MULTIREG2; + } void StringAt(FString *loc) { Location = loc; @@ -190,6 +195,7 @@ struct VMReturn VMReturn() { } VMReturn(int *loc) { IntAt(loc); } VMReturn(double *loc) { FloatAt(loc); } + VMReturn(DVector2 *loc) { Vec2At(loc); } VMReturn(FString *loc) { StringAt(loc); } VMReturn(void **loc) { PointerAt(loc); } }; diff --git a/wadsrc/static/zscript/constants.txt b/wadsrc/static/zscript/constants.txt index 8a1240f10..7931c40af 100644 --- a/wadsrc/static/zscript/constants.txt +++ b/wadsrc/static/zscript/constants.txt @@ -1265,3 +1265,12 @@ enum IntermissionSequenceType FSTATE_InLevel = 2 }; +enum Bobbing +{ + Bob_Normal, + Bob_Inverse, + Bob_Alpha, + Bob_InverseAlpha, + Bob_Smooth, + Bob_InverseSmooth +}; diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 2e1cda0e9..998b1ce6b 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -49,6 +49,7 @@ class PlayerPawn : Actor native native color DamageFade; // [CW] Fades for when you are being damaged. native double ViewBob; // [SP] ViewBob Multiplier native double FullHeight; + native double curBob; meta Name HealingRadiusType; meta Name InvulMode; @@ -1939,6 +1940,116 @@ class PlayerPawn : Actor native return player.ReadyWeapon; } + //============================================================================ + // + // P_BobWeapon + // + // [RH] Moved this out of A_WeaponReady so that the weapon can bob every + // tic and not just when A_WeaponReady is called. Not all weapons execute + // A_WeaponReady every tic, and it looks bad if they don't bob smoothly. + // + // [XA] Added new bob styles and exposed bob properties. Thanks, Ryan Cordell! + // [SP] Added new user option for bob speed + // + //============================================================================ + + virtual Vector2 BobWeapon (double ticfrac) + { + Vector2 p1, p2, r; + Vector2 result; + + float bobtarget; + + let player = self.player; + if (!player) return (0, 0); + let weapon = player.ReadyWeapon; + + if (weapon == null || weapon.bDontBob) + { + return (0, 0); + } + + // [XA] Get the current weapon's bob properties. + int bobstyle = weapon.BobStyle; + double BobSpeed = (weapon.BobSpeed * 128); + double Rangex = weapon.BobRangeX; + double Rangey = weapon.BobRangeY; + + for (int i = 0; i < 2; i++) + { + // Bob the weapon based on movement speed. ([SP] And user's bob speed setting) + double angle = (BobSpeed * player.GetWBobSpeed() * 35 / TICRATE*(level.time - 1 + i)) * (360. / 8192.); + + // [RH] Smooth transitions between bobbing and not-bobbing frames. + // This also fixes the bug where you can "stick" a weapon off-center by + // shooting it when it's at the peak of its swing. + bobtarget = double((player.WeaponState & WF_WEAPONBOBBING) ? player.bob : 0.); + if (curbob != bobtarget) + { + if (abs(bobtarget - curbob) <= 1) + { + curbob = bobtarget; + } + else + { + double zoom = MAX(1., abs(curbob - bobtarget) / 40); + if (curbob > bobtarget) + { + curbob -= zoom; + } + else + { + curbob += zoom; + } + } + } + + if (curbob != 0) + { + //[SP] Added in decorate player.viewbob checks + double bobx = (player.bob * Rangex * ViewBob); + double boby = (player.bob * Rangey * ViewBob); + switch (bobstyle) + { + case Bob_Normal: + r.X = bobx * cos(angle); + r.Y = boby * abs(sin(angle)); + break; + + case Bob_Inverse: + r.X = bobx*cos(angle); + r.Y = boby * (1. - abs(sin(angle))); + break; + + case Bob_Alpha: + r.X = bobx * sin(angle); + r.Y = boby * abs(sin(angle)); + break; + + case Bob_InverseAlpha: + r.X = bobx * sin(angle); + r.Y = boby * (1. - abs(sin(angle))); + break; + + case Bob_Smooth: + r.X = bobx*cos(angle); + r.Y = 0.5f * (boby * (1. - (cos(angle * 2)))); + break; + + case Bob_InverseSmooth: + r.X = bobx*cos(angle); + r.Y = 0.5f * (boby * (1. + (cos(angle * 2)))); + } + } + else + { + r = (0, 0); + } + if (i == 0) p1 = r; else p2 = r; + } + return p1 * (1. - ticfrac) + p2 * ticfrac; + } + //---------------------------------------------------------------------------- // @@ -2169,6 +2280,7 @@ struct PlayerInfo native play // self is what internally is known as player_t native int GetTeam() const; native float GetAutoaim() const; native bool GetNoAutostartMap() const; + native double GetWBobSpeed() const; native void SetFOV(float fov); native bool GetClassicFlight() const; native clearscope bool HasWeaponsInSlot(int slot) const;