Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Simon 2023-03-18 10:22:22 +00:00
commit 7536fbfa85
77 changed files with 736 additions and 1237 deletions

View file

@ -178,6 +178,7 @@ CVAR(Bool, disableautoload, false, CVAR_ARCHIVE | CVAR_NOINITCALL | CVAR_GLOBALC
extern int hud_size_max; extern int hud_size_max;
static bool sendPause;
bool pausedWithKey; bool pausedWithKey;
bool gamesetinput = false; bool gamesetinput = false;
@ -1289,6 +1290,12 @@ void CONFIG_ReadCombatMacros()
//========================================================================== //==========================================================================
CCMD(pause)
{
sendPause = true;
}
CCMD(snd_reset) CCMD(snd_reset)
{ {
Mus_Stop(); Mus_Stop();
@ -1512,6 +1519,12 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, GetBuildTime, I_GetBuildTime)
ACTION_RETURN_INT(I_GetBuildTime()); ACTION_RETURN_INT(I_GetBuildTime());
} }
DEFINE_ACTION_FUNCTION_NATIVE(_Raze, forceSyncInput, setForcedSyncInput)
{
setForcedSyncInput();
return 0;
}
DEFINE_ACTION_FUNCTION(_Raze, PickTexture) DEFINE_ACTION_FUNCTION(_Raze, PickTexture)
{ {
PARAM_PROLOGUE; PARAM_PROLOGUE;

View file

@ -235,7 +235,6 @@ enum
extern int paused; extern int paused;
extern int chatmodeon; extern int chatmodeon;
extern bool sendPause;
extern int lastTic; extern int lastTic;
extern int PlayClock; extern int PlayClock;

View file

@ -46,6 +46,7 @@
#include "quotemgr.h" #include "quotemgr.h"
#include "gamestruct.h" #include "gamestruct.h"
#include "statusbar.h" #include "statusbar.h"
#include "coreactor.h"
CVARD(Bool, cl_crosshair, false, CVAR_ARCHIVE, "enable/disable crosshair"); CVARD(Bool, cl_crosshair, false, CVAR_ARCHIVE, "enable/disable crosshair");
CVARD(Bool, cl_automsg, false, CVAR_ARCHIVE, "enable/disable automatically sending messages to all players") // Not implemented for Blood CVARD(Bool, cl_automsg, false, CVAR_ARCHIVE, "enable/disable automatically sending messages to all players") // Not implemented for Blood
@ -235,14 +236,14 @@ ADD_STAT(fps)
ADD_STAT(coord) ADD_STAT(coord)
{ {
auto coord = gi->GetCoordinates();
FString out; FString out;
if (coord.first.X < DBL_MAX) if (const auto pActor = gi->getConsoleActor())
{ {
out.AppendFormat("X: %f ", coord.first.X); out.AppendFormat("X: %.4f ", pActor->spr.pos.X);
out.AppendFormat("Y: %f ", coord.first.Y); out.AppendFormat("Y: %.4f ", pActor->spr.pos.Y);
out.AppendFormat("Z: %f ", coord.first.Z); out.AppendFormat("Z: %.4f ", pActor->spr.pos.Z);
out.AppendFormat("Angle: %f\n", coord.second.Degrees()); out.AppendFormat("Yaw: %.4f ", pActor->spr.Angles.Yaw.Degrees());
out.AppendFormat("Pitch: %.4f\n", pActor->spr.Angles.Pitch.Degrees());
} }
return out; return out;
} }

View file

@ -21,11 +21,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
#include "gamecontrol.h" #include "menu.h"
#include "gamestate.h"
#include "gameinput.h" #include "gameinput.h"
#include "gamestruct.h"
#include "serializer.h"
#include "gamefuncs.h"
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
@ -53,6 +51,7 @@ static constexpr double PITCH_HORIZOFFSPEED = 4.375;
static constexpr DAngle PITCH_CNTRSINEOFFSET = DAngle90 / 8.; static constexpr DAngle PITCH_CNTRSINEOFFSET = DAngle90 / 8.;
static constexpr DAngle PITCH_HORIZOFFCLIMB = DAngle::fromDeg(-38.); static constexpr DAngle PITCH_HORIZOFFCLIMB = DAngle::fromDeg(-38.);
static constexpr DAngle PITCH_HORIZOFFPUSH = DAngle::fromDeg(0.4476); static constexpr DAngle PITCH_HORIZOFFPUSH = DAngle::fromDeg(0.4476);
static InputPacket inputBuffer{};
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -73,7 +72,7 @@ static inline DAngle getscaledangle(const DAngle angle, const double scale, cons
static inline bool scaletozero(DAngle& angle, const double scale, const DAngle push = DAngle::fromDeg(32. / 465.)) static inline bool scaletozero(DAngle& angle, const double scale, const DAngle push = DAngle::fromDeg(32. / 465.))
{ {
auto sgn = angle.Sgn(); const auto sgn = angle.Sgn();
if (!sgn || sgn != (angle -= getscaledangle(angle, scale, push * sgn)).Sgn()) if (!sgn || sgn != (angle -= getscaledangle(angle, scale, push * sgn)).Sgn())
{ {
@ -92,7 +91,7 @@ static inline bool scaletozero(DAngle& angle, const double scale, const DAngle p
static double turnheldtime; static double turnheldtime;
void updateTurnHeldAmt(double const scaleAdjust) void updateTurnHeldAmt(const double scaleAdjust)
{ {
turnheldtime += getTicrateScale(BUILDTICRATE) * scaleAdjust; turnheldtime += getTicrateScale(BUILDTICRATE) * scaleAdjust;
} }
@ -117,36 +116,36 @@ extern int resyncVRYawWithGame;
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void processMovement(InputPacket* const currInput, InputPacket* const inputBuffer, ControlInfo* const hidInput, double const scaleAdjust, int const drink_amt, bool const allowstrafe, double const turnscale) void processMovement(HIDInput* const hidInput, InputPacket* const inputBuffer, InputPacket* const currInput, const double scaleAdjust, const int drink_amt, const bool allowstrafe, const double turnscale)
{ {
// set up variables. // set up variables.
int const keymove = 1 << int(!!(inputBuffer->actions & SB_RUN)); const int keymove = 1 << int(!!(inputBuffer->actions & SB_RUN));
float const hidspeed = float(getTicrateScale(YAW_TURNSPEEDS[2]) * turnscale); const float hidspeed = float(getTicrateScale(YAW_TURNSPEEDS[2]) * turnscale);
float const scaleAdjustf = float(scaleAdjust); const float scaleAdjustf = float(scaleAdjust);
// determine player input. // determine player input.
auto const turning = buttonMap.ButtonDown(gamefunc_Turn_Right) - buttonMap.ButtonDown(gamefunc_Turn_Left); const auto turning = buttonMap.ButtonDown(gamefunc_Turn_Right) - buttonMap.ButtonDown(gamefunc_Turn_Left);
auto const moving = buttonMap.ButtonDown(gamefunc_Move_Forward) - buttonMap.ButtonDown(gamefunc_Move_Backward) + hidInput->dz * scaleAdjustf; const auto moving = buttonMap.ButtonDown(gamefunc_Move_Forward) - buttonMap.ButtonDown(gamefunc_Move_Backward) + hidInput->joyaxes[JOYAXIS_Forward] * scaleAdjustf;
auto const strafing = buttonMap.ButtonDown(gamefunc_Strafe_Right) - buttonMap.ButtonDown(gamefunc_Strafe_Left) - hidInput->dx * scaleAdjustf; const auto strafing = buttonMap.ButtonDown(gamefunc_Strafe_Right) - buttonMap.ButtonDown(gamefunc_Strafe_Left) - hidInput->joyaxes[JOYAXIS_Side] * scaleAdjustf;
// process player angle input. // process player angle input.
if (!(buttonMap.ButtonDown(gamefunc_Strafe) && allowstrafe)) if (!(buttonMap.ButtonDown(gamefunc_Strafe) && allowstrafe))
{ {
float const turndir = clamp(turning + strafing * !allowstrafe, -1.f, 1.f); const float turndir = clamp(turning + strafing * !allowstrafe, -1.f, 1.f);
float const turnspeed = float(getTicrateScale(YAW_TURNSPEEDS[keymove]) * turnscale * (isTurboTurnTime() ? 1. : YAW_PREAMBLESCALE)); const float turnspeed = float(getTicrateScale(YAW_TURNSPEEDS[keymove]) * turnscale * (isTurboTurnTime() ? 1. : YAW_PREAMBLESCALE));
currInput->avel += hidInput->mouseturnx + (hidInput->dyaw * hidspeed + turndir * turnspeed) * scaleAdjustf; currInput->avel += hidInput->mouseturnx - (hidInput->joyaxes[JOYAXIS_Yaw] * hidspeed - turndir * turnspeed) * scaleAdjustf;
if (turndir) updateTurnHeldAmt(scaleAdjust); else resetTurnHeldAmt(); if (turndir) updateTurnHeldAmt(scaleAdjust); else resetTurnHeldAmt();
} }
else else
{ {
currInput->svel += hidInput->mousemovex + (hidInput->dyaw + turning) * keymove * scaleAdjustf; currInput->svel += hidInput->mousemovex - (hidInput->joyaxes[JOYAXIS_Yaw] - turning) * keymove * scaleAdjustf;
} }
// process player pitch input. // process player pitch input.
if (!(inputBuffer->actions & SB_AIMMODE)) if (!(inputBuffer->actions & SB_AIMMODE))
currInput->horz += hidInput->mouseturny + hidInput->dpitch * hidspeed * scaleAdjustf; currInput->horz += hidInput->mouseturny - hidInput->joyaxes[JOYAXIS_Pitch] * hidspeed * scaleAdjustf;
else else
currInput->fvel -= hidInput->mousemovey + hidInput->dpitch * keymove * scaleAdjustf; currInput->fvel -= hidInput->mousemovey - hidInput->joyaxes[JOYAXIS_Pitch] * keymove * scaleAdjustf;
// process movement input. // process movement input.
currInput->fvel += moving * keymove; currInput->fvel += moving * keymove;
@ -178,36 +177,77 @@ void processMovement(InputPacket* const currInput, InputPacket* const inputBuffe
} }
//---------------------------------------------------------------------------
//
// Processes input and returns a packet if provided.
//
//---------------------------------------------------------------------------
void clearLocalInputBuffer()
{
inputBuffer = {};
}
void getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet)
{
if (paused || M_Active() || gamestate != GS_LEVEL || !plrAngles || !plrAngles->pActor)
{
clearLocalInputBuffer();
return;
}
InputPacket input{};
HIDInput hidInput{};
getHidInput(&hidInput);
ApplyGlobalInput(&hidInput, &inputBuffer);
gi->GetInput(&hidInput, &inputBuffer, &input, !SyncInput() ? scaleAdjust : 1.);
// Directly update the camera angles if we're unsynchronised.
if (!SyncInput())
{
plrAngles->CameraAngles.Yaw += DAngle::fromDeg(input.avel);
plrAngles->CameraAngles.Pitch += DAngle::fromDeg(input.horz);
}
if (packet)
{
*packet = inputBuffer;
clearLocalInputBuffer();
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// Adjust player's pitch by way of keyboard input. // Adjust player's pitch by way of keyboard input.
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void PlayerAngles::doPitchKeys(ESyncBits* actions, const bool stopcentering) void PlayerAngles::doPitchKeys(InputPacket* const input)
{ {
// Cancel return to center if conditions met. // Cancel return to center if conditions met.
if (stopcentering) *actions &= ~SB_CENTERVIEW; if (input->horz)
input->actions &= ~SB_CENTERVIEW;
// Process keyboard input. // Process keyboard input.
if (auto aiming = !!(*actions & SB_AIM_DOWN) - !!(*actions & SB_AIM_UP)) if (const auto aiming = !!(input->actions & SB_AIM_DOWN) - !!(input->actions & SB_AIM_UP))
{ {
pActor->spr.Angles.Pitch += DAngle::fromDeg(getTicrateScale(PITCH_AIMSPEED)) * aiming; pActor->spr.Angles.Pitch += DAngle::fromDeg(getTicrateScale(PITCH_AIMSPEED) * aiming);
*actions &= ~SB_CENTERVIEW; input->actions &= ~SB_CENTERVIEW;
} }
if (auto looking = !!(*actions & SB_LOOK_DOWN) - !!(*actions & SB_LOOK_UP)) if (const auto looking = !!(input->actions & SB_LOOK_DOWN) - !!(input->actions & SB_LOOK_UP))
{ {
pActor->spr.Angles.Pitch += DAngle::fromDeg(getTicrateScale(PITCH_LOOKSPEED)) * looking; pActor->spr.Angles.Pitch += DAngle::fromDeg(getTicrateScale(PITCH_LOOKSPEED) * looking);
*actions |= SB_CENTERVIEW; input->actions |= SB_CENTERVIEW;
} }
// Do return to centre. // Do return to centre.
if ((*actions & SB_CENTERVIEW) && !(*actions & (SB_LOOK_UP|SB_LOOK_DOWN))) if ((input->actions & SB_CENTERVIEW) && !(input->actions & (SB_LOOK_UP|SB_LOOK_DOWN)))
{ {
const auto pitch = abs(pActor->spr.Angles.Pitch); const auto pitch = abs(pActor->spr.Angles.Pitch);
const auto scale = pitch > PITCH_CNTRSINEOFFSET ? (pitch - PITCH_CNTRSINEOFFSET).Cos() : 1.; const auto scale = pitch > PITCH_CNTRSINEOFFSET ? (pitch - PITCH_CNTRSINEOFFSET).Cos() : 1.;
if (scaletozero(pActor->spr.Angles.Pitch, PITCH_CENTERSPEED * scale)) if (scaletozero(pActor->spr.Angles.Pitch, PITCH_CENTERSPEED * scale))
*actions &= ~SB_CENTERVIEW; input->actions &= ~SB_CENTERVIEW;
} }
// clamp before we finish, factoring in the player's view pitch offset. // clamp before we finish, factoring in the player's view pitch offset.
@ -223,22 +263,22 @@ void PlayerAngles::doPitchKeys(ESyncBits* actions, const bool stopcentering)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void PlayerAngles::doYawKeys(ESyncBits* actions) void PlayerAngles::doYawKeys(InputPacket* const input)
{ {
if (*actions & SB_TURNAROUND) if (input->actions & SB_TURNAROUND)
{ {
if (YawSpin == nullAngle) if (YawSpin == nullAngle)
{ {
// currently not spinning, so start a spin // currently not spinning, so start a spin
YawSpin = -DAngle180; YawSpin = -DAngle180;
} }
*actions &= ~SB_TURNAROUND; input->actions &= ~SB_TURNAROUND;
} }
if (YawSpin < nullAngle) if (YawSpin < nullAngle)
{ {
// return spin to 0 // return spin to 0
DAngle add = DAngle::fromDeg(getTicrateScale(!(*actions & SB_CROUCH) ? YAW_SPINSTAND : YAW_SPINCROUCH)); DAngle add = DAngle::fromDeg(getTicrateScale(!(input->actions & SB_CROUCH) ? YAW_SPINSTAND : YAW_SPINCROUCH));
YawSpin += add; YawSpin += add;
if (YawSpin > nullAngle) if (YawSpin > nullAngle)
{ {
@ -257,51 +297,52 @@ void PlayerAngles::doYawKeys(ESyncBits* actions)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void PlayerAngles::doViewPitch(const DVector2& pos, DAngle const ang, bool const aimmode, bool const canslopetilt, sectortype* const cursectnum, bool const climbing) void PlayerAngles::doViewPitch(const bool canslopetilt, const bool climbing)
{ {
if (cl_slopetilting && cursectnum != nullptr) if (cl_slopetilting && canslopetilt)
{ {
if (aimmode && canslopetilt) // If the floor is sloped const auto actorsect = pActor->sector();
if (actorsect && (actorsect->floorstat & CSTAT_SECTOR_SLOPE)) // If the floor is sloped
{ {
// Get a point, 512 (64 for Blood) units ahead of player's position // Get a point, 512 (64 for Blood) units ahead of player's position
auto rotpt = pos + ang.ToVector() * (!isBlood() ? 32 : 4); const auto rotpt = pActor->spr.pos.XY() + pActor->spr.Angles.Yaw.ToVector() * (!isBlood() ? 32 : 4);
auto tempsect = cursectnum; auto tempsect = actorsect;
updatesector(rotpt, &tempsect); updatesector(rotpt, &tempsect);
if (tempsect != nullptr) // If the new point is inside a valid sector... if (tempsect != nullptr) // If the new point is inside a valid sector...
{ {
// Get the floorz as if the new (x,y) point was still in // Get the floorz as if the new (x,y) point was still in
// your sector, unless it's Blood. // your sector, unless it's Blood.
double const j = getflorzofslopeptr(cursectnum, pos); const double j = getflorzofslopeptr(actorsect, pActor->spr.pos.XY());
double const k = getflorzofslopeptr(!isBlood() ? cursectnum : tempsect, rotpt); const double k = getflorzofslopeptr(!isBlood() ? actorsect : tempsect, rotpt);
// If extended point is in same sector as you or the slopes // If extended point is in same sector as you or the slopes
// of the sector of the extended point and your sector match // of the sector of the extended point and your sector match
// closely (to avoid accidently looking straight out when // closely (to avoid accidently looking straight out when
// you're at the edge of a sector line) then adjust horizon // you're at the edge of a sector line) then adjust horizon
// accordingly // accordingly
if (cursectnum == tempsect || (!isBlood() && abs(getflorzofslopeptr(tempsect, rotpt) - k) <= 4)) if (actorsect == tempsect || (!isBlood() && abs(getflorzofslopeptr(tempsect, rotpt) - k) <= 4))
{ {
ViewAngles.Pitch -= maphoriz((j - k) * (!isBlood() ? 0.625 : 5.5)); ViewAngles.Pitch -= maphoriz((j - k) * (!isBlood() ? 0.625 : 5.5));
} }
} }
} }
if (climbing)
{
// tilt when climbing but you can't even really tell it.
if (ViewAngles.Pitch > PITCH_HORIZOFFCLIMB)
ViewAngles.Pitch += getscaledangle(deltaangle(ViewAngles.Pitch, PITCH_HORIZOFFCLIMB), PITCH_HORIZOFFSPEED, PITCH_HORIZOFFPUSH);
}
else
{
// Make horizoff grow towards 0 since horizoff is not modified when you're not on a slope.
scaletozero(ViewAngles.Pitch, PITCH_HORIZOFFSPEED, PITCH_HORIZOFFPUSH);
}
// Clamp off against the maximum allowed pitch.
ViewAngles.Pitch = ClampViewPitch(ViewAngles.Pitch);
} }
if (cl_slopetilting && climbing)
{
// tilt when climbing but you can't even really tell it.
if (ViewAngles.Pitch > PITCH_HORIZOFFCLIMB)
ViewAngles.Pitch += getscaledangle(deltaangle(ViewAngles.Pitch, PITCH_HORIZOFFCLIMB), PITCH_HORIZOFFSPEED, PITCH_HORIZOFFPUSH);
}
else
{
// Make horizoff grow towards 0 since horizoff is not modified when you're not on a slope.
scaletozero(ViewAngles.Pitch, PITCH_HORIZOFFSPEED, PITCH_HORIZOFFPUSH);
}
// Clamp off against the maximum allowed pitch.
ViewAngles.Pitch = ClampViewPitch(ViewAngles.Pitch);
} }
@ -311,7 +352,7 @@ void PlayerAngles::doViewPitch(const DVector2& pos, DAngle const ang, bool const
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void PlayerAngles::doViewYaw(const ESyncBits actions) void PlayerAngles::doViewYaw(InputPacket* const input)
{ {
if (ViewAngles.Yaw.Degrees() != 0.0f || if (ViewAngles.Yaw.Degrees() != 0.0f ||
ViewAngles.Roll.Degrees() != 0.0f) ViewAngles.Roll.Degrees() != 0.0f)
@ -324,10 +365,10 @@ void PlayerAngles::doViewYaw(const ESyncBits actions)
scaletozero(ViewAngles.Roll, YAW_LOOKRETURN); scaletozero(ViewAngles.Roll, YAW_LOOKRETURN);
// Process keyboard input. // Process keyboard input.
if (auto looking = !!(actions & SB_LOOK_RIGHT) - !!(actions & SB_LOOK_LEFT)) if (const auto looking = !!(input->actions & SB_LOOK_RIGHT) - !!(input->actions & SB_LOOK_LEFT))
{ {
ViewAngles.Yaw += DAngle::fromDeg(getTicrateScale(YAW_LOOKINGSPEED)) * looking; ViewAngles.Yaw += DAngle::fromDeg(getTicrateScale(YAW_LOOKINGSPEED) * looking);
ViewAngles.Roll += DAngle::fromDeg(getTicrateScale(YAW_ROTATESPEED)) * looking; ViewAngles.Roll += DAngle::fromDeg(getTicrateScale(YAW_ROTATESPEED) * looking);
} }
} }
@ -349,7 +390,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, P
if (arc.isReading()) if (arc.isReading())
{ {
w.resetRenderAngles(); w.resetCameraAngles();
} }
} }
return arc; return arc;

View file

@ -1,34 +1,29 @@
#pragma once #pragma once
#include "m_fixed.h" #include "serializer.h"
#include "gamecvars.h"
#include "gamestruct.h"
#include "gamefuncs.h" #include "gamefuncs.h"
#include "packet.h"
struct PlayerAngles struct PlayerAngles
{ {
// Player viewing angles, separate from the camera. // Player viewing angles, separate from the camera.
DRotator PrevViewAngles, ViewAngles; DRotator PrevViewAngles, ViewAngles;
// Player camera angles, not for direct manipulation within the playsim.
DRotator RenderAngles;
// Holder of current yaw spin state for the 180 degree turn. // Holder of current yaw spin state for the 180 degree turn.
DAngle YawSpin; DAngle YawSpin;
friend FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def); friend FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def);
friend void getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet);
// Prototypes. // Prototypes.
void doPitchKeys(ESyncBits* actions, const bool stopcentering); void doPitchKeys(InputPacket* const input);
void doYawKeys(ESyncBits* actions); void doYawKeys(InputPacket* const input);
void doViewPitch(const DVector2& pos, DAngle const ang, bool const aimmode, bool const canslopetilt, sectortype* const cursectnum, bool const climbing = false); void doViewPitch(const bool canslopetilt, const bool climbing = false);
void doViewYaw(const ESyncBits actions); void doViewYaw(InputPacket* const input);
// General methods. // General methods.
void initialize(DCoreActor* const actor, const DAngle viewyaw = nullAngle) void initialize(DCoreActor* const actor, const DAngle viewyaw = nullAngle)
{ {
if (pActor = actor) RenderAngles = PrevLerpAngles = pActor->spr.Angles; if (pActor = actor) CameraAngles = PrevLerpAngles = pActor->spr.Angles;
PrevViewAngles.Yaw = ViewAngles.Yaw = viewyaw; PrevViewAngles.Yaw = ViewAngles.Yaw = viewyaw;
} }
DAngle getPitchWithView() DAngle getPitchWithView()
@ -37,25 +32,29 @@ struct PlayerAngles
} }
// Render angle functions. // Render angle functions.
const DRotator& getCameraAngles() const
{
return CameraAngles;
}
DRotator getRenderAngles(const double interpfrac) DRotator getRenderAngles(const double interpfrac)
{ {
// Get angles and return with clamped off pitch. // Get angles and return with clamped off pitch.
auto angles = RenderAngles + interpolatedvalue(PrevViewAngles, ViewAngles, interpfrac); auto angles = CameraAngles + interpolatedvalue(PrevViewAngles, ViewAngles, interpfrac);
angles.Pitch = ClampViewPitch(angles.Pitch); angles.Pitch = ClampViewPitch(angles.Pitch);
return angles; return angles;
} }
void updateRenderAngles(const double interpfrac) void updateCameraAngles(const double interpfrac)
{ {
// Apply the current interpolated angle state to the render angles. // Apply the current interpolated angle state to the render angles.
const auto lerpAngles = interpolatedvalue(pActor->PrevAngles, pActor->spr.Angles, interpfrac); const auto lerpAngles = interpolatedvalue(pActor->PrevAngles, pActor->spr.Angles, interpfrac);
RenderAngles += lerpAngles - PrevLerpAngles; CameraAngles += lerpAngles - PrevLerpAngles;
PrevLerpAngles = lerpAngles; PrevLerpAngles = lerpAngles;
} }
void resetRenderAngles() void resetCameraAngles()
{ {
// Apply any last remaining ticrate angle updates and reset variables. // Apply any last remaining ticrate angle updates and reset variables.
RenderAngles += pActor->spr.Angles - PrevLerpAngles; CameraAngles += pActor->spr.Angles - PrevLerpAngles;
PrevLerpAngles = pActor->spr.Angles = RenderAngles; PrevLerpAngles = pActor->spr.Angles = CameraAngles;
PrevViewAngles = ViewAngles; PrevViewAngles = ViewAngles;
} }
@ -68,14 +67,14 @@ struct PlayerAngles
} }
auto getWeaponOffsets(const double interpfrac) auto getWeaponOffsets(const double interpfrac)
{ {
// Push the Y down a bit since the weapon is at the edge of the screen. // Push the Y down a bit since the weapon is at the edge of the screen. Also null roll for now.
auto offsets = getCrosshairOffsets(interpfrac); offsets.first.Y *= 4.; auto offsets = getCrosshairOffsets(interpfrac); offsets.first.Y *= 4.; offsets.second = nullAngle;
return offsets; return offsets;
} }
private: private:
// Private data which should never be accessed publically. // Private data which should never be accessed publicly.
DRotator PrevLerpAngles; DRotator PrevLerpAngles, CameraAngles;
DCoreActor* pActor; DCoreActor* pActor;
}; };
@ -83,7 +82,8 @@ 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 updateTurnHeldAmt(double const scaleAdjust); void updateTurnHeldAmt(const double scaleAdjust);
bool isTurboTurnTime(); bool isTurboTurnTime();
void resetTurnHeldAmt(); void resetTurnHeldAmt();
void processMovement(InputPacket* const currInput, InputPacket* const inputBuffer, ControlInfo* const hidInput, double const scaleAdjust, int const drink_amt = 0, bool const allowstrafe = true, double const turnscale = 1); void clearLocalInputBuffer();
void getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet = nullptr);

View file

@ -17,6 +17,9 @@ struct sectortype;
struct tspritetype; struct tspritetype;
class DCoreActor; class DCoreActor;
struct MapRecord; struct MapRecord;
struct PlayerAngles;
void processMovement(HIDInput* const hidInput, InputPacket* const inputBuffer, InputPacket* const currInput, const double scaleAdjust, const int drink_amt = 0, const bool allowstrafe = true, const double turnscale = 1.);
struct GameStats struct GameStats
{ {
@ -69,7 +72,6 @@ struct GameInterface
virtual void LoadTextureInfo(TilesetBuildInfo& info) {} virtual void LoadTextureInfo(TilesetBuildInfo& info) {}
virtual void SetupSpecialTextures(TilesetBuildInfo&) {} virtual void SetupSpecialTextures(TilesetBuildInfo&) {}
virtual void loadPalette(); virtual void loadPalette();
virtual void clearlocalinputstate() {}
virtual void UpdateScreenSize() {} virtual void UpdateScreenSize() {}
virtual void FreeLevelData(); virtual void FreeLevelData();
virtual void FreeGameData() {} virtual void FreeGameData() {}
@ -87,9 +89,8 @@ struct GameInterface
virtual void SerializeGameState(FSerializer& arc) {} virtual void SerializeGameState(FSerializer& arc) {}
virtual void DrawPlayerSprite(const DVector2& origin, bool onteam) {} virtual void DrawPlayerSprite(const DVector2& origin, bool onteam) {}
virtual void SetAmbience(bool on) {} virtual void SetAmbience(bool on) {}
virtual std::pair<DVector3, DAngle> GetCoordinates() { return {}; }
virtual void ExitFromMenu() { throw CExitEvent(0); } virtual void ExitFromMenu() { throw CExitEvent(0); }
virtual void GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet = nullptr) {} virtual void GetInput(HIDInput* const hidInput, InputPacket* const inputBuffer, InputPacket* const currInput, const double scaleAdjust) { processMovement(hidInput, inputBuffer, currInput, scaleAdjust); }
virtual void UpdateSounds() {} virtual void UpdateSounds() {}
virtual void ErrorCleanup() {} virtual void ErrorCleanup() {}
virtual void Startup() {} virtual void Startup() {}
@ -105,7 +106,8 @@ struct GameInterface
virtual bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) { return false; } virtual bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) { return false; }
virtual DAngle playerPitchMin() { return DAngle::fromDeg(57.375); } virtual DAngle playerPitchMin() { return DAngle::fromDeg(57.375); }
virtual DAngle playerPitchMax() { return DAngle::fromDeg(-57.375); } virtual DAngle playerPitchMax() { return DAngle::fromDeg(-57.375); }
virtual void WarpToCoords(double x, double y, double z, DAngle a) {} virtual DCoreActor* getConsoleActor() = 0;
virtual PlayerAngles* getConsoleAngles() = 0;
virtual void ToggleThirdPerson() { } virtual void ToggleThirdPerson() { }
virtual void SwitchCoopView() { Printf("Unsupported command\n"); } virtual void SwitchCoopView() { Printf("Unsupported command\n"); }
virtual void ToggleShowWeapon() { Printf("Unsupported command\n"); } virtual void ToggleShowWeapon() { Printf("Unsupported command\n"); }

View file

@ -48,7 +48,6 @@
static int WeaponToSend = 0; static int WeaponToSend = 0;
ESyncBits ActionsToSend = 0; ESyncBits ActionsToSend = 0;
static int dpad_lock = 0; static int dpad_lock = 0;
bool sendPause;
bool crouch_toggle; bool crouch_toggle;
// Mouse speeds // Mouse speeds
@ -65,7 +64,7 @@ CVARD(Bool, invertmouse, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "invert vertic
// //
//========================================================================== //==========================================================================
void InputState::GetMouseDelta(ControlInfo * hidInput) void InputState::GetMouseDelta(HIDInput * hidInput)
{ {
g_mousePos *= backendinputscale(); g_mousePos *= backendinputscale();
@ -142,7 +141,7 @@ void InputState::ClearAllInput()
{ {
ActionsToSend = 0; ActionsToSend = 0;
crouch_toggle = false; crouch_toggle = false;
gi->clearlocalinputstate(); // also clear game local input state. clearLocalInputBuffer(); // also clear game local input state.
} }
else if (gamestate == GS_LEVEL && crouch_toggle) else if (gamestate == GS_LEVEL && crouch_toggle)
{ {
@ -195,34 +194,6 @@ int32_t handleevents(void)
return 0; return 0;
} }
//==========================================================================
//
//
//
//==========================================================================
ControlInfo CONTROL_GetInput()
{
ControlInfo hidInput {};
inputState.GetMouseDelta(&hidInput);
if (use_joystick)
{
// Handle joysticks/game controllers.
float joyaxes[NUM_JOYAXIS];
I_GetAxes(joyaxes);
hidInput.dyaw += -joyaxes[JOYAXIS_Yaw];
hidInput.dx += joyaxes[JOYAXIS_Side] * .5f;
hidInput.dz += joyaxes[JOYAXIS_Forward] * .5f;
hidInput.dpitch += -joyaxes[JOYAXIS_Pitch];
}
return hidInput;
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //
@ -351,11 +322,6 @@ CCMD(holsterweapon)
ActionsToSend |= SB_HOLSTER; ActionsToSend |= SB_HOLSTER;
} }
CCMD(pause)
{
sendPause = true;
}
CCMD(warptocoords) CCMD(warptocoords)
{ {
if (netgame) if (netgame)
@ -365,7 +331,7 @@ CCMD(warptocoords)
} }
if (argv.argc() < 4) if (argv.argc() < 4)
{ {
Printf("warptocoords [x] [y] [z] [ang] (optional) [horiz] (optional): warps the player to the specified coordinates\n"); Printf("warptocoords [x] [y] [z] [yaw] (optional) [pitch] (optional): warps the player to the specified coordinates\n");
return; return;
} }
if (gamestate != GS_LEVEL) if (gamestate != GS_LEVEL)
@ -373,20 +339,14 @@ CCMD(warptocoords)
Printf("warptocoords: must be in a level\n"); Printf("warptocoords: must be in a level\n");
return; return;
} }
int x = atoi(argv[1]);
int y = atoi(argv[2]);
int z = atoi(argv[3]);
int ang = INT_MIN, horiz = INT_MIN;
if (argv.argc() > 4)
{
ang = atoi(argv[4]);
}
if (argv.argc() > 5)
{
horiz = atoi(argv[5]);
}
gi->WarpToCoords(x, y, z, DAngle::fromDeg(ang)); if (const auto pActor = gi->getConsoleActor())
{
pActor->spr.pos = DVector3(atof(argv[1]), atof(argv[2]), atof(argv[3]));
if (argv.argc() > 4) pActor->spr.Angles.Yaw = DAngle::fromDeg(atof(argv[4]));
if (argv.argc() > 5) pActor->spr.Angles.Pitch = DAngle::fromDeg(atof(argv[5]));
pActor->backuploc();
}
} }
CCMD(third_person_view) CCMD(third_person_view)
@ -404,84 +364,87 @@ CCMD(show_weapon)
gi->ToggleShowWeapon(); gi->ToggleShowWeapon();
} }
void ApplyGlobalInput(InputPacket& input, ControlInfo* hidInput, bool const crouchable, bool const disableToggle) void ApplyGlobalInput(HIDInput* const hidInput, InputPacket* const inputBuffer)
{ {
if (WeaponToSend != 0) input.setNewWeapon(WeaponToSend); if (WeaponToSend != 0) inputBuffer->setNewWeapon(WeaponToSend);
WeaponToSend = 0; WeaponToSend = 0;
if (hidInput && buttonMap.ButtonDown(gamefunc_Dpad_Select)) if (hidInput && buttonMap.ButtonDown(gamefunc_Dpad_Select))
{ {
// These buttons should not autorepeat. The game handlers are not really equipped for that. // These buttons should not autorepeat. The game handlers are not really equipped for that.
if (hidInput->dz > 0 && !(dpad_lock & 1)) { dpad_lock |= 1; input.setNewWeapon(WeaponSel_Prev); } if (hidInput->joyaxes[JOYAXIS_Forward] > 0 && !(dpad_lock & 1)) { dpad_lock |= 1; inputBuffer->setNewWeapon(WeaponSel_Prev); }
else dpad_lock &= ~1; else dpad_lock &= ~1;
if (hidInput->dz < 0 && !(dpad_lock & 2)) { dpad_lock |= 2; input.setNewWeapon(WeaponSel_Next); } if (hidInput->joyaxes[JOYAXIS_Forward] < 0 && !(dpad_lock & 2)) { dpad_lock |= 2; inputBuffer->setNewWeapon(WeaponSel_Next); }
else dpad_lock &= ~2; else dpad_lock &= ~2;
if ((hidInput->dx < 0 || hidInput->dyaw < 0) && !(dpad_lock & 4)) { dpad_lock |= 4; input.actions |= SB_INVPREV; } if ((hidInput->joyaxes[JOYAXIS_Side] < 0 || hidInput->joyaxes[JOYAXIS_Yaw] > 0) && !(dpad_lock & 4)) { dpad_lock |= 4; inputBuffer->actions |= SB_INVPREV; }
else dpad_lock &= ~4; else dpad_lock &= ~4;
if ((hidInput->dx > 0 || hidInput->dyaw > 0) && !(dpad_lock & 8)) { dpad_lock |= 8; input.actions |= SB_INVNEXT; } if ((hidInput->joyaxes[JOYAXIS_Side] > 0 || hidInput->joyaxes[JOYAXIS_Yaw] < 0) && !(dpad_lock & 8)) { dpad_lock |= 8; inputBuffer->actions |= SB_INVNEXT; }
else dpad_lock &= ~8; else dpad_lock &= ~8;
// This eats the controller input for regular use // This eats the controller inputBuffer-> for regular use
hidInput->dx = 0; hidInput->joyaxes[JOYAXIS_Side] = 0;
hidInput->dz = 0; hidInput->joyaxes[JOYAXIS_Forward] = 0;
hidInput->dyaw = 0; hidInput->joyaxes[JOYAXIS_Yaw] = 0;
} }
else dpad_lock = 0; else dpad_lock = 0;
input.actions |= ActionsToSend; inputBuffer->actions |= ActionsToSend;
ActionsToSend = 0; ActionsToSend = 0;
if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && hidInput->dz > 0)) if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && hidInput->joyaxes[JOYAXIS_Forward] > 0))
input.actions |= SB_AIM_UP; inputBuffer->actions |= SB_AIM_UP;
if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && hidInput->dz < 0))) if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && hidInput->joyaxes[JOYAXIS_Forward] < 0)))
input.actions |= SB_AIM_DOWN; inputBuffer->actions |= SB_AIM_DOWN;
if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming))
hidInput->dz = 0; hidInput->joyaxes[JOYAXIS_Forward] = 0;
if (buttonMap.ButtonDown(gamefunc_Jump)) if (buttonMap.ButtonDown(gamefunc_Jump))
input.actions |= SB_JUMP; inputBuffer->actions |= SB_JUMP;
if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || crouch_toggle) if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || crouch_toggle)
input.actions |= SB_CROUCH; inputBuffer->actions |= SB_CROUCH;
if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch)) if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch))
{ {
crouch_toggle = !crouch_toggle && crouchable; crouch_toggle = !crouch_toggle;
if (crouchable) buttonMap.ClearButton(gamefunc_Toggle_Crouch); buttonMap.ClearButton(gamefunc_Toggle_Crouch);
} }
if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Jump) || disableToggle) if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Jump))
crouch_toggle = false; crouch_toggle = false;
if (buttonMap.ButtonDown(gamefunc_Fire)) if (buttonMap.ButtonDown(gamefunc_Fire))
input.actions |= SB_FIRE; inputBuffer->actions |= SB_FIRE;
if (buttonMap.ButtonDown(gamefunc_Alt_Fire)) if (buttonMap.ButtonDown(gamefunc_Alt_Fire))
input.actions |= SB_ALTFIRE; inputBuffer->actions |= SB_ALTFIRE;
if (buttonMap.ButtonDown(gamefunc_Open)) if (buttonMap.ButtonDown(gamefunc_Open))
{ {
if (isBlood()) buttonMap.ClearButton(gamefunc_Open); if (isBlood()) buttonMap.ClearButton(gamefunc_Open);
input.actions |= SB_OPEN; inputBuffer->actions |= SB_OPEN;
} }
if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run))) if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)))
input.actions |= SB_RUN; inputBuffer->actions |= SB_RUN;
if (!in_mousemode && !buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) if (!in_mousemode && !buttonMap.ButtonDown(gamefunc_Mouse_Aiming))
input.actions |= SB_AIMMODE; inputBuffer->actions |= SB_AIMMODE;
if (buttonMap.ButtonDown(gamefunc_Look_Up)) if (buttonMap.ButtonDown(gamefunc_Look_Up))
input.actions |= SB_LOOK_UP; inputBuffer->actions |= SB_LOOK_UP;
if (buttonMap.ButtonDown(gamefunc_Look_Down)) if (buttonMap.ButtonDown(gamefunc_Look_Down))
input.actions |= SB_LOOK_DOWN; inputBuffer->actions |= SB_LOOK_DOWN;
if (buttonMap.ButtonDown(gamefunc_Look_Left)) if (buttonMap.ButtonDown(gamefunc_Look_Left))
input.actions |= SB_LOOK_LEFT; inputBuffer->actions |= SB_LOOK_LEFT;
if (buttonMap.ButtonDown(gamefunc_Look_Right)) if (buttonMap.ButtonDown(gamefunc_Look_Right))
input.actions |= SB_LOOK_RIGHT; inputBuffer->actions |= SB_LOOK_RIGHT;
if (buttonMap.ButtonDown(gamefunc_Quick_Kick))
inputBuffer->actions |= SB_QUICK_KICK;
} }

View file

@ -14,14 +14,9 @@
#include "vectors.h" #include "vectors.h"
struct ControlInfo struct HIDInput
{ {
float dx; float joyaxes[NUM_JOYAXIS];
float dy;
float dz;
float dyaw;
float dpitch;
float droll;
float mouseturnx; float mouseturnx;
float mouseturny; float mouseturny;
float mousemovex; float mousemovex;
@ -50,7 +45,7 @@ public:
g_mousePos.Y += y; g_mousePos.Y += y;
} }
void GetMouseDelta(ControlInfo* hidInput); void GetMouseDelta(HIDInput* hidInput);
void ClearAllInput(); void ClearAllInput();
bool CheckAllInput() bool CheckAllInput()
@ -63,7 +58,6 @@ public:
extern InputState inputState; extern InputState inputState;
ControlInfo CONTROL_GetInput();
int32_t handleevents(void); int32_t handleevents(void);
enum GameFunction_t enum GameFunction_t
@ -102,7 +96,7 @@ enum GameFunction_t
}; };
void SetupGameButtons(); void SetupGameButtons();
void ApplyGlobalInput(InputPacket& input, ControlInfo* const hidInput, bool const crouchable = true, bool const disableToggle = false); void ApplyGlobalInput(HIDInput* const hidInput, InputPacket* const inputBuffer);
extern ESyncBits ActionsToSend; extern ESyncBits ActionsToSend;
extern bool gamesetinput; extern bool gamesetinput;
@ -116,6 +110,12 @@ inline float backendinputscale()
return (1.f / 16.f); return (1.f / 16.f);
} }
inline void getHidInput(HIDInput* const hidInput)
{
inputState.GetMouseDelta(hidInput);
if (use_joystick) I_GetAxes(hidInput->joyaxes);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// Inline functions to help with edge cases where synchronised input is needed. // Inline functions to help with edge cases where synchronised input is needed.

View file

@ -91,6 +91,7 @@
#include "i_interface.h" #include "i_interface.h"
#include "texinfo.h" #include "texinfo.h"
#include "texturemanager.h" #include "texturemanager.h"
#include "gameinput.h"
#include "menustate.h" #include "menustate.h"
void RazeXR_setUseScreenLayer(bool use); void RazeXR_setUseScreenLayer(bool use);
@ -139,8 +140,7 @@ void G_BuildTiccmd(ticcmd_t* cmd)
} }
cmd->ucmd = {}; cmd->ucmd = {};
I_GetEvent(); I_GetEvent();
auto input = CONTROL_GetInput(); getInput(inputScale, gi->getConsoleAngles(), &cmd->ucmd);
gi->GetInput(&input, inputScale, &cmd->ucmd);
cmd->consistency = consistency[myconnectindex][(maketic / ticdup) % BACKUPTICS]; cmd->consistency = consistency[myconnectindex][(maketic / ticdup) % BACKUPTICS];
} }
@ -593,7 +593,7 @@ void TryRunTics (void)
oldentertics = entertic; oldentertics = entertic;
// update the scale factor for unsynchronised input here. // update the scale factor for unsynchronised input here.
inputScale = !SyncInput() ? I_GetInputFrac() : 1.; inputScale = I_GetInputFrac();
// get available tics // get available tics
NetUpdate (); NetUpdate ();
@ -643,8 +643,7 @@ void TryRunTics (void)
if (!SyncInput()) if (!SyncInput())
{ {
I_GetEvent(); I_GetEvent();
auto input = CONTROL_GetInput(); getInput(inputScale, gi->getConsoleAngles());
gi->GetInput(&input, inputScale);
} }
return; return;
} }

View file

@ -487,8 +487,8 @@ bool HWSprite::ProcessVoxel(HWDrawInfo* di, voxmodel_t* vox, tspritetype* spr, s
{ {
sprxscale *= 1.25f; sprxscale *= 1.25f;
auto rvec = ownerActor->sprext.rot.Yaw.ToVector(); auto rvec = ownerActor->sprext.rot.Yaw.ToVector();
translatevec.Y -= spr->xoffset * rvec.X; translatevec.Y -= spr->xoffset * rvec.X / 64;
translatevec.X += spr->xoffset * rvec.Y; translatevec.X += spr->xoffset * rvec.Y / 64;
} }
if (spr->cstat & CSTAT_SPRITE_YFLIP) if (spr->cstat & CSTAT_SPRITE_YFLIP)

View file

@ -30,7 +30,6 @@
#include "src/blood.cpp" #include "src/blood.cpp"
#include "src/callback.cpp" #include "src/callback.cpp"
#include "src/choke.cpp" #include "src/choke.cpp"
#include "src/controls.cpp"
#include "src/db.cpp" #include "src/db.cpp"
#include "src/dude.cpp" #include "src/dude.cpp"
#include "src/endgame.cpp" #include "src/endgame.cpp"

View file

@ -2574,7 +2574,7 @@ static void ConcussSprite(DBloodActor* source, DBloodActor* actor, const DVector
if (mass > 0) if (mass > 0)
{ {
auto tex = TexMan.GetGameTexture(actor->spr.spritetexture()); auto tex = TexMan.GetGameTexture(actor->spr.spritetexture());
double size = (tex->GetDisplayWidth() * actor->spr.scale.X * tex->GetDisplayHeight() * actor->spr.scale.Y) / 0x20000; double size = tex->GetDisplayWidth() * actor->spr.scale.X * tex->GetDisplayHeight() * actor->spr.scale.Y * (1. / 0x100000);
actor->vel += vect * Scale(damage, size, mass); actor->vel += vect * Scale(damage, size, mass);
} }
} }

View file

@ -60,8 +60,8 @@ AISTATE zombie13AC2C = { kAiStateOther, 11, nStandClient, 0, entryEZombie, NULL,
void HackSeqCallback(int, DBloodActor* actor) void HackSeqCallback(int, DBloodActor* actor)
{ {
if (!actor->ValidateTarget(__FUNCTION__)) return;
auto target = actor->GetTarget(); auto target = actor->GetTarget();
if (!target) return;
DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type); DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type);
DUDEINFO* pDudeInfoT = getDudeInfo(target->spr.type); DUDEINFO* pDudeInfoT = getDudeInfo(target->spr.type);
DVector3 dv; DVector3 dv;

View file

@ -423,7 +423,7 @@ void GameInterface::Ticker()
inp.actions |= oldactions & ~(SB_BUTTON_MASK | SB_RUN | SB_WEAPONMASK_BITS); // should be everything non-button and non-weapon inp.actions |= oldactions & ~(SB_BUTTON_MASK | SB_RUN | SB_WEAPONMASK_BITS); // should be everything non-button and non-weapon
int newweap = inp.getNewWeapon(); int newweap = inp.getNewWeapon();
if (newweap > 0 && newweap < WeaponSel_MaxBlood) gPlayer[i].newWeapon = newweap; if (newweap > 0 && newweap <= WeaponSel_MaxBlood) gPlayer[i].newWeapon = newweap;
} }
BloodSpriteIterator it; BloodSpriteIterator it;
@ -439,14 +439,12 @@ void GameInterface::Ticker()
PLAYER* pPlayer = &gPlayer[myconnectindex]; PLAYER* pPlayer = &gPlayer[myconnectindex];
// this must be done before the view is backed up.
pPlayer->Angles.resetRenderAngles();
// disable synchronised input if set by game. // disable synchronised input if set by game.
resetForcedSyncInput(); resetForcedSyncInput();
for (int i = connecthead; i >= 0; i = connectpoint2[i]) for (int i = connecthead; i >= 0; i = connectpoint2[i])
{ {
gPlayer[i].Angles.resetCameraAngles();
viewBackupView(i); viewBackupView(i);
playerProcess(&gPlayer[i]); playerProcess(&gPlayer[i]);
} }

View file

@ -111,7 +111,6 @@ struct GameInterface : public ::GameInterface
void app_init() override; void app_init() override;
void SerializeGameState(FSerializer& arc) override; void SerializeGameState(FSerializer& arc) override;
void loadPalette() override; void loadPalette() override;
void clearlocalinputstate() override;
bool GenerateSavePic() override; bool GenerateSavePic() override;
void FreeLevelData() override; void FreeLevelData() override;
void FreeGameData() override; void FreeGameData() override;
@ -119,9 +118,7 @@ struct GameInterface : public ::GameInterface
void MenuOpened() override; void MenuOpened() override;
void MenuClosed() override; void MenuClosed() override;
bool CanSave() override; bool CanSave() override;
std::pair<DVector3, DAngle> GetCoordinates() override;
void UpdateSounds() override; void UpdateSounds() override;
void GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet = nullptr) override;
void Ticker() override; void Ticker() override;
void DrawBackground() override; void DrawBackground() override;
void Startup() override; void Startup() override;
@ -133,7 +130,8 @@ struct GameInterface : public ::GameInterface
bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) override; bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) override;
DAngle playerPitchMin() override { return DAngle::fromDeg(54.575); } DAngle playerPitchMin() override { return DAngle::fromDeg(54.575); }
DAngle playerPitchMax() override { return DAngle::fromDeg(-43.15); } DAngle playerPitchMax() override { return DAngle::fromDeg(-43.15); }
void WarpToCoords(double x, double y, double z, DAngle a) override; DCoreActor* getConsoleActor() override { return gPlayer[myconnectindex].actor; }
PlayerAngles* getConsoleAngles() override { return &gPlayer[myconnectindex].Angles; }
void ToggleThirdPerson() override; void ToggleThirdPerson() override;
void SwitchCoopView() override; void SwitchCoopView() override;
void ToggleShowWeapon() override; void ToggleShowWeapon() override;

View file

@ -1,83 +0,0 @@
#pragma once
//-------------------------------------------------------------------------
/*
Copyright (C) 2020 Christoph Oelckers & Mitchell Richters
This file is part of Raze.
Raze is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License version 2
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
//-------------------------------------------------------------------------
#include "ns.h" // Must come before everything else!
#include "blood.h"
#include "gamestate.h"
#include "inputstate.h"
#include "gamestruct.h"
#include "razemenu.h"
BEGIN_BLD_NS
static InputPacket gInput;
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void GameInterface::GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet)
{
if (paused || M_Active())
{
gInput = {};
return;
}
PLAYER* pPlayer = &gPlayer[myconnectindex];
InputPacket input{};
ApplyGlobalInput(gInput, hidInput);
processMovement(&input, &gInput, hidInput, scaleAdjust);
// Perform unsynchronised angle/horizon if not dead.
if (!SyncInput() && gamestate == GS_LEVEL && pPlayer->actor->xspr.health != 0)
{
pPlayer->Angles.RenderAngles.Yaw += DAngle::fromDeg(input.avel);
//For VR just set the pitch directly
pPlayer->Angles.RenderAngles.Pitch = DAngle::fromDeg(input.horz);
}
if (packet)
{
*packet = gInput;
gInput = {};
}
}
//---------------------------------------------------------------------------
//
// This is called from InputState::ClearAllInput and resets all static state being used here.
//
//---------------------------------------------------------------------------
void GameInterface::clearlocalinputstate()
{
gInput = {};
}
END_BLD_NS

View file

@ -112,6 +112,9 @@ void hudDraw(PLAYER* pPlayer, sectortype* pSector, double bobx, double boby, dou
{ {
if (gViewPos == 0) if (gViewPos == 0)
{ {
// Nullify incoming roll angle for now as it doesn't draw weapons made up of parts correctly.
angle = nullAngle;
auto cXY = DVector2(160, 220) + pPlayer->Angles.getWeaponOffsets(interpfrac).first; auto cXY = DVector2(160, 220) + pPlayer->Angles.getWeaponOffsets(interpfrac).first;
if (cl_weaponsway) if (cl_weaponsway)

View file

@ -31,20 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_BLD_NS BEGIN_BLD_NS
void GameInterface::WarpToCoords(double x, double y, double z, DAngle ang)
{
PLAYER* pPlayer = &gPlayer[myconnectindex];
pPlayer->actor->spr.pos = { x, y, z };
playerResetInertia(pPlayer);
if (ang != DAngle::fromDeg(INT_MIN))
{
pPlayer->actor->spr.Angles.Yaw = ang;
pPlayer->actor->backupang();
}
}
void GameInterface::ToggleThirdPerson() void GameInterface::ToggleThirdPerson()
{ {
if (gamestate != GS_LEVEL) return; if (gamestate != GS_LEVEL) return;

View file

@ -1499,20 +1499,6 @@ int ActionScan(PLAYER* pPlayer, HitInfo* out)
return -1; return -1;
} }
//---------------------------------------------------------------------------
//
// Player's slope tilting wrapper function function, called in ProcessInput() or from gi->GetInput() as required.
//
//---------------------------------------------------------------------------
void doslopetilting(PLAYER* pPlayer)
{
auto plActor = pPlayer->actor;
int const florhit = pPlayer->actor->hit.florhit.type;
bool const va = plActor->xspr.height < 16 && (florhit == kHitSector || florhit == 0) ? 1 : 0;
pPlayer->Angles.doViewPitch(plActor->spr.pos.XY(), plActor->spr.Angles.Yaw, va, plActor->sector()->floorstat & CSTAT_SECTOR_SLOPE, plActor->sector());
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //
@ -1642,6 +1628,9 @@ void ProcessInput(PLAYER* pPlayer)
if (actor->xspr.health == 0) if (actor->xspr.health == 0)
{ {
// force synchronised input upon death.
setForcedSyncInput();
bool bSeqStat = playerSeqPlaying(pPlayer, 16); bool bSeqStat = playerSeqPlaying(pPlayer, 16);
DBloodActor* fragger = pPlayer->fragger; DBloodActor* fragger = pPlayer->fragger;
if (fragger) if (fragger)
@ -1687,14 +1676,14 @@ void ProcessInput(PLAYER* pPlayer)
actor->vel.XY() += DVector2(pInput->fvel * fvAccel, pInput->svel * svAccel).Rotated(actor->spr.Angles.Yaw) * speed; actor->vel.XY() += DVector2(pInput->fvel * fvAccel, pInput->svel * svAccel).Rotated(actor->spr.Angles.Yaw) * speed;
} }
pPlayer->Angles.doViewYaw(pInput->actions); pPlayer->Angles.doViewYaw(pInput);
if (SyncInput()) if (SyncInput())
{ {
pPlayer->actor->spr.Angles.Yaw += DAngle::fromDeg(pInput->avel); pPlayer->actor->spr.Angles.Yaw += DAngle::fromDeg(pInput->avel);
} }
pPlayer->Angles.doYawKeys(&pInput->actions); pPlayer->Angles.doYawKeys(pInput);
if (!(pInput->actions & SB_JUMP)) if (!(pInput->actions & SB_JUMP))
pPlayer->cantJump = 0; pPlayer->cantJump = 0;
@ -1822,8 +1811,9 @@ void ProcessInput(PLAYER* pPlayer)
pPlayer->actor->spr.Angles.Pitch = DAngle::fromDeg(pInput->horz); pPlayer->actor->spr.Angles.Pitch = DAngle::fromDeg(pInput->horz);
} }
pPlayer->Angles.doPitchKeys(&pInput->actions, pInput->horz); const int florhit = pPlayer->actor->hit.florhit.type;
doslopetilting(pPlayer); pPlayer->Angles.doViewPitch(actor->xspr.height < 16 && (florhit == kHitSector || florhit == 0));
pPlayer->Angles.doPitchKeys(pInput);
pPlayer->slope = pPlayer->actor->spr.Angles.Pitch.Tan(); pPlayer->slope = pPlayer->actor->spr.Angles.Pitch.Tan();
if (pInput->actions & SB_INVPREV) if (pInput->actions & SB_INVPREV)

View file

@ -309,9 +309,8 @@ void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick)
{ {
if (*duration > 0) if (*duration > 0)
{ {
auto thisTick = I_GetTime(pQAV->ticrate); const auto thisTick = I_GetTime(pQAV->ticrate);
auto numTicks = thisTick - (*lastTick); if (const auto numTicks = thisTick - (*lastTick))
if (numTicks)
{ {
*lastTick = thisTick; *lastTick = thisTick;
*duration -= pQAV->ticksPerFrame * numTicks; *duration -= pQAV->ticksPerFrame * numTicks;
@ -328,35 +327,34 @@ void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick)
void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, double* interpfrac, bool const fixedduration, bool const ignoreWeaponTimer) void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, double* interpfrac, bool const fixedduration, bool const ignoreWeaponTimer)
{ {
// Process if not paused. // Process clock based on QAV's ticrate and last tick value.
if (!paused) if (!paused)
{ {
// Process clock based on QAV's ticrate and last tick value.
qavProcessTicker(pQAV, &pPlayer->qavTimer, &pPlayer->qavLastTick); qavProcessTicker(pQAV, &pPlayer->qavTimer, &pPlayer->qavLastTick);
if (pPlayer->weaponTimer == 0 && pPlayer->qavTimer == 0 && !ignoreWeaponTimer)
{
// Check if we're playing an idle QAV as per the ticker's weapon timer.
*duration = fixedduration ? pQAV->duration - 1 : I_GetBuildTime() % pQAV->duration;
*interpfrac = 1.;
}
else if (pPlayer->qavTimer == 0)
{
// If qavTimer is 0, play the last frame uninterpolated. Sometimes the timer can be just ahead of weaponTimer.
*duration = pQAV->duration - 1;
*interpfrac = 1.;
}
else
{
// Apply normal values.
*duration = pQAV->duration - pPlayer->qavTimer;
*interpfrac = !cl_interpolate || cl_capfps ? 1. : I_GetTimeFrac(pQAV->ticrate);
}
} }
else else
{ {
pPlayer->qavLastTick = I_GetTime(pQAV->ticrate);
}
if (pPlayer->weaponTimer == 0 && pPlayer->qavTimer == 0 && !ignoreWeaponTimer)
{
// Check if we're playing an idle QAV as per the ticker's weapon timer.
*duration = fixedduration ? pQAV->duration - 1 : I_GetBuildTime() % pQAV->duration;
*interpfrac = 1.; *interpfrac = 1.;
} }
else if (pPlayer->qavTimer == 0)
{
// If qavTimer is 0, play the last frame uninterpolated. Sometimes the timer can be just ahead of weaponTimer.
*duration = pQAV->duration - 1;
*interpfrac = 1.;
}
else
{
// Apply normal values.
*duration = pQAV->duration - pPlayer->qavTimer;
*interpfrac = !cl_interpolate || cl_capfps || paused ? 1. : I_GetTimeFrac(pQAV->ticrate);
}
} }

View file

@ -582,7 +582,7 @@ void viewDrawScreen(bool sceneonly)
else interpfrac = 1.; else interpfrac = 1.;
// update render angles. // update render angles.
pPlayer->Angles.updateRenderAngles(interpfrac); pPlayer->Angles.updateCameraAngles(interpfrac);
if (cl_interpolate) if (cl_interpolate)
{ {
@ -774,13 +774,6 @@ bool GameInterface::GenerateSavePic()
return true; return true;
} }
std::pair<DVector3, DAngle> GameInterface::GetCoordinates()
{
PLAYER* pPlayer = &gPlayer[myconnectindex];
if (!pPlayer->actor) return std::make_pair(DVector3(DBL_MAX, 0, 0), nullAngle);
return std::make_pair(pPlayer->actor->spr.pos, pPlayer->actor->spr.Angles.Yaw);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
@ -800,7 +793,7 @@ bool GameInterface::DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos,
auto vect = OutAutomapVector(mxy - cpos, cangvect, czoom, xydim); auto vect = OutAutomapVector(mxy - cpos, cangvect, czoom, xydim);
DrawTexture(twod, tileGetTexture(actor->spr.picnum, true), vect.X, vect.Y, DTA_ClipLeft, viewport3d.Left(), DTA_ClipTop, viewport3d.Top(), DTA_ScaleX, czoom * (2. / 3.), DTA_ScaleY, czoom * (2. / 3.), DTA_CenterOffset, true, DrawTexture(twod, tileGetTexture(actor->spr.picnum, true), vect.X, vect.Y, DTA_ClipLeft, viewport3d.Left(), DTA_ClipTop, viewport3d.Top(), DTA_ScaleX, czoom * (2. / 3.), DTA_ScaleY, czoom * (2. / 3.), DTA_CenterOffset, true,
DTA_ClipRight, viewport3d.Right(), DTA_ClipBottom, viewport3d.Bottom(), DTA_Alpha, (actor->spr.cstat & CSTAT_SPRITE_TRANSLUCENT ? 0.5 : 1.), TAG_DONE); DTA_ClipRight, viewport3d.Right(), DTA_ClipBottom, viewport3d.Bottom(), DTA_Alpha, (actor->spr.cstat & CSTAT_SPRITE_TRANSLUCENT ? 0.5 : 1.), DTA_TranslationIndex, TRANSLATION(Translation_Remap, actor->spr.pal), TAG_DONE);
} }
} }
return true; return true;

View file

@ -862,6 +862,7 @@ void WeaponLower(PLAYER* pPlayer)
} }
else else
{ {
pPlayer->weaponState = 1;
StartQAV(pPlayer, kQAVBUNDOWN2); StartQAV(pPlayer, kQAVBUNDOWN2);
} }
break; break;
@ -2400,7 +2401,7 @@ void WeaponProcess(PLAYER* pPlayer) {
{ {
pPlayer->fuseTime = pPlayer->weaponTimer; pPlayer->fuseTime = pPlayer->weaponTimer;
DropBundle(1, pPlayer); DropBundle(1, pPlayer);
pPlayer->weaponState = 1; pPlayer->weaponState = 3;
} }
} }
WeaponLower(pPlayer); WeaponLower(pPlayer);

View file

@ -118,22 +118,6 @@ static int ccmd_spawn(CCmdFuncPtr parm)
return CCMD_OK; return CCMD_OK;
} }
void GameInterface::WarpToCoords(double x, double y, double z, DAngle ang)
{
player_struct* p = &ps[myconnectindex];
auto pActor = p->GetActor();
if (!pActor) return;
pActor->spr.pos = DVector3(x, y, z);
pActor->backuppos();
if (ang != DAngle::fromDeg(INT_MIN))
{
p->GetActor()->PrevAngles.Yaw = p->GetActor()->spr.Angles.Yaw = ang;
}
}
void GameInterface::ToggleThirdPerson() void GameInterface::ToggleThirdPerson()
{ {
if (gamestate != GS_LEVEL) return; if (gamestate != GS_LEVEL) return;

View file

@ -66,7 +66,6 @@ static const char *cheatGod(int myconnectindex, int state)
auto* p = &ps[myconnectindex]; auto* p = &ps[myconnectindex];
auto act = p->GetActor(); auto act = p->GetActor();
p->resurrected = true;
act->spr.extra = gs.max_player_health; act->spr.extra = gs.max_player_health;
act->hitextra = 0; act->hitextra = 0;
if (ud.god) if (ud.god)

View file

@ -19,13 +19,14 @@
BEGIN_DUKE_NS BEGIN_DUKE_NS
extern player_struct ps[MAXPLAYERS];
struct GameInterface : public ::GameInterface struct GameInterface : public ::GameInterface
{ {
const char* Name() override { return "Duke"; } const char* Name() override { return "Duke"; }
void app_init() override; void app_init() override;
void loadPalette() override; void loadPalette() override;
void SetupSpecialTextures(TilesetBuildInfo& info) override; void SetupSpecialTextures(TilesetBuildInfo& info) override;
void clearlocalinputstate() override;
bool GenerateSavePic() override; bool GenerateSavePic() override;
void PlayHudSound() override; void PlayHudSound() override;
GameStats getStats() override; GameStats getStats() override;
@ -36,10 +37,9 @@ struct GameInterface : public ::GameInterface
FSavegameInfo GetSaveSig() override; FSavegameInfo GetSaveSig() override;
double SmallFontScale() override { return isRR() ? 0.5 : 1.; } double SmallFontScale() override { return isRR() ? 0.5 : 1.; }
void SerializeGameState(FSerializer& arc) override; void SerializeGameState(FSerializer& arc) override;
std::pair<DVector3, DAngle> GetCoordinates() override;
void ExitFromMenu() override; void ExitFromMenu() override;
void DrawPlayerSprite(const DVector2& origin, bool onteam) override; void DrawPlayerSprite(const DVector2& origin, bool onteam) override;
void GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet = nullptr) override; void GetInput(HIDInput* const hidInput, InputPacket* const inputBuffer, InputPacket* const currInput, const double scaleAdjust) override;
void UpdateSounds() override; void UpdateSounds() override;
void Startup() override; void Startup() override;
void DrawBackground() override; void DrawBackground() override;
@ -51,7 +51,8 @@ struct GameInterface : public ::GameInterface
void NewGame(MapRecord* map, int skill, bool) override; void NewGame(MapRecord* map, int skill, bool) override;
void LevelCompleted(MapRecord* map, int skill) override; void LevelCompleted(MapRecord* map, int skill) override;
bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) override; bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) override;
void WarpToCoords(double x, double y, double z, DAngle ang) override; DCoreActor* getConsoleActor() override { return ps[myconnectindex].GetActor(); }
PlayerAngles* getConsoleAngles() override { return &ps[myconnectindex].Angles; }
void ToggleThirdPerson() override; void ToggleThirdPerson() override;
void SwitchCoopView() override; void SwitchCoopView() override;
void ToggleShowWeapon() override; void ToggleShowWeapon() override;

View file

@ -402,7 +402,6 @@ void GameInterface::app_init()
//Net_SendClientInfo(); //Net_SendClientInfo();
setupbackdrop(); setupbackdrop();
SetupGameButtons();
InitCheats(); InitCheats();
checkcommandline(); checkcommandline();
registerosdcommands(); registerosdcommands();

View file

@ -55,13 +55,6 @@ BEGIN_DUKE_NS
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
std::pair<DVector3, DAngle> GameInterface::GetCoordinates()
{
auto pActor = ps[screenpeek].GetActor();
if (!pActor) return std::make_pair(DVector3(DBL_MAX, 0, 0), nullAngle);
return std::make_pair(pActor->spr.pos, pActor->spr.Angles.Yaw);
}
GameStats GameInterface::getStats() GameStats GameInterface::getStats()
{ {
player_struct* p = &ps[myconnectindex]; player_struct* p = &ps[myconnectindex];
@ -426,7 +419,7 @@ bool GameInterface::DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos,
double j = clamp(czoom * act->spr.scale.Y + abs(pp.truefz - act->getOffsetZ()) * REPEAT_SCALE, (1. / 3.), 2.); double j = clamp(czoom * act->spr.scale.Y + abs(pp.truefz - act->getOffsetZ()) * REPEAT_SCALE, (1. / 3.), 2.);
auto const vec = OutAutomapVector(mxy - cpos, cangvect, czoom, xydim); auto const vec = OutAutomapVector(mxy - cpos, cangvect, czoom, xydim);
auto const daang = -(pp.Angles.RenderAngles.Yaw - cang).Normalized360().Degrees(); auto const daang = -(pp.Angles.getCameraAngles().Yaw - cang).Normalized360().Degrees();
DrawTexture(twod, tileGetTexture(i), vec.X, vec.Y, DTA_TranslationIndex, TRANSLATION(Translation_Remap + setpal(&pp), act->spr.pal), DTA_CenterOffset, true, DrawTexture(twod, tileGetTexture(i), vec.X, vec.Y, DTA_TranslationIndex, TRANSLATION(Translation_Remap + setpal(&pp), act->spr.pal), DTA_CenterOffset, true,
DTA_Rotate, daang, DTA_Color, shadeToLight(act->spr.shade), DTA_ScaleX, j, DTA_ScaleY, j, TAG_DONE); DTA_Rotate, daang, DTA_Color, shadeToLight(act->spr.shade), DTA_ScaleX, j, DTA_ScaleY, j, TAG_DONE);

View file

@ -551,7 +551,7 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor,
break; break;
case PLAYER_NEWOWNER: case PLAYER_NEWOWNER:
if (bSet) ps[iPlayer].newOwner = vValue.safeActor(); if (bSet && (ps[iPlayer].newOwner = vValue.safeActor())) setForcedSyncInput();
else SetGameVarID(lVar2, ps[iPlayer].newOwner, sActor, sPlayer); else SetGameVarID(lVar2, ps[iPlayer].newOwner, sActor, sPlayer);
break; break;
@ -621,7 +621,7 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor,
break; break;
case PLAYER_ON_CRANE: case PLAYER_ON_CRANE:
if (bSet) ps[iPlayer].on_crane = vValue.safeActor(); if (bSet && (ps[iPlayer].on_crane = vValue.safeActor())) setForcedSyncInput();
else SetGameVarID(lVar2, (ps[iPlayer].on_crane), sActor, sPlayer); else SetGameVarID(lVar2, (ps[iPlayer].on_crane), sActor, sPlayer);
break; break;
@ -2268,7 +2268,6 @@ int ParseState::parse(void)
ps[g_p].wackedbyactor = nullptr; ps[g_p].wackedbyactor = nullptr;
ps[g_p].shield_amount = gs.max_armour_amount; ps[g_p].shield_amount = gs.max_armour_amount;
ps[g_p].dead_flag = 0; ps[g_p].dead_flag = 0;
ps[g_p].resurrected = false;
ps[g_p].pals.a = 0; ps[g_p].pals.a = 0;
ps[g_p].footprintcount = 0; ps[g_p].footprintcount = 0;
ps[g_p].weapreccnt = 0; ps[g_p].weapreccnt = 0;

View file

@ -70,7 +70,10 @@ void GameInterface::Ticker()
everyothertime++; everyothertime++;
// this must be done before the view is backed up. // this must be done before the view is backed up.
ps[myconnectindex].Angles.resetRenderAngles(); for (int i = connecthead; i >= 0; i = connectpoint2[i])
{
ps[i].Angles.resetCameraAngles();
}
// disable synchronised input if set by game. // disable synchronised input if set by game.
resetForcedSyncInput(); resetForcedSyncInput();
@ -87,17 +90,14 @@ void GameInterface::Ticker()
for (int i = connecthead; i >= 0; i = connectpoint2[i]) for (int i = connecthead; i >= 0; i = connectpoint2[i])
{ {
if (playrunning()) auto p = &ps[i];
{ if (p->pals.a > 0)
auto p = &ps[i]; p->pals.a--;
if (p->pals.a > 0)
p->pals.a--;
hud_input(i); hud_input(i);
processinputvel(i); processinputvel(i);
fi.processinput(i); fi.processinput(i);
fi.checksectors(i); fi.checksectors(i);
}
} }
fi.think(); fi.think();

View file

@ -234,8 +234,7 @@ inline bool playrunning()
inline void doslopetilting(player_struct* p) inline void doslopetilting(player_struct* p)
{ {
bool const canslopetilt = p->on_ground && p->insector() && p->cursector->lotag != ST_2_UNDERWATER && (p->cursector->floorstat & CSTAT_SECTOR_SLOPE); p->Angles.doViewPitch(p->aim_mode == 0 && p->on_ground && p->cursector->lotag != ST_2_UNDERWATER);
p->Angles.doViewPitch(p->GetActor()->spr.pos.XY(), p->GetActor()->spr.Angles.Yaw, p->aim_mode == 0, canslopetilt, p->cursector);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -354,4 +353,14 @@ inline void processinputvel(int snum)
p->sync.svel = (float)velvect.Y; p->sync.svel = (float)velvect.Y;
} }
inline void setPlayerActorViewZOffset(DDukeActor* const pact)
{
if (!PlayClock)
{
pact->spr.pos.Z += gs.playerheight;
pact->opos.Z += gs.playerheight;
pact->oviewzoffset = pact->viewzoffset = -gs.playerheight;
}
}
END_DUKE_NS END_DUKE_NS

View file

@ -44,9 +44,6 @@ EXTERN_CVAR(Float, m_yaw)
BEGIN_DUKE_NS BEGIN_DUKE_NS
// State timer counters.
static InputPacket loc; // input accumulation buffer.
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// handles all HUD related input, i.e. inventory item selection and activation plus weapon selection. // handles all HUD related input, i.e. inventory item selection and activation plus weapon selection.
@ -73,6 +70,31 @@ 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);
const bool disableToggle = p->jetpack_on || (!crouchable && p->on_ground) || (isRRRA() && (p->OnMotorcycle || p->OnBoat));
if (isRR() && (p->sync.actions & SB_CROUCH)) p->sync.actions &= ~SB_JUMP;
if (crouch_toggle && (!crouchable || disableToggle))
{
crouch_toggle = false;
p->sync.actions &= ~SB_CROUCH;
}
if (p->OnMotorcycle || p->OnBoat)
{
// mask out all actions not compatible with vehicles.
p->sync.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN |
SB_AIM_UP | SB_AIM_DOWN | SB_AIMMODE | SB_LOOK_UP | SB_LOOK_DOWN | SB_LOOK_LEFT | SB_LOOK_RIGHT);
}
else
{
if ((isRR() && p->drink_amt > 88)) p->sync.actions |= SB_LOOK_LEFT;
if ((isRR() && p->drink_amt > 99)) p->sync.actions |= SB_LOOK_DOWN;
}
if (isRR()) if (isRR())
{ {
if (PlayerInput(plnum, SB_QUICK_KICK) && p->last_pissed_time == 0) if (PlayerInput(plnum, SB_QUICK_KICK) && p->last_pissed_time == 0)
@ -85,7 +107,6 @@ void hud_input(int plnum)
{ {
p->GetActor()->spr.extra += 2; p->GetActor()->spr.extra += 2;
p->last_extra = p->GetActor()->spr.extra; p->last_extra = p->GetActor()->spr.extra;
p->resurrected = true;
} }
else if (p->GetActor()->spr.extra < gs.max_player_health) else if (p->GetActor()->spr.extra < gs.max_player_health)
p->GetActor()->spr.extra = gs.max_player_health; p->GetActor()->spr.extra = gs.max_player_health;
@ -110,18 +131,9 @@ void hud_input(int plnum)
if (!PlayerInputBits(plnum, SB_INTERFACE_BITS)) if (!PlayerInputBits(plnum, SB_INTERFACE_BITS))
p->interface_toggle_flag = 0; p->interface_toggle_flag = 0;
#ifndef __MOBILE__
else if (p->interface_toggle_flag == 0) else if (p->interface_toggle_flag == 0)
{ {
#else p->interface_toggle_flag = 1;
//Without the following, it seems weapon swtich doesn't work in RazeXR?!
else
{
if (p->interface_toggle_flag == 0)
{
p->interface_toggle_flag = 1;
}
#endif
// Don't go on if paused or dead. // Don't go on if paused or dead.
if (paused) return; if (paused) return;
@ -523,40 +535,9 @@ enum
enum enum
{ {
MAXVELMOTO = 120, MAXVELMOTO = 120,
VEHICLETURN = 20
}; };
//--------------------------------------------------------------------------- static constexpr float VEHICLETURN = (20.f * 360.f / 2048.f);
//
// handles the input bits
//
//---------------------------------------------------------------------------
static void processInputBits(player_struct *p, ControlInfo* const hidInput)
{
// Set-up crouch bools.
int const sectorLotag = p->insector() ? p->cursector->lotag : 0;
bool const crouchable = sectorLotag != ST_2_UNDERWATER && (sectorLotag != ST_1_ABOVE_WATER || p->spritebridge);
bool const disableToggle = p->jetpack_on || (!crouchable && p->on_ground) || (isRRRA() && (p->OnMotorcycle || p->OnBoat));
ApplyGlobalInput(loc, hidInput, crouchable, disableToggle);
if (isRR() && (loc.actions & SB_CROUCH)) loc.actions &= ~SB_JUMP;
if (p->OnMotorcycle || p->OnBoat)
{
// mask out all actions not compatible with vehicles.
loc.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN |
SB_AIM_UP | SB_AIM_DOWN | SB_AIMMODE | SB_LOOK_UP | SB_LOOK_DOWN | SB_LOOK_LEFT | SB_LOOK_RIGHT);
}
else
{
if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) // this shares a bit with another function so cannot be in the common code.
loc.actions |= SB_QUICK_KICK;
if ((isRR() && p->drink_amt > 88)) loc.actions |= SB_LOOK_LEFT;
if ((isRR() && p->drink_amt > 99)) loc.actions |= SB_LOOK_DOWN;
}
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
@ -564,88 +545,85 @@ static void processInputBits(player_struct *p, ControlInfo* const hidInput)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static FAngle motoApplyTurn(player_struct* p, ControlInfo* const hidInput, bool const kbdLeft, bool const kbdRight, double const factor) static float motoApplyTurn(player_struct* p, HIDInput* const hidInput, bool const kbdLeft, bool const kbdRight, const float factor)
{ {
double turnvel = 0; float turnvel = 0;
p->oTiltStatus = p->TiltStatus; p->oTiltStatus = p->TiltStatus;
if (p->MotoSpeed == 0 || !p->on_ground) if (p->MotoSpeed == 0 || !p->on_ground)
{ {
resetTurnHeldAmt(); resetTurnHeldAmt();
if (kbdLeft || hidInput->mouseturnx < 0 || hidInput->dyaw < 0) if (p->vehTurnLeft)
{ {
p->TiltStatus -= (float)factor; p->TiltStatus -= (float)factor;
if (p->TiltStatus < -10) if (p->TiltStatus < -10)
p->TiltStatus = -10; p->TiltStatus = -10;
} }
else if (kbdRight || hidInput->mouseturnx > 0 || hidInput->dyaw > 0) else if (p->vehTurnRight)
{ {
p->TiltStatus += (float)factor; p->TiltStatus += (float)factor;
if (p->TiltStatus > 10) if (p->TiltStatus > 10)
p->TiltStatus = 10; p->TiltStatus = 10;
} }
} }
else if (p->vehTurnLeft || p->vehTurnRight || p->moto_drink)
{
constexpr float velScale = (3.f / 10.f);
const float baseVel = (buttonMap.ButtonDown(gamefunc_Move_Backward) || hidInput->joyaxes[JOYAXIS_Forward] < 0) && p->MotoSpeed <= 0 ? -VEHICLETURN : VEHICLETURN;
if (p->vehTurnLeft || p->moto_drink < 0)
{
p->TiltStatus -= (float)factor;
if (p->TiltStatus < -10)
p->TiltStatus = -10;
if (kbdLeft)
turnvel -= isTurboTurnTime() && p->MotoSpeed > 0 ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx < 0)
turnvel -= Sgn(baseVel) * sqrtf(abs(p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * -(hidInput->mouseturnx / factor) * (7.f / 20.f));
if (hidInput->joyaxes[JOYAXIS_Yaw] > 0)
turnvel += (p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * hidInput->joyaxes[JOYAXIS_Yaw];
updateTurnHeldAmt(factor);
}
if (p->vehTurnRight || p->moto_drink > 0)
{
p->TiltStatus += (float)factor;
if (p->TiltStatus > 10)
p->TiltStatus = 10;
if (kbdRight)
turnvel += isTurboTurnTime() && p->MotoSpeed > 0 ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx > 0)
turnvel += Sgn(baseVel) * sqrtf(abs(p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * (hidInput->mouseturnx / factor) * (7.f / 20.f));
if (hidInput->joyaxes[JOYAXIS_Yaw] < 0)
turnvel += (p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * hidInput->joyaxes[JOYAXIS_Yaw];
updateTurnHeldAmt(factor);
}
}
else else
{ {
if (kbdLeft || kbdRight || p->moto_drink || hidInput->mouseturnx || hidInput->dyaw) resetTurnHeldAmt();
{
double const velScale = 3. / 10;
auto const baseVel = (buttonMap.ButtonDown(gamefunc_Move_Backward) || hidInput->dz < 0) && p->MotoSpeed <= 0 ? -VEHICLETURN : VEHICLETURN;
if (kbdLeft || p->moto_drink < 0 || hidInput->mouseturnx < 0 || hidInput->dyaw < 0) if (p->TiltStatus > 0)
{ p->TiltStatus -= (float)factor;
p->TiltStatus -= (float)factor; else if (p->TiltStatus < 0)
p->TiltStatus += (float)factor;
if (p->TiltStatus < -10)
p->TiltStatus = -10;
if (kbdLeft)
turnvel -= isTurboTurnTime() && p->MotoSpeed > 0 ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx < 0)
turnvel -= Sgn(baseVel) * sqrt((p->MotoSpeed > 0 ? abs(baseVel) : abs(baseVel) * velScale) * -(hidInput->mouseturnx / factor) * 2.);
if (hidInput->dyaw < 0)
turnvel += (p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * hidInput->dyaw;
updateTurnHeldAmt(factor);
}
if (kbdRight || p->moto_drink > 0 || hidInput->mouseturnx > 0 || hidInput->dyaw > 0)
{
p->TiltStatus += (float)factor;
if (p->TiltStatus > 10)
p->TiltStatus = 10;
if (kbdRight)
turnvel += isTurboTurnTime() && p->MotoSpeed > 0 ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx > 0)
turnvel += Sgn(baseVel) * sqrt((p->MotoSpeed > 0 ? abs(baseVel) : abs(baseVel) * velScale) * (hidInput->mouseturnx / factor) * 2.);
if (hidInput->dyaw > 0)
turnvel += (p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * hidInput->dyaw;
updateTurnHeldAmt(factor);
}
}
else
{
resetTurnHeldAmt();
if (p->TiltStatus > 0)
p->TiltStatus -= (float)factor;
else if (p->TiltStatus < 0)
p->TiltStatus += (float)factor;
}
} }
if (fabs(p->TiltStatus) < factor) if (fabs(p->TiltStatus) < factor)
p->TiltStatus = 0; p->TiltStatus = 0;
return FAngle::fromBuild(turnvel * factor); return turnvel * factor;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -654,68 +632,56 @@ static FAngle motoApplyTurn(player_struct* p, ControlInfo* const hidInput, bool
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static FAngle boatApplyTurn(player_struct *p, ControlInfo* const hidInput, bool const kbdLeft, bool const kbdRight, double const factor) static float boatApplyTurn(player_struct *p, HIDInput* const hidInput, bool const kbdLeft, bool const kbdRight, const float factor)
{ {
double turnvel = 0; float turnvel = 0;
p->oTiltStatus = p->TiltStatus; p->oTiltStatus = p->TiltStatus;
if (p->MotoSpeed) if (p->MotoSpeed && (p->vehTurnLeft || p->vehTurnRight || p->moto_drink))
{ {
if (kbdLeft || kbdRight || p->moto_drink || hidInput->mouseturnx || hidInput->dyaw) const float velScale = !p->NotOnWater? 1.f : (6.f / 19.f);
const float baseVel = VEHICLETURN * velScale;
if (p->vehTurnLeft || p->moto_drink < 0)
{ {
double const velScale = !p->NotOnWater? 1. : 6. / 19.; if (!p->NotOnWater)
auto const baseVel = +VEHICLETURN * velScale;
if (kbdLeft || p->moto_drink < 0 || hidInput->mouseturnx < 0 || hidInput->dyaw < 0)
{ {
if (!p->NotOnWater)
{
p->TiltStatus -= (float)factor;
if (p->TiltStatus < -10)
p->TiltStatus = -10;
}
if (kbdLeft)
turnvel -= isTurboTurnTime() ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx < 0)
turnvel -= Sgn(baseVel) * sqrt(abs(baseVel) * -(hidInput->mouseturnx / factor) * 2.);
if (hidInput->dyaw < 0)
turnvel += baseVel * hidInput->dyaw;
updateTurnHeldAmt(factor);
}
if (kbdRight || p->moto_drink > 0 || hidInput->mouseturnx > 0 || hidInput->dyaw > 0)
{
if (!p->NotOnWater)
{
p->TiltStatus += (float)factor;
if (p->TiltStatus > 10)
p->TiltStatus = 10;
}
if (kbdRight)
turnvel += isTurboTurnTime() ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx > 0)
turnvel += Sgn(baseVel) * sqrt(abs(baseVel) * (hidInput->mouseturnx / factor) * 2.);
if (hidInput->dyaw > 0)
turnvel += baseVel * hidInput->dyaw;
updateTurnHeldAmt(factor);
}
}
else if (!p->NotOnWater)
{
resetTurnHeldAmt();
if (p->TiltStatus > 0)
p->TiltStatus -= (float)factor; p->TiltStatus -= (float)factor;
else if (p->TiltStatus < 0) if (p->TiltStatus < -10)
p->TiltStatus = -10;
}
if (kbdLeft)
turnvel -= isTurboTurnTime() ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx < 0)
turnvel -= Sgn(baseVel) * sqrtf(abs(baseVel) * -(hidInput->mouseturnx / factor) * (7.f / 20.f));
if (hidInput->joyaxes[JOYAXIS_Yaw] > 0)
turnvel += baseVel * hidInput->joyaxes[JOYAXIS_Yaw];
updateTurnHeldAmt(factor);
}
if (p->vehTurnRight || p->moto_drink > 0)
{
if (!p->NotOnWater)
{
p->TiltStatus += (float)factor; p->TiltStatus += (float)factor;
if (p->TiltStatus > 10)
p->TiltStatus = 10;
}
if (kbdRight)
turnvel += isTurboTurnTime() ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx > 0)
turnvel += Sgn(baseVel) * sqrtf(abs(baseVel) * (hidInput->mouseturnx / factor) * (7.f / 20.f));
if (hidInput->joyaxes[JOYAXIS_Yaw] < 0)
turnvel += baseVel * hidInput->joyaxes[JOYAXIS_Yaw];
updateTurnHeldAmt(factor);
} }
} }
else if (!p->NotOnWater) else if (!p->NotOnWater)
@ -731,7 +697,7 @@ static FAngle boatApplyTurn(player_struct *p, ControlInfo* const hidInput, bool
if (fabs(p->TiltStatus) < factor) if (fabs(p->TiltStatus) < factor)
p->TiltStatus = 0; p->TiltStatus = 0;
return FAngle::fromBuild(turnvel * factor); return turnvel * factor;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -740,7 +706,7 @@ static FAngle boatApplyTurn(player_struct *p, ControlInfo* const hidInput, bool
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void processVehicleInput(player_struct *p, ControlInfo* const hidInput, InputPacket& input, double const scaleAdjust) static void processVehicleInput(player_struct *p, HIDInput* const hidInput, InputPacket* const inputBuffer, InputPacket* const currInput, const double scaleAdjust)
{ {
bool const kbdLeft = buttonMap.ButtonDown(gamefunc_Turn_Left) || buttonMap.ButtonDown(gamefunc_Strafe_Left); bool const kbdLeft = buttonMap.ButtonDown(gamefunc_Turn_Left) || buttonMap.ButtonDown(gamefunc_Strafe_Left);
bool const kbdRight = buttonMap.ButtonDown(gamefunc_Turn_Right) || buttonMap.ButtonDown(gamefunc_Strafe_Right); bool const kbdRight = buttonMap.ButtonDown(gamefunc_Turn_Right) || buttonMap.ButtonDown(gamefunc_Strafe_Right);
@ -748,63 +714,28 @@ static void processVehicleInput(player_struct *p, ControlInfo* const hidInput, I
// Cancel out micro-movement // Cancel out micro-movement
if (fabs(hidInput->mouseturnx) < (m_sensitivity_x * m_yaw * backendinputscale() * 2.f)) hidInput->mouseturnx = 0; if (fabs(hidInput->mouseturnx) < (m_sensitivity_x * m_yaw * backendinputscale() * 2.f)) hidInput->mouseturnx = 0;
p->vehTurnLeft = kbdLeft || hidInput->mouseturnx < 0 || hidInput->dyaw < 0; p->vehTurnLeft = kbdLeft || hidInput->mouseturnx < 0 || hidInput->joyaxes[JOYAXIS_Yaw] > 0;
p->vehTurnRight = kbdRight || hidInput->mouseturnx > 0 || hidInput->dyaw > 0; p->vehTurnRight = kbdRight || hidInput->mouseturnx > 0 || hidInput->joyaxes[JOYAXIS_Yaw] < 0;
if (p->OnBoat || !p->moto_underwater) if (p->OnBoat || !p->moto_underwater)
{ {
p->vehForwardScale = min((buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) + hidInput->dz, 1.f); p->vehForwardScale = min((buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) + hidInput->joyaxes[JOYAXIS_Forward], 1.f);
p->vehReverseScale = min(buttonMap.ButtonDown(gamefunc_Move_Backward) + -hidInput->dz, 1.f); p->vehReverseScale = min(buttonMap.ButtonDown(gamefunc_Move_Backward) + -hidInput->joyaxes[JOYAXIS_Forward], 1.f);
p->vehBraking = buttonMap.ButtonDown(gamefunc_Run); p->vehBraking = buttonMap.ButtonDown(gamefunc_Run);
} }
if (p->OnMotorcycle) if (p->OnMotorcycle)
{ {
input.avel = motoApplyTurn(p, hidInput, kbdLeft, kbdRight, scaleAdjust).Degrees(); currInput->avel = motoApplyTurn(p, hidInput, kbdLeft, kbdRight, (float)scaleAdjust);
if (p->moto_underwater) p->MotoSpeed = 0; if (p->moto_underwater) p->MotoSpeed = 0;
} }
else else
{ {
input.avel = boatApplyTurn(p, hidInput, kbdLeft, kbdRight, scaleAdjust).Degrees(); currInput->avel = boatApplyTurn(p, hidInput, kbdLeft, kbdRight, (float)scaleAdjust);
} }
loc.fvel = clamp<float>((float)p->MotoSpeed, -(MAXVELMOTO >> 3), MAXVELMOTO) * (1.f / 40.f); inputBuffer->fvel = clamp<float>((float)p->MotoSpeed, -(MAXVELMOTO >> 3), MAXVELMOTO) * (1.f / 40.f);
loc.avel += input.avel; inputBuffer->avel += currInput->avel;
}
//---------------------------------------------------------------------------
//
// finalizes the input and passes it to the global input buffer
//
//---------------------------------------------------------------------------
static void FinalizeInput(player_struct *p, InputPacket& input)
{
if (gamestate != GS_LEVEL || movementBlocked(p) || p->GetActor()->spr.extra <= 0 || (p->dead_flag && !ud.god && !p->resurrected))
{
// neutralize all movement when not in a game, blocked or in automap follow mode
loc.fvel = loc.svel = 0;
loc.avel = loc.horz = 0;
input.avel = input.horz = 0;
}
else
{
if (p->on_crane != nullptr)
{
loc.fvel = input.fvel = 0;
loc.svel = input.svel = 0;
}
if (p->newOwner != nullptr || p->on_crane != nullptr)
{
loc.avel = input.avel = 0;
}
if (p->newOwner != nullptr || (p->sync.actions & SB_CENTERVIEW && abs(p->GetActor()->spr.Angles.Pitch.Degrees()) > 2.2370))
{
loc.horz = input.horz = 0;
}
}
} }
@ -814,53 +745,18 @@ static void FinalizeInput(player_struct *p, InputPacket& input)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void GameInterface::GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet) void GameInterface::GetInput(HIDInput* const hidInput, InputPacket* const inputBuffer, InputPacket* const currInput, const double scaleAdjust)
{ {
if (paused || gamestate != GS_LEVEL)
{
loc = {};
return;
}
auto const p = &ps[myconnectindex]; auto const p = &ps[myconnectindex];
InputPacket input{};
processInputBits(p, hidInput);
if (isRRRA() && (p->OnMotorcycle || p->OnBoat)) if (isRRRA() && (p->OnMotorcycle || p->OnBoat))
{ {
processVehicleInput(p, hidInput, input, scaleAdjust); processVehicleInput(p, hidInput, inputBuffer, currInput, scaleAdjust);
} }
else else
{ {
processMovement(&input, &loc, hidInput, scaleAdjust, p->drink_amt); processMovement(hidInput, inputBuffer, currInput, scaleAdjust, p->drink_amt);
} }
FinalizeInput(p, input);
if (!SyncInput() && p->GetActor()->spr.extra > 0)
{
p->Angles.RenderAngles.Yaw += p->adjustavel(input.avel);
//For VR just set the pitch directly
p->Angles.RenderAngles.Pitch = DAngle::fromDeg(input.horz);
}
if (packet)
{
*packet = loc;
loc = {};
}
}
//---------------------------------------------------------------------------
//
// This is called from InputState::ClearAllInput and resets all static state being used here.
//
//---------------------------------------------------------------------------
void GameInterface::clearlocalinputstate()
{
loc = {};
} }

View file

@ -545,6 +545,9 @@ void playerisdead(int snum, int psectlotag, double floorz, double ceilingz)
auto p = &ps[snum]; auto p = &ps[snum];
auto actor = p->GetActor(); auto actor = p->GetActor();
// lock input when dead.
setForcedSyncInput();
if (p->dead_flag == 0) if (p->dead_flag == 0)
{ {
if (actor->spr.pal != 1) if (actor->spr.pal != 1)
@ -726,7 +729,7 @@ void playerJump(int snum, double floorz, double ceilingz)
void player_struct::apply_seasick() void player_struct::apply_seasick()
{ {
if (isRRRA() && SeaSick && (dead_flag == 0 || (dead_flag && resurrected))) if (isRRRA() && SeaSick && (dead_flag == 0))
{ {
if (SeaSick < 250) if (SeaSick < 250)
{ {
@ -958,6 +961,8 @@ bool movementBlocked(player_struct *p)
p->hard_landing || p->hard_landing ||
p->access_incs > 0 || p->access_incs > 0 ||
p->knee_incs > 0 || p->knee_incs > 0 ||
p->GetActor()->spr.extra <= 0 ||
(p->dead_flag && !ud.god) ||
(blockingweapon() && p->kickback_pic > 1 && p->kickback_pic < weapondelay())); (blockingweapon() && p->kickback_pic > 1 && p->kickback_pic < weapondelay()));
} }

View file

@ -1784,7 +1784,7 @@ static void movement(int snum, ESyncBits actions, sectortype* psect, double floo
p->on_warping_sector = 0; p->on_warping_sector = 0;
if ((actions & SB_CROUCH) || crouch_toggle) // FIXME: The crouch_toggle check here is not network safe and needs revision when multiplayer is going. if (actions & SB_CROUCH)
{ {
playerCrouch(snum); playerCrouch(snum);
} }
@ -2732,6 +2732,8 @@ void processinput_d(int snum)
shrunk = (pact->spr.scale.Y < 0.5); shrunk = (pact->spr.scale.Y < 0.5);
getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 10.1875, CLIPMASK0); getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 10.1875, CLIPMASK0);
setPlayerActorViewZOffset(pact);
p->truefz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); p->truefz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ());
p->truecz = getceilzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); p->truecz = getceilzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ());
@ -2823,6 +2825,7 @@ void processinput_d(int snum)
if (p->newOwner != nullptr) if (p->newOwner != nullptr)
{ {
setForcedSyncInput();
p->vel.X = p->vel.Y = 0; p->vel.X = p->vel.Y = 0;
pact->vel.X = 0; pact->vel.X = 0;
@ -2840,7 +2843,10 @@ void processinput_d(int snum)
auto oldpos = p->GetActor()->opos; auto oldpos = p->GetActor()->opos;
if (p->on_crane != nullptr) if (p->on_crane != nullptr)
{
setForcedSyncInput();
goto HORIZONLY; goto HORIZONLY;
}
p->playerweaponsway(pact->vel.X); p->playerweaponsway(pact->vel.X);
@ -2868,13 +2874,14 @@ void processinput_d(int snum)
p->psectlotag = psectlotag; p->psectlotag = psectlotag;
//Do the quick lefts and rights //Do the quick lefts and rights
p->Angles.doViewYaw(actions); p->Angles.doViewYaw(&p->sync);
if (movementBlocked(p)) if (movementBlocked(p))
{ {
doubvel = 0; doubvel = 0;
p->vel.X = 0; p->vel.X = 0;
p->vel.Y = 0; p->vel.Y = 0;
setForcedSyncInput();
} }
else if (SyncInput()) else if (SyncInput())
{ {
@ -2885,7 +2892,7 @@ void processinput_d(int snum)
p->GetActor()->spr.Angles.Yaw += p->adjustavel(PlayerInputAngVel(snum)); p->GetActor()->spr.Angles.Yaw += p->adjustavel(PlayerInputAngVel(snum));
} }
p->Angles.doYawKeys(&actions); p->Angles.doYawKeys(&p->sync);
purplelavacheck(p); purplelavacheck(p);
if (p->spritebridge == 0 && pact->insector()) if (p->spritebridge == 0 && pact->insector())
@ -3022,7 +3029,7 @@ HORIZONLY:
} }
// RBG*** // RBG***
SetActor(pact, p->GetActor()->spr.pos); SetActor(pact, pact->spr.pos);
if (psectlotag < 3) if (psectlotag < 3)
{ {
@ -3095,12 +3102,17 @@ HORIZONLY:
playerAimDown(snum, actions); playerAimDown(snum, actions);
} }
if (SyncInput()) if (p->centeringView())
{
p->sync.horz = 0;
setForcedSyncInput();
}
else if (SyncInput())
{ {
p->GetActor()->spr.Angles.Pitch += GetPlayerHorizon(snum); p->GetActor()->spr.Angles.Pitch += GetPlayerHorizon(snum);
} }
p->Angles.doPitchKeys(&actions, GetPlayerHorizon(snum).Sgn()); p->Angles.doPitchKeys(&p->sync);
p->checkhardlanding(); p->checkhardlanding();

View file

@ -2160,7 +2160,7 @@ static void movement(int snum, ESyncBits actions, sectortype* psect, double floo
p->on_warping_sector = 0; p->on_warping_sector = 0;
if (((actions & SB_CROUCH) || crouch_toggle) && !p->OnMotorcycle) // FIXME: The crouch_toggle check here is not network safe and needs revision when multiplayer is going. if ((actions & SB_CROUCH) && !p->OnMotorcycle)
{ {
playerCrouch(snum); playerCrouch(snum);
} }
@ -3353,22 +3353,21 @@ void processinput_r(int snum)
p->spritebridge = 0; p->spritebridge = 0;
shrunk = (pact->spr.scale.Y < 0.125); shrunk = (pact->spr.scale.Y < 0.125);
double tempfz;
if (pact->clipdist == 16) if (pact->clipdist == 16)
{ {
getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 10.1875, CLIPMASK0); getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 10.1875, CLIPMASK0);
tempfz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ());
} }
else else
{ {
getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 0.25, CLIPMASK0); getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 0.25, CLIPMASK0);
tempfz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ());
} }
p->truefz = tempfz; setPlayerActorViewZOffset(pact);
p->truefz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ());
p->truecz = getceilzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ()); p->truecz = getceilzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ());
double truefdist = abs(p->GetActor()->getOffsetZ() - tempfz); double truefdist = abs(p->GetActor()->getOffsetZ() - p->truefz);
if (clz.type == kHitSector && psectlotag == 1 && truefdist > gs.playerheight + 16) if (clz.type == kHitSector && psectlotag == 1 && truefdist > gs.playerheight + 16)
psectlotag = 0; psectlotag = 0;
@ -3501,6 +3500,7 @@ void processinput_r(int snum)
if (p->newOwner != nullptr) if (p->newOwner != nullptr)
{ {
setForcedSyncInput();
p->vel.X = p->vel.Y = 0; p->vel.X = p->vel.Y = 0;
pact->vel.X = 0; pact->vel.X = 0;
@ -3518,7 +3518,10 @@ void processinput_r(int snum)
auto oldpos = p->GetActor()->opos; auto oldpos = p->GetActor()->opos;
if (p->on_crane != nullptr) if (p->on_crane != nullptr)
{
setForcedSyncInput();
goto HORIZONLY; goto HORIZONLY;
}
p->playerweaponsway(pact->vel.X); p->playerweaponsway(pact->vel.X);
@ -3560,13 +3563,14 @@ void processinput_r(int snum)
p->psectlotag = psectlotag; p->psectlotag = psectlotag;
//Do the quick lefts and rights //Do the quick lefts and rights
p->Angles.doViewYaw(actions); p->Angles.doViewYaw(&p->sync);
if (movementBlocked(p)) if (movementBlocked(p))
{ {
doubvel = 0; doubvel = 0;
p->vel.X = 0; p->vel.X = 0;
p->vel.Y = 0; p->vel.Y = 0;
setForcedSyncInput();
} }
else if (SyncInput()) else if (SyncInput())
{ {
@ -3577,7 +3581,7 @@ void processinput_r(int snum)
p->GetActor()->spr.Angles.Yaw += p->adjustavel(PlayerInputAngVel(snum)); p->GetActor()->spr.Angles.Yaw += p->adjustavel(PlayerInputAngVel(snum));
} }
p->Angles.doYawKeys(&actions); p->Angles.doYawKeys(&p->sync);
purplelavacheck(p); purplelavacheck(p);
if (p->spritebridge == 0 && pact->insector()) if (p->spritebridge == 0 && pact->insector())
@ -3818,7 +3822,7 @@ HORIZONLY:
} }
// RBG*** // RBG***
SetActor(pact, p->GetActor()->spr.pos); SetActor(pact, pact->spr.pos);
if (psectlotag == 800 && (!isRRRA() || !p->lotag800kill)) if (psectlotag == 800 && (!isRRRA() || !p->lotag800kill))
{ {
@ -3915,12 +3919,17 @@ HORIZONLY:
p->GetActor()->spr.Angles.Pitch += maphoriz(d); p->GetActor()->spr.Angles.Pitch += maphoriz(d);
} }
if (SyncInput()) if (p->centeringView())
{
p->sync.horz = 0;
setForcedSyncInput();
}
else if (SyncInput())
{ {
p->GetActor()->spr.Angles.Pitch += GetPlayerHorizon(snum); p->GetActor()->spr.Angles.Pitch += GetPlayerHorizon(snum);
} }
p->Angles.doPitchKeys(&actions, GetPlayerHorizon(snum).Sgn()); p->Angles.doPitchKeys(&p->sync);
p->checkhardlanding(); p->checkhardlanding();

View file

@ -91,7 +91,6 @@ void resetplayerstats(int snum)
gFullMap = 0; gFullMap = 0;
p->dead_flag = 0; p->dead_flag = 0;
p->resurrected = false;
p->wackedbyactor = nullptr; p->wackedbyactor = nullptr;
p->falling_counter = 0; p->falling_counter = 0;
p->quick_kick = 0; p->quick_kick = 0;
@ -503,11 +502,10 @@ void resetpspritevars(int g, const DVector3& startpos, const DAngle startang)
int aimmode[MAXPLAYERS]; int aimmode[MAXPLAYERS];
STATUSBARTYPE tsbar[MAXPLAYERS]; STATUSBARTYPE tsbar[MAXPLAYERS];
auto newActor = CreateActor(ps[0].cursector, startpos.plusZ(gs.playerheight), auto newActor = CreateActor(ps[0].cursector, startpos,
TILE_APLAYER, 0, DVector2(0, 0), startang, 0., 0., nullptr, 10); TILE_APLAYER, 0, DVector2(0, 0), startang, 0., 0., nullptr, 10);
newActor->spr.Angles.Pitch = DAngle::fromDeg(-17.354); newActor->spr.Angles.Pitch = DAngle::fromDeg(-17.354);
newActor->viewzoffset = -gs.playerheight;
newActor->backuploc(); newActor->backuploc();
if (ud.recstat != 2) for (i = 0; i < MAXPLAYERS; i++) if (ud.recstat != 2) for (i = 0; i < MAXPLAYERS; i++)

View file

@ -221,7 +221,7 @@ void displayrooms(int snum, double interpfrac, bool sceneonly)
player_struct* p = &ps[snum]; player_struct* p = &ps[snum];
// update render angles. // update render angles.
p->Angles.updateRenderAngles(interpfrac); p->Angles.updateCameraAngles(interpfrac);
if (automapMode == am_full || !p->insector()) if (automapMode == am_full || !p->insector())
return; return;

View file

@ -151,7 +151,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
.Array("weaprecs", w.weaprecs, w.weapreccnt) .Array("weaprecs", w.weaprecs, w.weapreccnt)
("interface_toggle_flag", w.interface_toggle_flag) ("interface_toggle_flag", w.interface_toggle_flag)
("dead_flag", w.dead_flag) ("dead_flag", w.dead_flag)
("resurrected", w.resurrected)
("show_empty_weapon", w.show_empty_weapon) ("show_empty_weapon", w.show_empty_weapon)
("scuba_amount", w.scuba_amount) ("scuba_amount", w.scuba_amount)
("jetpack_amount", w.jetpack_amount) ("jetpack_amount", w.jetpack_amount)

View file

@ -276,8 +276,6 @@ struct player_struct
int max_secret_rooms, secret_rooms, max_actors_killed, actors_killed; int max_secret_rooms, secret_rooms, max_actors_killed, actors_killed;
bool resurrected;
// Redneck Rampage additions. Those which did not have names in the reconstructed source got one from either RedneckGDX or RedNukem. // Redneck Rampage additions. Those which did not have names in the reconstructed source got one from either RedneckGDX or RedNukem.
// Items were reordered by size. // Items were reordered by size.
int stairs; int stairs;
@ -347,6 +345,11 @@ struct player_struct
{ {
bobpos = GetActor()->spr.pos.XY(); bobpos = GetActor()->spr.pos.XY();
} }
bool centeringView()
{
return (sync.actions & SB_CENTERVIEW) && abs(GetActor()->spr.Angles.Pitch.Degrees()) > 2.2370;
}
}; };
struct Cycler struct Cycler

View file

@ -898,7 +898,6 @@ DEFINE_FIELD_X(DukePlayer, player_struct, max_secret_rooms)
DEFINE_FIELD_X(DukePlayer, player_struct, secret_rooms) DEFINE_FIELD_X(DukePlayer, player_struct, secret_rooms)
DEFINE_FIELD_X(DukePlayer, player_struct, max_actors_killed) DEFINE_FIELD_X(DukePlayer, player_struct, max_actors_killed)
DEFINE_FIELD_X(DukePlayer, player_struct, actors_killed) DEFINE_FIELD_X(DukePlayer, player_struct, actors_killed)
DEFINE_FIELD_X(DukePlayer, player_struct, resurrected)
DEFINE_FIELD_X(DukePlayer, player_struct, stairs) DEFINE_FIELD_X(DukePlayer, player_struct, stairs)
DEFINE_FIELD_X(DukePlayer, player_struct, detonate_count) DEFINE_FIELD_X(DukePlayer, player_struct, detonate_count)
//DEFINE_FIELD_X(DukePlayer, player_struct, noise.X) //DEFINE_FIELD_X(DukePlayer, player_struct, noise.X)

View file

@ -27,10 +27,16 @@ BEGIN_PS_NS
// anims // anims
enum
{
kAnimFlag1 = (1 << 2),
kAnimLoop = (1 << 4)
};
void InitAnims(); void InitAnims();
void DestroyAnim(DExhumedActor* nAnim); void DestroyAnim(DExhumedActor* nAnim);
DExhumedActor* BuildAnim(DExhumedActor* actor, int val, int val2, const DVector3& pos, sectortype* pSector, double nScale, int nFlag); DExhumedActor* BuildAnim(DExhumedActor* actor, int val, int val2, const DVector3& pos, sectortype* pSector, double nScale, int nFlag);
void UnlinkIgnitedAnim(DExhumedActor* pActor);
void FuncAnim(int, int, int, int); void FuncAnim(int, int, int, int);
void BuildExplosion(DExhumedActor* actor); void BuildExplosion(DExhumedActor* actor);
void BuildSplash(DExhumedActor* actor, sectortype* pSector); void BuildSplash(DExhumedActor* actor, sectortype* pSector);

View file

@ -54,6 +54,30 @@ void InitAnims()
nSavePointSeq = SeqOffsets[kSeqItems] + 12; nSavePointSeq = SeqOffsets[kSeqItems] + 12;
} }
/*
Use when deleting an ignited actor to check if any actors reference it.
Will remove the actor's anim loop flag and set the source (the ignited actor's) actor target to null.
FuncAnim() will then delete the actor on next call for this actor.
Without this, the actor will hold reference to an actor which will prevent the GC from deleting it properly.
Specifically needed for IgniteSprite() anims which can become orphaned from the source sprite (e.g a bullet)
when the bullet sprite is deleted.
*/
void UnlinkIgnitedAnim(DExhumedActor* pActor)
{
ExhumedStatIterator it(kStatIgnited);
while (auto itActor = it.Next())
{
// .pTarget holds the actor pointer of the source 'actor that's on fire' actor
if (pActor == itActor->pTarget)
{
itActor->nAction &= ~kAnimLoop; // clear the animation loop flag
itActor->pTarget = nullptr; // set the actor target to null
}
}
}
void DestroyAnim(DExhumedActor* pActor) void DestroyAnim(DExhumedActor* pActor)
{ {
if (pActor) if (pActor)

View file

@ -22,6 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "sequence.h" #include "sequence.h"
#include "mapinfo.h" #include "mapinfo.h"
#include <assert.h> #include <assert.h>
#include "player.h"
BEGIN_PS_NS BEGIN_PS_NS
@ -53,6 +54,7 @@ DExhumedActor* BuildBubble(const DVector3& pos, sectortype* pSector)
} }
auto pActor = insertActor(pSector, 402); auto pActor = insertActor(pSector, 402);
auto pPlayerActor = PlayerList[nLocalPlayer].pActor;
pActor->spr.pos = pos; pActor->spr.pos = pos;
pActor->spr.cstat = 0; pActor->spr.cstat = 0;
@ -63,7 +65,7 @@ DExhumedActor* BuildBubble(const DVector3& pos, sectortype* pSector)
pActor->spr.xoffset = 0; pActor->spr.xoffset = 0;
pActor->spr.yoffset = 0; pActor->spr.yoffset = 0;
pActor->spr.picnum = 1; pActor->spr.picnum = 1;
pActor->spr.Angles.Yaw = inita; pActor->spr.Angles.Yaw = pPlayerActor->spr.Angles.Yaw;
pActor->vel.X = 0; pActor->vel.X = 0;
pActor->vel.Y = 0; pActor->vel.Y = 0;
pActor->vel.Z = -1200 / 256.; pActor->vel.Z = -1200 / 256.;

View file

@ -56,10 +56,6 @@ enum {
kSectLava = 0x4000, kSectLava = 0x4000,
}; };
extern DVector3 initpos;
extern DAngle inita;
extern sectortype* initsectp;
extern int nCurChunkNum; extern int nCurChunkNum;
// all static counters combined in an array for easier maintenance. // all static counters combined in an array for easier maintenance.

View file

@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "ns.h" #include "ns.h"
#include "engine.h" #include "engine.h"
#include "exhumed.h" #include "exhumed.h"
#include "aistuff.h"
#include "sequence.h" #include "sequence.h"
#include "names.h" #include "names.h"
#include "player.h" #include "player.h"
@ -66,7 +67,6 @@ IMPLEMENT_POINTERS_END
size_t MarkMove(); size_t MarkMove();
size_t MarkBullets(); size_t MarkBullets();
size_t MarkInput();
size_t MarkItems(); size_t MarkItems();
size_t MarkLighting(); size_t MarkLighting();
size_t MarkObjects(); size_t MarkObjects();
@ -80,7 +80,6 @@ size_t MarkRunlist();
static void markgcroots() static void markgcroots()
{ {
MarkBullets(); MarkBullets();
MarkInput();
MarkItems(); MarkItems();
MarkLighting(); MarkLighting();
MarkObjects(); MarkObjects();
@ -103,8 +102,6 @@ void InitCheats();
int EndLevel = 0; int EndLevel = 0;
InputPacket localInput;
//////// ////////
void ResetEngine() void ResetEngine()
@ -151,8 +148,6 @@ int nEnergyTowers = 0;
int nCfgNetPlayers = 0; int nCfgNetPlayers = 0;
int lLocalCodes = 0;
bool bCoordinates = false; bool bCoordinates = false;
int nNetTime = -1; int nNetTime = -1;
@ -375,28 +370,44 @@ void GameInterface::Ticker()
} }
else if (EndLevel == 0) else if (EndLevel == 0)
{ {
// Shorten some constant array accesses.
const auto pPlayer = &PlayerList[nLocalPlayer];
auto& pInput = pPlayer->input;
// this must be done before the view is backed up. // this must be done before the view is backed up.
PlayerList[nLocalPlayer].Angles.resetRenderAngles(); pPlayer->Angles.resetCameraAngles();
UpdatePlayerSpriteAngle(&PlayerList[nLocalPlayer]);
// disable synchronised input if set by game. // disable synchronised input if set by game.
resetForcedSyncInput(); resetForcedSyncInput();
auto& lPlayerVel = sPlayerInput[nLocalPlayer].vel; // set new player input, factoring in previous view centering.
const auto oldactions = pInput.actions;
pInput = playercmds[nLocalPlayer].ucmd;
if (oldactions & SB_CENTERVIEW) pInput.actions |= SB_CENTERVIEW;
auto inputvect = DVector2(localInput.fvel, localInput.svel).Rotated(inita) * 0.375; const auto inputvect = DVector2(pInput.fvel, pInput.svel).Rotated(pPlayer->pActor->spr.Angles.Yaw) * 0.375;
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
// Velocities are stored as Q14.18 // Velocities are stored as Q14.18
lPlayerVel += inputvect; pPlayer->vel += inputvect;
lPlayerVel *= 0.953125; pPlayer->vel *= 0.953125;
} }
UpdateInterpolations(); UpdateInterpolations();
if (localInput.actions & SB_INVPREV) if (nFreeze) setForcedSyncInput();
if (pPlayer->nHealth <= 0)
{ {
int nItem = PlayerList[nLocalPlayer].nItem; setForcedSyncInput();
auto& packet = pInput;
packet.fvel = packet.svel = packet.avel = packet.horz = 0;
pPlayer->vel.Zero();
}
if (pInput.actions & SB_INVPREV)
{
int nItem = pPlayer->nItem;
int i; int i;
for (i = 6; i > 0; i--) for (i = 6; i > 0; i--)
@ -404,16 +415,16 @@ void GameInterface::Ticker()
nItem--; nItem--;
if (nItem < 0) nItem = 5; if (nItem < 0) nItem = 5;
if (PlayerList[nLocalPlayer].items[nItem] != 0) if (pPlayer->items[nItem] != 0)
break; break;
} }
if (i > 0) PlayerList[nLocalPlayer].nItem = nItem; if (i > 0) pPlayer->nItem = nItem;
} }
if (localInput.actions & SB_INVNEXT) if (pInput.actions & SB_INVNEXT)
{ {
int nItem = PlayerList[nLocalPlayer].nItem; int nItem = pPlayer->nItem;
int i; int i;
for (i = 6; i > 0; i--) for (i = 6; i > 0; i--)
@ -421,57 +432,57 @@ void GameInterface::Ticker()
nItem++; nItem++;
if (nItem == 6) nItem = 0; if (nItem == 6) nItem = 0;
if (PlayerList[nLocalPlayer].items[nItem] != 0) if (pPlayer->items[nItem] != 0)
break; break;
} }
if (i > 0) PlayerList[nLocalPlayer].nItem = nItem; if (i > 0) pPlayer->nItem = nItem;
} }
if (localInput.actions & SB_INVUSE) if (pInput.actions & SB_INVUSE)
{ {
if (PlayerList[nLocalPlayer].nItem != -1) if (pPlayer->nItem != -1)
{ {
localInput.setItemUsed(PlayerList[nLocalPlayer].nItem); pInput.setItemUsed(pPlayer->nItem);
} }
} }
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
{ {
if (localInput.isItemUsed(i)) if (pInput.isItemUsed(i))
{ {
localInput.clearItemUsed(i); pInput.clearItemUsed(i);
if (PlayerList[nLocalPlayer].items[i] > 0) if (pPlayer->items[i] > 0)
{ {
if (nItemMagic[i] <= PlayerList[nLocalPlayer].nMagic) if (nItemMagic[i] <= pPlayer->nMagic)
{ {
sPlayerInput[nLocalPlayer].nItem = i; pPlayer->nCurrentItem = i;
break; break;
} }
} }
} }
} }
auto currWeap = PlayerList[nLocalPlayer].nCurrentWeapon; auto currWeap = pPlayer->nCurrentWeapon;
int weap2 = localInput.getNewWeapon(); int weap2 = pInput.getNewWeapon();
if (weap2 == WeaponSel_Next) if (weap2 == WeaponSel_Next)
{ {
auto newWeap = currWeap == 6 ? 0 : currWeap + 1; auto newWeap = currWeap == 6 ? 0 : currWeap + 1;
while (newWeap != 0 && (!(PlayerList[nLocalPlayer].nPlayerWeapons & (1 << newWeap)) || (PlayerList[nLocalPlayer].nPlayerWeapons & (1 << newWeap) && PlayerList[nLocalPlayer].nAmmo[newWeap] == 0))) while (newWeap != 0 && (!(pPlayer->nPlayerWeapons & (1 << newWeap)) || (pPlayer->nPlayerWeapons & (1 << newWeap) && pPlayer->nAmmo[newWeap] == 0)))
{ {
newWeap++; newWeap++;
if (newWeap > 6) newWeap = 0; if (newWeap > 6) newWeap = 0;
} }
localInput.setNewWeapon(newWeap + 1); pInput.setNewWeapon(newWeap + 1);
} }
else if (weap2 == WeaponSel_Prev) else if (weap2 == WeaponSel_Prev)
{ {
auto newWeap = currWeap == 0 ? 6 : currWeap - 1; auto newWeap = currWeap == 0 ? 6 : currWeap - 1;
while (newWeap != 0 && ((!(PlayerList[nLocalPlayer].nPlayerWeapons & (1 << newWeap)) || (PlayerList[nLocalPlayer].nPlayerWeapons & (1 << newWeap) && PlayerList[nLocalPlayer].nAmmo[newWeap] == 0)))) while (newWeap != 0 && ((!(pPlayer->nPlayerWeapons & (1 << newWeap)) || (pPlayer->nPlayerWeapons & (1 << newWeap) && pPlayer->nAmmo[newWeap] == 0))))
{ {
newWeap--; newWeap--;
} }
localInput.setNewWeapon(newWeap + 1); pInput.setNewWeapon(newWeap + 1);
} }
else if (weap2 == WeaponSel_Alt) else if (weap2 == WeaponSel_Alt)
{ {
@ -479,21 +490,10 @@ void GameInterface::Ticker()
} }
// make weapon selection persist until it gets used up. // make weapon selection persist until it gets used up.
int weap = sPlayerInput[nLocalPlayer].getNewWeapon(); int weap = pInput.getNewWeapon();
if (weap2 <= 0 || weap2 > 7) sPlayerInput[nLocalPlayer].SetNewWeapon(weap); if (weap2 <= 0 || weap2 > 7) pInput.setNewWeapon(weap);
auto oldactions = sPlayerInput[nLocalPlayer].actions; pPlayer->pTarget = Ra[nLocalPlayer].pTarget = bestTarget;
sPlayerInput[nLocalPlayer].actions = localInput.actions;
if (oldactions & SB_CENTERVIEW) sPlayerInput[nLocalPlayer].actions |= SB_CENTERVIEW;
sPlayerInput[nLocalPlayer].buttons = lLocalCodes;
sPlayerInput[nLocalPlayer].pTarget = bestTarget;
sPlayerInput[nLocalPlayer].nAngle = localInput.avel;
sPlayerInput[nLocalPlayer].pan = localInput.horz;
Ra[nLocalPlayer].pTarget = bestTarget;
lLocalCodes = 0;
PlayClock += 4; PlayClock += 4;
if (PlayClock == 8) gameaction = ga_autosave; // let the game run for 1 frame before saving. if (PlayClock == 8) gameaction = ga_autosave; // let the game run for 1 frame before saving.
@ -617,6 +617,7 @@ void DeleteActor(DExhumedActor* actor)
bestTarget = nullptr; bestTarget = nullptr;
} }
UnlinkIgnitedAnim(actor);
actor->Destroy(); actor->Destroy();
} }
@ -691,13 +692,6 @@ bool GameInterface::CanSave()
return new GameInterface; return new GameInterface;
} }
std::pair<DVector3, DAngle> GameInterface::GetCoordinates()
{
auto pPlayerActor = PlayerList[nLocalPlayer].pActor;
if (!pPlayerActor) return std::make_pair(DVector3(DBL_MAX, 0, 0), nullAngle);
return std::make_pair(pPlayerActor->spr.pos, pPlayerActor->spr.Angles.Yaw);
}
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //

View file

@ -34,6 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "exhumedactor.h" #include "exhumedactor.h"
#include "serialize_obj.h" #include "serialize_obj.h"
#include "texturemanager.h" #include "texturemanager.h"
#include "player.h"
BEGIN_PS_NS BEGIN_PS_NS
@ -211,7 +212,6 @@ struct GameInterface : public ::GameInterface
const char* Name() override { return "Exhumed"; } const char* Name() override { return "Exhumed"; }
void app_init() override; void app_init() override;
void SetupSpecialTextures(TilesetBuildInfo& info) override; void SetupSpecialTextures(TilesetBuildInfo& info) override;
void clearlocalinputstate() override;
void loadPalette() override; void loadPalette() override;
bool GenerateSavePic() override; bool GenerateSavePic() override;
void MenuOpened() override; void MenuOpened() override;
@ -225,7 +225,6 @@ struct GameInterface : public ::GameInterface
void DrawBackground() override; void DrawBackground() override;
void Render() override; void Render() override;
//void DrawWeapons() override; //void DrawWeapons() override;
void GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet = nullptr) override;
void Startup() override; void Startup() override;
const char* GenericCheat(int player, int cheat) override; const char* GenericCheat(int player, int cheat) override;
void NewGame(MapRecord *map, int skill, bool) override; void NewGame(MapRecord *map, int skill, bool) override;
@ -234,11 +233,11 @@ struct GameInterface : public ::GameInterface
bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) override; bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) override;
DAngle playerPitchMin() override { return DAngle::fromDeg(49.5); } DAngle playerPitchMin() override { return DAngle::fromDeg(49.5); }
DAngle playerPitchMax() override { return DAngle::fromDeg(-49.5); } DAngle playerPitchMax() override { return DAngle::fromDeg(-49.5); }
void WarpToCoords(double x, double y, double z, DAngle ang) override; DCoreActor* getConsoleActor() override { return PlayerList[nLocalPlayer].pActor; }
PlayerAngles* getConsoleAngles() override { return &PlayerList[nLocalPlayer].Angles; }
void ToggleThirdPerson() override; void ToggleThirdPerson() override;
void processSprites(tspriteArray& tsprites, const DVector3& view, DAngle viewang, double interpfrac) override; void processSprites(tspriteArray& tsprites, const DVector3& view, DAngle viewang, double interpfrac) override;
int GetCurrentSkill() override; int GetCurrentSkill() override;
std::pair<DVector3, DAngle> GetCoordinates() override;
void StartSoundEngine() override; void StartSoundEngine() override;
::GameStats getStats() override; ::GameStats getStats() override;

View file

@ -838,9 +838,9 @@ loc_flag:
nHeight += h; nHeight += h;
DExhumedActor* target = nullptr; DExhumedActor* target = nullptr;
if (sPlayerInput[nPlayer].pTarget != nullptr && Autoaim(nPlayer)) if (PlayerList[nPlayer].pTarget != nullptr && Autoaim(nPlayer))
{ {
DExhumedActor* t = sPlayerInput[nPlayer].pTarget; DExhumedActor* t = PlayerList[nPlayer].pTarget;
// only autoaim if target is in front of the player. // only autoaim if target is in front of the player.
assert(t->sector()); assert(t->sector());
DAngle angletotarget = (t->spr.pos - pPlayerActor->spr.pos).Angle(); DAngle angletotarget = (t->spr.pos - pPlayerActor->spr.pos).Angle();
@ -942,7 +942,7 @@ void DrawWeapons(double interpfrac)
int var_28 = var_30 + WeaponInfo[nWeapon].b[var_34]; int var_28 = var_30 + WeaponInfo[nWeapon].b[var_34];
int8_t nShade = initsectp->ceilingshade; int8_t nShade = PlayerList[nLocalPlayer].pActor->sector()->ceilingshade;
int nDouble = PlayerList[nLocalPlayer].nDouble; int nDouble = PlayerList[nLocalPlayer].nDouble;
int nPal = kPalNormal; int nPal = kPalNormal;

View file

@ -39,10 +39,6 @@ enum
kTagRamses = 61, kTagRamses = 61,
}; };
DVector3 initpos;
DAngle inita;
sectortype* initsectp;
int nCurChunkNum = 0; int nCurChunkNum = 0;
int Counters[kNumCounters]; int Counters[kNumCounters];
@ -145,10 +141,9 @@ uint8_t LoadLevel(MapRecord* map)
sectortype* initsect; sectortype* initsect;
SpawnSpriteDef spawned; SpawnSpriteDef spawned;
DVector3 initpos;
int16_t mapang; int16_t mapang;
loadMap(currentLevel->fileName, 0, &initpos, &mapang, &initsect, spawned); loadMap(currentLevel->fileName, 0, &initpos, &mapang, &initsect, spawned);
inita = DAngle::fromBuild(mapang);
initsectp = initsect;
auto actors = spawnactors(spawned); auto actors = spawnactors(spawned);
int i; int i;
@ -164,6 +159,13 @@ uint8_t LoadLevel(MapRecord* map)
precache(); precache();
LoadObjects(actors); LoadObjects(actors);
for (int i = 0; i < nTotalPlayers; i++)
{
SetSavePoint(i, initpos, initsect, DAngle::fromBuild(mapang));
RestartPlayer(i);
InitPlayerKeys(i);
}
return true; return true;
} }
@ -180,13 +182,6 @@ void InitLevel(MapRecord* map)
if (!LoadLevel(map)) { if (!LoadLevel(map)) {
I_Error("Cannot load %s...\n", map->fileName.GetChars()); I_Error("Cannot load %s...\n", map->fileName.GetChars());
} }
for (int i = 0; i < nTotalPlayers; i++)
{
SetSavePoint(i, initpos, initsectp, inita);
RestartPlayer(i);
InitPlayerKeys(i);
}
EndLevel = 0; EndLevel = 0;
ResetView(); ResetView();
ResetEngine(); ResetEngine();
@ -769,9 +764,9 @@ void ExamineSprites(TArray<DExhumedActor*>& actors)
if (nNetPlayerCount) if (nNetPlayerCount)
{ {
auto pActor = insertActor(initsectp, 0); auto pActor = insertActor(PlayerList[nLocalPlayer].pActor->sector(), 0);
pActor->spr.pos = initpos; pActor->spr.pos = PlayerList[nLocalPlayer].pActor->spr.pos;
pActor->spr.cstat = CSTAT_SPRITE_INVISIBLE; pActor->spr.cstat = CSTAT_SPRITE_INVISIBLE;
nNetStartSprite[nNetStartSprites] = pActor; nNetStartSprite[nNetStartSprites] = pActor;
nNetStartSprites++; nNetStartSprites++;
@ -839,8 +834,6 @@ void LoadObjects(TArray<DExhumedActor*>& actors)
runlist_ChangeChannel(nChannel, 0); runlist_ChangeChannel(nChannel, 0);
runlist_ReadyChannel(nChannel); runlist_ReadyChannel(nChannel);
} }
nCamerapos = initpos;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -853,10 +846,7 @@ void SerializeInit(FSerializer& arc)
{ {
if (arc.BeginObject("init")) if (arc.BeginObject("init"))
{ {
arc("init", initpos) arc("curchunk", nCurChunkNum)
("inita", inita)
("initsect", initsectp)
("curchunk", nCurChunkNum)
.Array("counters", Counters, kNumCounters) .Array("counters", Counters, kNumCounters)
.EndObject(); .EndObject();
} }

View file

@ -25,92 +25,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS BEGIN_PS_NS
PlayerInput sPlayerInput[kMaxPlayers];
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
size_t MarkInput()
{
for (auto& p : sPlayerInput)
{
GC::Mark(p.pTarget);
}
return kMaxPlayers;
}
void ClearSpaceBar(int nPlayer) void ClearSpaceBar(int nPlayer)
{ {
sPlayerInput[nPlayer].actions &= SB_OPEN; PlayerList[nPlayer].input.actions &= SB_OPEN;
buttonMap.ClearButton(gamefunc_Open); buttonMap.ClearButton(gamefunc_Open);
} }
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void GameInterface::GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet)
{
if (paused || M_Active())
{
localInput = {};
return;
}
if (packet != nullptr)
{
localInput = {};
ApplyGlobalInput(localInput, hidInput);
if (PlayerList[nLocalPlayer].nHealth == 0) localInput.actions &= SB_OPEN;
}
Player* pPlayer = &PlayerList[nLocalPlayer];
InputPacket input {};
if (PlayerList[nLocalPlayer].nHealth != 0)
{
processMovement(&input, &localInput, hidInput, scaleAdjust);
}
else
{
sPlayerInput[nLocalPlayer].vel.Zero();
}
if (!SyncInput() && gamestate == GS_LEVEL && !nFreeze)
{
pPlayer->Angles.RenderAngles.Yaw += DAngle::fromDeg(input.avel);
//For VR just set the pitch directly
pPlayer->Angles.RenderAngles.Pitch = DAngle::fromDeg(input.horz);
if (input.horz)
{
pPlayer->bPlayerPan = pPlayer->bLockPan = true;
}
UpdatePlayerSpriteAngle(pPlayer);
}
if (packet)
{
*packet = localInput;
}
}
//---------------------------------------------------------------------------
//
// This is called from InputState::ClearAllInput and resets all static state being used here.
//
//---------------------------------------------------------------------------
void GameInterface::clearlocalinputstate()
{
localInput = {};
}
END_PS_NS END_PS_NS

View file

@ -29,36 +29,7 @@ enum {
kButtonCheatItems = 0x100, kButtonCheatItems = 0x100,
}; };
// 32 bytes
struct PlayerInput
{
TObjPtr<DExhumedActor*> pTarget;
DVector2 vel;
uint16_t buttons;
float nAngle;
float pan;
int8_t nItem;
ESyncBits actions;
int getNewWeapon() const
{
return (actions & SB_WEAPONMASK_BITS).GetValue();
}
void SetNewWeapon(int weap)
{
actions = (actions & ~SB_WEAPONMASK_BITS) | (ESyncBits::FromInt(weap) & SB_WEAPONMASK_BITS);
}
};
void ClearSpaceBar(int nPlayer); void ClearSpaceBar(int nPlayer);
int GetLocalInput();
extern PlayerInput sPlayerInput[];
extern InputPacket localInput;
extern int lLocalCodes;
END_PS_NS END_PS_NS

View file

@ -45,6 +45,7 @@ void GrabMap()
void UpdateMap() void UpdateMap()
{ {
const auto initsectp = PlayerList[nLocalPlayer].pActor->sector();
if (initsectp->ceilingpal != 3 || (PlayerList[nLocalPlayer].nTorch != 0)) { if (initsectp->ceilingpal != 3 || (PlayerList[nLocalPlayer].nTorch != 0)) {
MarkSectorSeen(initsectp); MarkSectorSeen(initsectp);
} }

View file

@ -936,17 +936,6 @@ void MoveSector(sectortype* pSector, DAngle nAngle, DVector2& nVel)
} }
nVel = vect; nVel = vect;
/*
Update player position variables, in case the player sprite was moved by a sector,
Otherwise these can be out of sync when used in sound code (before being updated in PlayerFunc()).
Can cause local player sounds to play off-centre.
TODO: Might need to be done elsewhere too?
*/
auto pActor = PlayerList[nLocalPlayer].pActor;
initpos = pActor->spr.pos;
inita = pActor->spr.Angles.Yaw;
initsectp = pActor->sector();
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View file

@ -39,25 +39,6 @@ BEGIN_PS_NS
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void GameInterface::WarpToCoords(double x, double y, double z, DAngle ang)
{
Player *nPlayer = &PlayerList[nLocalPlayer];
nPlayer->pActor->spr.pos = DVector3(x, y, z);
nPlayer->pActor->backuppos();
if (ang != DAngle::fromDeg(INT_MIN))
{
nPlayer->pActor->PrevAngles.Yaw = nPlayer->pActor->spr.Angles.Yaw = ang;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static int osdcmd_doors(CCmdFuncPtr parm) static int osdcmd_doors(CCmdFuncPtr parm)
{ {
for (int i = 0; i < kMaxChannels; i++) for (int i = 0; i < kMaxChannels; i++)
@ -81,13 +62,17 @@ static int osdcmd_doors(CCmdFuncPtr parm)
static int osdcmd_spawn(CCmdFuncPtr parm) static int osdcmd_spawn(CCmdFuncPtr parm)
{ {
auto pActor = PlayerList[nLocalPlayer].pActor;
if (parm->numparms != 1) return CCMD_SHOWHELP; if (parm->numparms != 1) return CCMD_SHOWHELP;
if (!pActor) return CCMD_SHOWHELP;
auto c = parm->parms[0]; auto c = parm->parms[0];
auto sectp = initsectp; auto& initpos = pActor->spr.pos;
auto sectp = pActor->sector();
auto inita = pActor->spr.Angles.Yaw;
if (!stricmp(c, "anubis")) BuildAnubis(nullptr, initpos, sectp, inita, false); if (!stricmp(c, "anubis")) BuildAnubis(nullptr, initpos, sectp, inita, false);
else if (!stricmp(c, "spider")) BuildSpider(nullptr, initpos, sectp, inita); else if (!stricmp(c, "spider")) BuildSpider(nullptr, initpos, sectp, inita);
else if (!stricmp(c, "mummy")) BuildMummy(nullptr, initpos, sectp, inita); else if (!stricmp(c, "mummy")) BuildMummy(nullptr, initpos, sectp, inita);
else if (!stricmp(c, "fish")) BuildFish(nullptr, initpos.plusZ(PlayerList[nLocalPlayer].pActor->viewzoffset), sectp, inita); else if (!stricmp(c, "fish")) BuildFish(nullptr, initpos.plusZ(pActor->viewzoffset), sectp, inita);
else if (!stricmp(c, "lion")) BuildLion(nullptr, initpos, sectp, inita); else if (!stricmp(c, "lion")) BuildLion(nullptr, initpos, sectp, inita);
else if (!stricmp(c, "lava")) BuildLava(nullptr, initpos, sectp, inita, nNetPlayerCount); else if (!stricmp(c, "lava")) BuildLava(nullptr, initpos, sectp, inita, nNetPlayerCount);
else if (!stricmp(c, "rex")) BuildRex(nullptr, initpos, sectp, inita, nNetPlayerCount); else if (!stricmp(c, "rex")) BuildRex(nullptr, initpos, sectp, inita, nNetPlayerCount);

View file

@ -106,9 +106,10 @@ size_t MarkPlayers()
GC::Mark(p.pDoppleSprite); GC::Mark(p.pDoppleSprite);
GC::Mark(p.pPlayerFloorSprite); GC::Mark(p.pPlayerFloorSprite);
GC::Mark(p.pPlayerGrenade); GC::Mark(p.pPlayerGrenade);
GC::Mark(p.pTarget);
} }
GC::MarkArray(nNetStartSprite, kMaxPlayers); GC::MarkArray(nNetStartSprite, kMaxPlayers);
return 5 * kMaxPlayers; return 6 * kMaxPlayers;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -437,8 +438,7 @@ void RestartPlayer(int nPlayer)
plr->ototalvel = plr->totalvel = 0; plr->ototalvel = plr->totalvel = 0;
memset(&sPlayerInput[nPlayer], 0, sizeof(PlayerInput)); PlayerList[nPlayer].nCurrentItem = -1;
sPlayerInput[nPlayer].nItem = -1;
plr->nDeathType = 0; plr->nDeathType = 0;
nQuake[nPlayer] = 0; nQuake[nPlayer] = 0;
@ -670,17 +670,6 @@ static void pickupMessage(int no)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void UpdatePlayerSpriteAngle(Player* pPlayer)
{
if (pPlayer->pActor) inita = pPlayer->pActor->spr.Angles.Yaw.Normalized360();
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void AIPlayer::Draw(RunListEvent* ev) void AIPlayer::Draw(RunListEvent* ev)
{ {
int nPlayer = RunData[ev->nRun].nObjIndex; int nPlayer = RunData[ev->nRun].nObjIndex;
@ -860,7 +849,7 @@ bool CheckMovingBlocks(int nPlayer, Collision& nMove, DVector3& spr_pos, sectort
{ {
PlayerList[nPlayer].pPlayerPushSect = sect; PlayerList[nPlayer].pPlayerPushSect = sect;
DVector2 vel = sPlayerInput[nPlayer].vel; DVector2 vel = PlayerList[nPlayer].vel;
auto nMyAngle = vel.Angle().Normalized360(); auto nMyAngle = vel.Angle().Normalized360();
setsectinterpolate(sect); setsectinterpolate(sect);
@ -911,12 +900,12 @@ void AIPlayer::Tick(RunListEvent* ev)
int nAction = PlayerList[nPlayer].nAction; int nAction = PlayerList[nPlayer].nAction;
int nActionB = PlayerList[nPlayer].nAction; int nActionB = PlayerList[nPlayer].nAction;
pPlayerActor->vel.XY() = sPlayerInput[nPlayer].vel; pPlayerActor->vel.XY() = PlayerList[nPlayer].vel;
if (sPlayerInput[nPlayer].nItem > -1) if (PlayerList[nPlayer].nCurrentItem > -1)
{ {
UseItem(nPlayer, sPlayerInput[nPlayer].nItem); UseItem(nPlayer, PlayerList[nPlayer].nCurrentItem);
sPlayerInput[nPlayer].nItem = -1; PlayerList[nPlayer].nCurrentItem = -1;
} }
pPlayerActor->spr.picnum = seq_GetSeqPicnum(PlayerList[nPlayer].nSeq, PlayerSeq[nHeightTemplate[nAction]].a, PlayerList[nPlayer].nSeqSize); pPlayerActor->spr.picnum = seq_GetSeqPicnum(PlayerList[nPlayer].nSeq, PlayerSeq[nHeightTemplate[nAction]].a, PlayerList[nPlayer].nSeqSize);
@ -984,16 +973,15 @@ void AIPlayer::Tick(RunListEvent* ev)
} }
} }
PlayerList[nPlayer].Angles.doViewYaw(sPlayerInput[nLocalPlayer].actions); PlayerList[nPlayer].Angles.doViewYaw(&PlayerList[nLocalPlayer].input);
// loc_1A494: // loc_1A494:
if (SyncInput()) if (SyncInput())
{ {
PlayerList[nPlayer].pActor->spr.Angles.Yaw += DAngle::fromDeg(sPlayerInput[nPlayer].nAngle); PlayerList[nPlayer].pActor->spr.Angles.Yaw += DAngle::fromDeg(PlayerList[nPlayer].input.avel);
} }
PlayerList[nPlayer].Angles.doYawKeys(&sPlayerInput[nLocalPlayer].actions); PlayerList[nPlayer].Angles.doYawKeys(&PlayerList[nLocalPlayer].input);
UpdatePlayerSpriteAngle(&PlayerList[nPlayer]);
// player.zvel is modified within Gravity() // player.zvel is modified within Gravity()
double zVel = pPlayerActor->vel.Z; double zVel = pPlayerActor->vel.Z;
@ -1011,7 +999,7 @@ void AIPlayer::Tick(RunListEvent* ev)
auto playerPos = pPlayerActor->spr.pos.XY(); auto playerPos = pPlayerActor->spr.pos.XY();
DVector2 vect = sPlayerInput[nPlayer].vel; DVector2 vect = PlayerList[nPlayer].vel;
double zz = pPlayerActor->vel.Z; double zz = pPlayerActor->vel.Z;
if (pPlayerActor->vel.Z > 32) if (pPlayerActor->vel.Z > 32)
@ -1079,7 +1067,7 @@ void AIPlayer::Tick(RunListEvent* ev)
pPlayerActor->spr.Angles = DRotator(nullAngle, GetAngleToSprite(pPlayerActor, pSpiritSprite), nullAngle); pPlayerActor->spr.Angles = DRotator(nullAngle, GetAngleToSprite(pPlayerActor, pSpiritSprite), nullAngle);
pPlayerActor->backupang(); pPlayerActor->backupang();
sPlayerInput[nPlayer].vel.Zero(); PlayerList[nPlayer].vel.Zero();
pPlayerActor->vel.Zero(); pPlayerActor->vel.Zero();
if (nFreeze < 1) if (nFreeze < 1)
@ -1223,7 +1211,7 @@ sectdone:
int var_5C = pViewSect->Flag & kSectUnderwater; int var_5C = pViewSect->Flag & kSectUnderwater;
auto actions = sPlayerInput[nPlayer].actions; auto actions = PlayerList[nPlayer].input.actions;
// loc_1AEF5: // loc_1AEF5:
if (PlayerList[nPlayer].nHealth > 0) if (PlayerList[nPlayer].nHealth > 0)
@ -2433,7 +2421,7 @@ sectdone:
// loc_1BE70: // loc_1BE70:
// Handle player pressing number keys to change weapon // Handle player pressing number keys to change weapon
uint8_t var_90 = sPlayerInput[nPlayer].getNewWeapon(); uint8_t var_90 = PlayerList[nPlayer].input.getNewWeapon();
if (var_90) if (var_90)
{ {
@ -2477,12 +2465,12 @@ sectdone:
if (SyncInput()) if (SyncInput())
{ {
pPlayer->pActor->spr.Angles.Pitch += DAngle::fromDeg(sPlayerInput[nPlayer].pan); pPlayer->pActor->spr.Angles.Pitch += DAngle::fromDeg(PlayerList[nPlayer].input.horz);
} }
pPlayer->Angles.doPitchKeys(&sPlayerInput[nLocalPlayer].actions, sPlayerInput[nPlayer].pan); pPlayer->Angles.doPitchKeys(&PlayerList[nLocalPlayer].input);
if (actions & (SB_AIM_UP | SB_AIM_DOWN) || sPlayerInput[nPlayer].pan) if (actions & (SB_AIM_UP | SB_AIM_DOWN) || PlayerList[nPlayer].input.horz)
{ {
pPlayer->nDestVertPan = pPlayer->pActor->spr.Angles.Pitch; pPlayer->nDestVertPan = pPlayer->pActor->spr.Angles.Pitch;
pPlayer->bPlayerPan = pPlayer->bLockPan = true; pPlayer->bPlayerPan = pPlayer->bLockPan = true;
@ -2601,14 +2589,6 @@ sectdone:
} }
} }
// loc_1C3B4:
if (nPlayer == nLocalPlayer)
{
initpos = pPlayerActor->spr.pos;
initsectp = pPlayerActor->sector();
inita = pPlayerActor->spr.Angles.Yaw;
}
if (!PlayerList[nPlayer].nHealth) if (!PlayerList[nPlayer].nHealth)
{ {
PlayerList[nPlayer].nThrust.Zero(); PlayerList[nPlayer].nThrust.Zero();
@ -2629,7 +2609,7 @@ sectdone:
{ {
PlayerList[nPlayer].pActor->spr.Angles.Pitch -= maphoriz(dVertPan[nPlayer]); PlayerList[nPlayer].pActor->spr.Angles.Pitch -= maphoriz(dVertPan[nPlayer]);
if (PlayerList[nPlayer].pActor->spr.Angles.Pitch.Degrees() <= 38) if (PlayerList[nPlayer].pActor->spr.Angles.Pitch.Degrees() <= -38)
{ {
PlayerList[nPlayer].pActor->spr.Angles.Pitch = DAngle::fromDeg(-37.72); PlayerList[nPlayer].pActor->spr.Angles.Pitch = DAngle::fromDeg(-37.72);
} }

View file

@ -65,7 +65,8 @@ struct Player
uint16_t keys; uint16_t keys;
int16_t nMagic; int16_t nMagic;
int16_t nItem; int16_t nItem;
uint8_t items[8]; int8_t nCurrentItem;
int8_t items[8];
int16_t nAmmo[7]; // TODO - kMaxWeapons? int16_t nAmmo[7]; // TODO - kMaxWeapons?
int16_t nCurrentWeapon; int16_t nCurrentWeapon;
@ -78,7 +79,9 @@ struct Player
bool bPlayerPan, bLockPan; bool bPlayerPan, bLockPan;
DAngle nDestVertPan; DAngle nDestVertPan;
InputPacket input;
PlayerAngles Angles; PlayerAngles Angles;
DVector2 vel;
sectortype* pPlayerPushSect; sectortype* pPlayerPushSect;
sectortype* pPlayerViewSect; sectortype* pPlayerViewSect;
@ -101,6 +104,7 @@ struct Player
TObjPtr<DExhumedActor*> pPlayerGrenade; TObjPtr<DExhumedActor*> pPlayerGrenade;
TObjPtr<DExhumedActor*> pPlayerFloorSprite; TObjPtr<DExhumedActor*> pPlayerFloorSprite;
TObjPtr<DExhumedActor*> pDoppleSprite; TObjPtr<DExhumedActor*> pDoppleSprite;
TObjPtr<DExhumedActor*> pTarget;
}; };
@ -118,7 +122,6 @@ int GetPlayerFromActor(DExhumedActor* actor);
void SetPlayerMummified(int nPlayer, int bIsMummified); void SetPlayerMummified(int nPlayer, int bIsMummified);
int AddAmmo(int nPlayer, int nWeapon, int nAmmoAmount); int AddAmmo(int nPlayer, int nWeapon, int nAmmoAmount);
void ShootStaff(int nPlayer); void ShootStaff(int nPlayer);
void UpdatePlayerSpriteAngle(Player* pPlayer);
END_PS_NS END_PS_NS

View file

@ -216,7 +216,7 @@ void AIRa::Tick(RunListEvent* ev)
bool bVal = false; bool bVal = false;
Ra[nPlayer].pTarget = sPlayerInput[nPlayer].pTarget; Ra[nPlayer].pTarget = PlayerList[nPlayer].pTarget;
pActor->spr.picnum = seq_GetSeqPicnum2(nSeq, Ra[nPlayer].nFrame); pActor->spr.picnum = seq_GetSeqPicnum2(nSeq, Ra[nPlayer].nFrame);
if (Ra[nPlayer].nAction) if (Ra[nPlayer].nAction)

View file

@ -196,7 +196,7 @@ void DoSpiritHead()
static int dimSectCount = 0; static int dimSectCount = 0;
auto pSpiritSpr = pSpiritSprite; auto pSpiritSpr = pSpiritSprite;
sPlayerInput[0].actions |= SB_CENTERVIEW; PlayerList[0].input.actions |= SB_CENTERVIEW;
switch (nHeadStage) switch (nHeadStage)
{ {

View file

@ -676,7 +676,7 @@ int seq_PlotSequence(int nSprite, int16_t edx, int16_t nFrame, int16_t ecx)
auto pSector =pTSprite->sectp; auto pSector =pTSprite->sectp;
double nFloorZ = pSector->floorz; double nFloorZ = pSector->floorz;
if (nFloorZ <= PlayerList[nLocalPlayer].pActor->viewzoffset + initpos.Z) { if (nFloorZ <= PlayerList[nLocalPlayer].pActor->viewzoffset + PlayerList[nLocalPlayer].pActor->spr.pos.Z) {
pTSprite->ownerActor = nullptr; pTSprite->ownerActor = nullptr;
} }
else else

View file

@ -191,9 +191,9 @@ void BuildSnake(int nPlayer, double zVal)
if (hitactor && hitactor->spr.statnum >= 90 && hitactor->spr.statnum <= 199) { if (hitactor && hitactor->spr.statnum >= 90 && hitactor->spr.statnum <= 199) {
pTarget = hitactor; pTarget = hitactor;
} }
else if (sPlayerInput[nPlayer].pTarget != nullptr) else if (PlayerList[nPlayer].pTarget != nullptr)
{ {
pTarget = sPlayerInput[nPlayer].pTarget; pTarget = PlayerList[nPlayer].pTarget;
} }
int nSnake = GrabSnake(); int nSnake = GrabSnake();

View file

@ -433,9 +433,9 @@ void EXSoundEngine::CalcPosVel(int type, const void* source, const float pt[3],
Snake* pSnake = &SnakeList[nSnakeCam]; Snake* pSnake = &SnakeList[nSnakeCam];
campos = pSnake->pSprites[0]->spr.pos; campos = pSnake->pSprites[0]->spr.pos;
} }
else else if (const auto pActor = PlayerList[nLocalPlayer].pActor)
{ {
campos = initpos; campos = pActor->spr.pos;
} }
auto fcampos = GetSoundPos(campos); auto fcampos = GetSoundPos(campos);
@ -500,6 +500,8 @@ void GameInterface::UpdateSounds()
if (nFreeze) if (nFreeze)
return; return;
const auto pActor = PlayerList[nLocalPlayer].pActor;
DVector3 pos; DVector3 pos;
DAngle ang; DAngle ang;
if (nSnakeCam > -1) if (nSnakeCam > -1)
@ -508,10 +510,10 @@ void GameInterface::UpdateSounds()
pos = pSnake->pSprites[0]->spr.pos; pos = pSnake->pSprites[0]->spr.pos;
ang = pSnake->pSprites[0]->spr.Angles.Yaw; ang = pSnake->pSprites[0]->spr.Angles.Yaw;
} }
else else if (pActor)
{ {
pos = initpos; pos = pActor->spr.pos;
ang = inita; ang = pActor->spr.Angles.Yaw;
} }
SoundListener listener; SoundListener listener;
listener.angle = float(-ang.Radians()); // Build uses a period of 2048. listener.angle = float(-ang.Radians()); // Build uses a period of 2048.

View file

@ -203,8 +203,7 @@ void DrawView(double interpfrac, bool sceneonly)
auto nDoppleOldCstat = pDop->spr.cstat; auto nDoppleOldCstat = pDop->spr.cstat;
// update render angles. // update render angles.
pPlayer->Angles.updateRenderAngles(interpfrac); pPlayer->Angles.updateCameraAngles(interpfrac);
UpdatePlayerSpriteAngle(pPlayer);
if (nSnakeCam >= 0 && !sceneonly) if (nSnakeCam >= 0 && !sceneonly)
{ {
@ -250,6 +249,8 @@ void DrawView(double interpfrac, bool sceneonly)
} }
} }
const auto ampos = nCamerapos.XY();
if (nSnakeCam >= 0 && !sceneonly) if (nSnakeCam >= 0 && !sceneonly)
{ {
nCameraangles.Pitch = nullAngle; nCameraangles.Pitch = nullAngle;
@ -340,12 +341,6 @@ void DrawView(double interpfrac, bool sceneonly)
if (ang2.Degrees() < 0) if (ang2.Degrees() < 0)
ang2 = -ang2; ang2 = -ang2;
if (ang2 > mapangle(10))
{
inita -= ang2 * (1. / 8.);
return;
}
if (bSubTitles) if (bSubTitles)
{ {
subtitleOverlay.Start(I_GetTimeNS() * (120. / 1'000'000'000)); subtitleOverlay.Start(I_GetTimeNS() * (120. / 1'000'000'000));
@ -379,7 +374,7 @@ void DrawView(double interpfrac, bool sceneonly)
} }
} }
DrawMap(nCamerapos.XY(), nCameraangles.Yaw, interpfrac); DrawMap(ampos, nCameraangles.Yaw, interpfrac);
} }
} }
else else

View file

@ -312,10 +312,13 @@ void DoShadows(tspriteArray& tsprites, tspritetype* tsp, double viewz)
scale = tsp->scale; scale = tsp->scale;
} }
loz = DoShadowFindGroundPoint(tsp); loz = ownerActor->user.loz;
if (ownerActor->user.lowActor && (ownerActor->user.lowActor->spr.cstat & (CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR))) if (ownerActor->user.lowActor)
{ {
loz = ownerActor->user.loz; if (!(ownerActor->user.lowActor->spr.cstat & (CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR)))
{
loz = DoShadowFindGroundPoint(tsp);
}
} }
// need to find the ground here // need to find the ground here
@ -781,7 +784,7 @@ static void analyzesprites(tspriteArray& tsprites, const DVector3& viewpos, doub
if (pp->Flags & (PF_VIEW_FROM_OUTSIDE)) if (pp->Flags & (PF_VIEW_FROM_OUTSIDE))
tsp->cstat |= (CSTAT_SPRITE_TRANSLUCENT); tsp->cstat |= (CSTAT_SPRITE_TRANSLUCENT);
auto pos = pp->si.plusZ(tsp->pos.Z + pp->getViewHeightDiff()); auto pos = pp->si.plusZ(tsp->pos.Z);
if (pp->Flags & (PF_CLIMBING)) if (pp->Flags & (PF_CLIMBING))
{ {
@ -800,7 +803,7 @@ static void analyzesprites(tspriteArray& tsprites, const DVector3& viewpos, doub
} }
tsp->pos = pos; tsp->pos = pos;
tsp->Angles.Yaw = pp->siang; tsp->Angles.Yaw = pp->Angles.getCameraAngles().Yaw;
//continue; //continue;
} }
else else
@ -964,19 +967,6 @@ void post_analyzesprites(tspriteArray& tsprites)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
std::pair<DVector3, DAngle> GameInterface::GetCoordinates()
{
auto ppActor = Player[myconnectindex].actor;
if (!ppActor) return std::make_pair(DVector3(DBL_MAX, 0, 0), nullAngle);
return std::make_pair(ppActor->spr.pos, ppActor->spr.Angles.Yaw);
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void PrintSpriteInfo(PLAYER* pp) void PrintSpriteInfo(PLAYER* pp)
{ {
const int Y_STEP = 7; const int Y_STEP = 7;
@ -1239,10 +1229,11 @@ void drawscreen(PLAYER* pp, double interpfrac, bool sceneonly)
} }
// update render angles. // update render angles.
pp->Angles.updateRenderAngles(interpfrac); pp->Angles.updateCameraAngles(interpfrac);
// Get initial player position, interpolating if required. // Get initial player position, interpolating if required.
DVector3 tpos = camerapp->actor->getRenderPos(interpfrac); DVector3 tpos = camerapp->actor->getRenderPos(interpfrac);
DVector2 ampos = tpos.XY();
DRotator tangles = camerapp->Angles.getRenderAngles(interpfrac); DRotator tangles = camerapp->Angles.getRenderAngles(interpfrac);
sectortype* tsect = camerapp->cursector; sectortype* tsect = camerapp->cursector;
@ -1260,7 +1251,6 @@ void drawscreen(PLAYER* pp, double interpfrac, bool sceneonly)
} }
pp->si = tpos.plusZ(-pp->actor->getOffsetZ()); pp->si = tpos.plusZ(-pp->actor->getOffsetZ());
pp->siang = tangles.Yaw;
QuakeViewChange(camerapp, tpos, tangles.Yaw); QuakeViewChange(camerapp, tpos, tangles.Yaw);
int vis = g_visibility; int vis = g_visibility;
@ -1331,7 +1321,7 @@ void drawscreen(PLAYER* pp, double interpfrac, bool sceneonly)
} }
} }
} }
DrawOverheadMap(tpos.XY(), tangles.Yaw, interpfrac); DrawOverheadMap(ampos, tangles.Yaw, interpfrac);
} }
SWSpriteIterator it; SWSpriteIterator it;
@ -1455,7 +1445,7 @@ bool GameInterface::DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos,
if (spnum >= 0) if (spnum >= 0)
{ {
const auto daang = -(pp->Angles.RenderAngles.Yaw - cang).Normalized360().Degrees(); const auto daang = -(pp->Angles.getCameraAngles().Yaw - cang).Normalized360().Degrees();
auto vect = OutAutomapVector(mxy - cpos, cangvect, czoom, xydim); auto vect = OutAutomapVector(mxy - cpos, cangvect, czoom, xydim);
// This repeat scale is correct. // This repeat scale is correct.

View file

@ -504,9 +504,6 @@ void InitRunLevel(void)
// send packets with player info // send packets with player info
InitNetPlayerOptions(); InitNetPlayerOptions();
// Initialize Game part of network code
InitNetVars();
if (currentLevel) if (currentLevel)
{ {
PlaySong(currentLevel->music, currentLevel->cdSongId); PlaySong(currentLevel->music, currentLevel->cdSongId);

View file

@ -567,8 +567,6 @@ enum
PF_TANK = (BIT(29)), // Doin the tank thang PF_TANK = (BIT(29)), // Doin the tank thang
PF_WEAPON_DOWN = (BIT(31)), PF_WEAPON_DOWN = (BIT(31)),
PF2_TELEPORTED = (BIT(0)), PF2_TELEPORTED = (BIT(0)),
PF2_INPUT_CAN_AIM = (BIT(1)), // Allow calling DoPlayerHorizon() from processMovement()
PF2_INPUT_CAN_TURN_GENERAL = (BIT(2)), // Allow calling DoPlayerTurn() from processMovement()
PF2_INPUT_CAN_TURN_VEHICLE = (BIT(3)), // Allow calling DoPlayerTurnVehicle() from processMovement() PF2_INPUT_CAN_TURN_VEHICLE = (BIT(3)), // Allow calling DoPlayerTurnVehicle() from processMovement()
PF2_INPUT_CAN_TURN_TURRET = (BIT(4)), // Allow calling DoPlayerTurnTurret() from processMovement() PF2_INPUT_CAN_TURN_TURRET = (BIT(4)), // Allow calling DoPlayerTurnTurret() from processMovement()
}; };
@ -1589,8 +1587,6 @@ void SyncStatMessage(void); // sync.c
int COVERsetgamemode(int mode, int xdim, int ydim, int bpp); // draw.c int COVERsetgamemode(int mode, int xdim, int ydim, int bpp); // draw.c
void ScreenCaptureKeys(void); // draw.c void ScreenCaptureKeys(void); // draw.c
void computergetinput(int snum,InputPacket *syn); // jplayer.c
void SetupMirrorTiles(void); // rooms.c void SetupMirrorTiles(void); // rooms.c
bool FAF_Sector(sectortype* sect); // rooms.c bool FAF_Sector(sectortype* sect); // rooms.c
double GetZadjustment(sectortype* sect,short hitag); // rooms.c double GetZadjustment(sectortype* sect,short hitag); // rooms.c
@ -1663,53 +1659,6 @@ extern int ChopTics;
extern int Bunny_Count; extern int Bunny_Count;
struct GameInterface : public ::GameInterface
{
const char* Name() override { return "ShadowWarrior"; }
void app_init() override;
void LoadTextureInfo(TilesetBuildInfo& info) override;
void SetupSpecialTextures(TilesetBuildInfo& info) override;
void loadPalette() override;
void clearlocalinputstate() override;
void FreeLevelData() override;
bool GenerateSavePic() override;
void MenuSound(EMenuSounds snd) override;
bool CanSave() override;
bool StartGame(FNewGameStartup& gs) override;
FSavegameInfo GetSaveSig() override;
void SerializeGameState(FSerializer& arc);
void SetAmbience(bool on) override { if (on) StartAmbientSound(); else StopAmbientSound(); }
std::pair<DVector3, DAngle> GetCoordinates() override;
void UpdateSounds() override;
void ErrorCleanup() override;
void GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* input = nullptr) override;
void DrawBackground(void) override;
void Ticker(void) override;
void Render() override;
//void DrawWeapons() override;
void Startup() override;
const char *CheckCheatMode() override;
const char* GenericCheat(int player, int cheat) override;
void LevelCompleted(MapRecord *map, int skill) override;
void NextLevel(MapRecord *map, int skill) override;
void NewGame(MapRecord *map, int skill, bool) override;
bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) override;
void WarpToCoords(double x, double y, double z, DAngle ang) override;
void ToggleThirdPerson() override;
void SwitchCoopView() override;
void processSprites(tspriteArray& tsprites, const DVector3& view, DAngle viewang, double smoothRatio) override;
void UpdateCameras(double smoothratio) override;
void EnterPortal(DCoreActor* viewer, int type) override;
void LeavePortal(DCoreActor* viewer, int type) override;
void ExitFromMenu() override;
int GetCurrentSkill() override;
void StartSoundEngine() override;
GameStats getStats() override;
};
END_SW_NS END_SW_NS
#include "swactor.h" #include "swactor.h"
@ -1744,7 +1693,6 @@ struct PLAYER
double circle_camera_dist; double circle_camera_dist;
DVector3 si; // save player interp position for PlayerSprite DVector3 si; // save player interp position for PlayerSprite
DAngle siang;
DVector2 vect, ovect, slide_vect; // these need floatification, but must be done together. vect is in 14.18 format! DVector2 vect, ovect, slide_vect; // these need floatification, but must be done together. vect is in 14.18 format!
@ -1892,11 +1840,6 @@ struct PLAYER
uint8_t WpnReloadState; uint8_t WpnReloadState;
double getViewHeightDiff()
{
return actor->viewzoffset + height;
}
void posZset(const double val) void posZset(const double val)
{ {
actor->spr.pos.Z = val - actor->viewzoffset; actor->spr.pos.Z = val - actor->viewzoffset;
@ -1906,6 +1849,52 @@ struct PLAYER
extern PLAYER Player[MAX_SW_PLAYERS_REG+1]; extern PLAYER Player[MAX_SW_PLAYERS_REG+1];
struct GameInterface : public ::GameInterface
{
const char* Name() override { return "ShadowWarrior"; }
void app_init() override;
void LoadTextureInfo(TilesetBuildInfo& info) override;
void SetupSpecialTextures(TilesetBuildInfo& info) override;
void loadPalette() override;
void FreeLevelData() override;
bool GenerateSavePic() override;
void MenuSound(EMenuSounds snd) override;
bool CanSave() override;
bool StartGame(FNewGameStartup& gs) override;
FSavegameInfo GetSaveSig() override;
void SerializeGameState(FSerializer& arc);
void SetAmbience(bool on) override { if (on) StartAmbientSound(); else StopAmbientSound(); }
void UpdateSounds() override;
void ErrorCleanup() override;
void GetInput(HIDInput* const hidInput, InputPacket* const inputBuffer, InputPacket* const currInput, const double scaleAdjust) override { processMovement(hidInput, inputBuffer, currInput, scaleAdjust, 0, Player[myconnectindex].sop, Player[myconnectindex].sop_control ? 3. / 1.40625 : 1.); }
void DrawBackground(void) override;
void Ticker(void) override;
void Render() override;
//void DrawWeapons() override;
void Startup() override;
const char *CheckCheatMode() override;
const char* GenericCheat(int player, int cheat) override;
void LevelCompleted(MapRecord *map, int skill) override;
void NextLevel(MapRecord *map, int skill) override;
void NewGame(MapRecord *map, int skill, bool) override;
bool DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos, const DAngle cang, const DVector2& xydim, const double czoom, double const interpfrac) override;
DCoreActor* getConsoleActor() override { return Player[myconnectindex].actor; }
PlayerAngles* getConsoleAngles() override { return &Player[myconnectindex].Angles; }
void ToggleThirdPerson() override;
void SwitchCoopView() override;
void processSprites(tspriteArray& tsprites, const DVector3& view, DAngle viewang, double smoothRatio) override;
void UpdateCameras(double smoothratio) override;
void EnterPortal(DCoreActor* viewer, int type) override;
void LeavePortal(DCoreActor* viewer, int type) override;
void ExitFromMenu() override;
int GetCurrentSkill() override;
void StartSoundEngine() override;
GameStats getStats() override;
};
// OVER and UNDER water macros // OVER and UNDER water macros
inline bool SectorIsDiveArea(sectortype* sect) inline bool SectorIsDiveArea(sectortype* sect)
{ {

View file

@ -34,22 +34,12 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
BEGIN_SW_NS BEGIN_SW_NS
void DoPlayerTurnVehicle(PLAYER* pp, DAngle& plyaw, float avel, double z, double floor_dist);
void DoPlayerTurnTurret(PLAYER* pp, DAngle& plyaw, float avel);
static InputPacket loc;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// //
// //
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void InitNetVars(void)
{
loc = {};
}
void InitTimingVars(void) void InitTimingVars(void)
{ {
PlayClock = 0; PlayClock = 0;
@ -80,13 +70,13 @@ enum
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static void processWeapon(PLAYER* const pp) void processWeapon(PLAYER* const pp)
{ {
DSWActor* plActor = pp->actor; DSWActor* plActor = pp->actor;
if (plActor == nullptr) return; if (plActor == nullptr) return;
int i; int i;
if (loc.getNewWeapon() == WeaponSel_Next) if (pp->input.getNewWeapon() == WeaponSel_Next)
{ {
int next_weapon = plActor->user.WeaponNum + 1; int next_weapon = plActor->user.WeaponNum + 1;
int start_weapon; int start_weapon;
@ -119,9 +109,9 @@ static void processWeapon(PLAYER* const pp)
} }
} }
loc.setNewWeapon(next_weapon + 1); pp->input.setNewWeapon(next_weapon + 1);
} }
else if (loc.getNewWeapon() == WeaponSel_Prev) else if (pp->input.getNewWeapon() == WeaponSel_Prev)
{ {
int prev_weapon = plActor->user.WeaponNum - 1; int prev_weapon = plActor->user.WeaponNum - 1;
int start_weapon; int start_weapon;
@ -151,72 +141,13 @@ static void processWeapon(PLAYER* const pp)
} }
} }
} }
loc.setNewWeapon(prev_weapon + 1); pp->input.setNewWeapon(prev_weapon + 1);
} }
else if (loc.getNewWeapon() == WeaponSel_Alt) else if (pp->input.getNewWeapon() == WeaponSel_Alt)
{ {
int which_weapon = plActor->user.WeaponNum + 1; int which_weapon = plActor->user.WeaponNum + 1;
loc.setNewWeapon(which_weapon); pp->input.setNewWeapon(which_weapon);
} }
} }
void GameInterface::GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket *packet)
{
PLAYER* pp = &Player[myconnectindex];
if (paused || M_Active() || pp->actor == nullptr)
{
loc = {};
return;
}
InputPacket input {};
ApplyGlobalInput(loc, hidInput);
processMovement(&input, &loc, hidInput, scaleAdjust, 0, !pp->sop, pp->sop_control ? 3. / 1.40625 : 1.);
processWeapon(pp);
if (!SyncInput())
{
if ((pp->Flags2 & PF2_INPUT_CAN_AIM))
{
//For VR just set the pitch directly
pp->Angles.RenderAngles.Pitch = DAngle::fromDeg(input.horz);
}
if ((pp->Flags2 & PF2_INPUT_CAN_TURN_GENERAL))
{
pp->Angles.RenderAngles.Yaw += DAngle::fromDeg(input.avel);
}
if ((pp->Flags2 & PF2_INPUT_CAN_TURN_VEHICLE))
{
DoPlayerTurnVehicle(pp, pp->Angles.RenderAngles.Yaw, input.avel, pp->actor->getOffsetZ() + 10, abs(pp->actor->getOffsetZ() + 10 - pp->sop->floor_loz));
}
if ((pp->Flags2 & PF2_INPUT_CAN_TURN_TURRET))
{
DoPlayerTurnTurret(pp, pp->Angles.RenderAngles.Yaw, input.avel);
}
}
if (packet)
{
*packet = loc;
loc = {};
}
}
//---------------------------------------------------------------------------
//
// This is called from InputState::ClearAllInput and resets all static state being used here.
//
//---------------------------------------------------------------------------
void GameInterface::clearlocalinputstate()
{
loc = {};
}
END_SW_NS END_SW_NS

View file

@ -385,11 +385,9 @@ void so_updateinterpolations(void) // Stick at beginning of domovethings
for (sop = SectorObject, interp = so_interpdata; for (sop = SectorObject, interp = so_interpdata;
sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++) sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++)
{ {
bool skip = !SyncInput() && (sop->track == SO_TURRET); if (SO_EMPTY(sop))
if (SO_EMPTY(sop) || skip)
continue; continue;
if (interp->tic < interp->lasttic) if (interp->tic < interp->lasttic)
interp->tic += synctics; interp->tic += synctics;
for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++) for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++)
@ -436,11 +434,9 @@ void so_dointerpolations(double interpfrac) // Stick at beg
for (sop = SectorObject, interp = so_interpdata; for (sop = SectorObject, interp = so_interpdata;
sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++) sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++)
{ {
bool skip = !SyncInput() && (sop->track == SO_TURRET); if (SO_EMPTY(sop))
if (SO_EMPTY(sop) || skip)
continue; continue;
for (i = 0; i < interp->numinterpolations; i++) for (i = 0; i < interp->numinterpolations; i++)
{ {
auto actorofang = interp->data[i].actorofang; auto actorofang = interp->data[i].actorofang;
@ -472,8 +468,7 @@ void so_dointerpolations(double interpfrac) // Stick at beg
for (sop = SectorObject, interp = so_interpdata; for (sop = SectorObject, interp = so_interpdata;
sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++) sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++)
{ {
bool skip = !SyncInput() && (sop->track == SO_TURRET); if (SO_EMPTY(sop))
if (SO_EMPTY(sop) || skip)
continue; continue;
// Check if interpolation has been explicitly disabled // Check if interpolation has been explicitly disabled
@ -542,8 +537,7 @@ void so_restoreinterpolations(void) // Stick at end of drawscree
for (sop = SectorObject, interp = so_interpdata; for (sop = SectorObject, interp = so_interpdata;
sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++) sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++)
{ {
bool skip = !SyncInput() && (sop->track == SO_TURRET); if (SO_EMPTY(sop))
if (SO_EMPTY(sop) || skip)
continue; continue;
for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++) for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++)

View file

@ -74,7 +74,6 @@ struct gNET
extern gNET gNet; extern gNET gNet;
void UpdateInputs(void); void UpdateInputs(void);
void InitNetVars(void);
void InitTimingVars(void); void InitTimingVars(void);
void InitNetPlayerOptions(void); void InitNetPlayerOptions(void);
inline void SW_SendMessage(short, const char*) {} inline void SW_SendMessage(short, const char*) {}

View file

@ -54,29 +54,6 @@ BEGIN_SW_NS
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void GameInterface::WarpToCoords(double x, double y, double z, DAngle ang)
{
auto pp = &Player[myconnectindex];
auto ppActor = pp->actor;
if (!ppActor) return;
ppActor->spr.pos = DVector3(x,y,z);
if (ang != DAngle::fromDeg(INT_MIN))
{
Player->actor->spr.Angles.Yaw = ang;
}
ppActor->backuploc();
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static int osdcmd_mirror(CCmdFuncPtr parm) static int osdcmd_mirror(CCmdFuncPtr parm)
{ {
char base[80]; char base[80];

View file

@ -152,7 +152,6 @@ void DoPlayerFly(PLAYER* pp);
void DoPlayerBeginClimb(PLAYER* pp); void DoPlayerBeginClimb(PLAYER* pp);
void DoPlayerClimb(PLAYER* pp); void DoPlayerClimb(PLAYER* pp);
void DoPlayerBeginDie(PLAYER* pp); void DoPlayerBeginDie(PLAYER* pp);
void DoPlayerDie(PLAYER* pp);
// void DoPlayerBeginOperateBoat(PLAYER* pp); // void DoPlayerBeginOperateBoat(PLAYER* pp);
void DoPlayerBeginOperateVehicle(PLAYER* pp); void DoPlayerBeginOperateVehicle(PLAYER* pp);
void DoPlayerBeginOperate(PLAYER* pp); void DoPlayerBeginOperate(PLAYER* pp);
@ -180,6 +179,7 @@ int GetOverlapSector2(const DVector2& pos, sectortype** over, sectortype** under
void PlayerToRemote(PLAYER* pp); void PlayerToRemote(PLAYER* pp);
void PlayerRemoteInit(PLAYER* pp); void PlayerRemoteInit(PLAYER* pp);
void PlayerSpawnPosition(PLAYER* pp); void PlayerSpawnPosition(PLAYER* pp);
void processWeapon(PLAYER* const pp);
extern short target_ang; extern short target_ang;
@ -1491,7 +1491,7 @@ void DoPlayerSetWadeDepth(PLAYER* pp)
void DoPlayerViewOffset(PLAYER* pp) void DoPlayerViewOffset(PLAYER* pp)
{ {
pp->actor->viewzoffset -= pp->getViewHeightDiff() * 0.375; pp->actor->viewzoffset -= (pp->actor->viewzoffset + pp->height) * 0.375;
} }
void DoPlayerHeight(PLAYER* pp) void DoPlayerHeight(PLAYER* pp)
@ -1535,28 +1535,28 @@ void UpdatePlayerSpriteAngle(PLAYER* pp)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void DoPlayerTurnVehicle(PLAYER* pp, DAngle& plyaw, float avel, double zz, double floordist) void DoPlayerTurnVehicle(PLAYER* pp, double zz, double floordist)
{ {
SECTOR_OBJECT* sop = pp->sop; SECTOR_OBJECT* sop = pp->sop;
if (sop->drive_angspeed) if (sop->drive_angspeed)
{ {
float drive_oavel = pp->drive_avel; float drive_oavel = pp->drive_avel;
pp->drive_avel = float((avel * sop->drive_angspeed + (drive_oavel * (sop->drive_angslide - 1))) / sop->drive_angslide); pp->drive_avel = float((pp->input.avel * sop->drive_angspeed + (drive_oavel * (sop->drive_angslide - 1))) / sop->drive_angslide);
avel = pp->drive_avel; pp->input.avel = pp->drive_avel;
} }
else else
{ {
avel *= synctics * 0.125f; pp->input.avel *= synctics * 0.125f;
} }
if (avel != 0) if (pp->input.avel != 0)
{ {
auto sum = plyaw + DAngle::fromDeg(avel); auto sum = pp->actor->spr.Angles.Yaw + DAngle::fromDeg(pp->input.avel);
if (MultiClipTurn(pp, sum, zz, floordist)) if (MultiClipTurn(pp, sum, zz, floordist))
{ {
plyaw = sum; pp->actor->spr.Angles.Yaw = sum;
} }
} }
} }
@ -1600,7 +1600,7 @@ void DoPlayerTurnVehicleRect(PLAYER* pp, DVector2* pos, DVector2* opos)
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void DoPlayerTurnTurret(PLAYER* pp, DAngle& plyaw, float avel) void DoPlayerTurnTurret(PLAYER* pp)
{ {
DAngle new_ang, diff; DAngle new_ang, diff;
SECTOR_OBJECT* sop = pp->sop; SECTOR_OBJECT* sop = pp->sop;
@ -1608,18 +1608,18 @@ void DoPlayerTurnTurret(PLAYER* pp, DAngle& plyaw, float avel)
if (sop->drive_angspeed) if (sop->drive_angspeed)
{ {
float drive_oavel = pp->drive_avel; float drive_oavel = pp->drive_avel;
pp->drive_avel = float((avel * sop->drive_angspeed + (drive_oavel * (sop->drive_angslide - 1))) / sop->drive_angslide); pp->drive_avel = float((pp->input.avel * sop->drive_angspeed + (drive_oavel * (sop->drive_angslide - 1))) / sop->drive_angslide);
avel = pp->drive_avel; pp->input.avel = pp->drive_avel;
} }
else else
{ {
avel = avel * synctics * 0.25f; pp->input.avel = pp->input.avel * synctics * 0.25f;
} }
if (fabs(avel) >= FLT_EPSILON) if (fabs(pp->input.avel) >= FLT_EPSILON)
{ {
new_ang = plyaw + DAngle::fromDeg(avel); new_ang = pp->actor->spr.Angles.Yaw + DAngle::fromDeg(pp->input.avel);
if (sop->limit_ang_center >= nullAngle) if (sop->limit_ang_center >= nullAngle)
{ {
@ -1634,10 +1634,10 @@ void DoPlayerTurnTurret(PLAYER* pp, DAngle& plyaw, float avel)
} }
} }
plyaw = new_ang; pp->actor->spr.Angles.Yaw = new_ang;
} }
OperateSectorObject(pp->sop, plyaw, pp->sop->pmid); OperateSectorObject(pp->sop, pp->actor->spr.Angles.Yaw, pp->sop->pmid);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -1669,8 +1669,8 @@ void SlipSlope(PLAYER* pp)
void DoPlayerSlopeTilting(PLAYER* pp) void DoPlayerSlopeTilting(PLAYER* pp)
{ {
bool const canslopetilt = !(pp->Flags & (PF_FLYING|PF_SWIMMING|PF_DIVING|PF_CLIMBING|PF_JUMPING|PF_FALLING)) && pp->cursector && (pp->cursector->floorstat & CSTAT_SECTOR_SLOPE); const bool canslopetilt = (pp->input.actions & SB_AIMMODE) && !(pp->Flags & (PF_FLYING|PF_SWIMMING|PF_DIVING|PF_CLIMBING|PF_JUMPING|PF_FALLING));
pp->Angles.doViewPitch(pp->actor->spr.pos.XY(), pp->actor->spr.Angles.Yaw, pp->input.actions & SB_AIMMODE, canslopetilt, pp->cursector, (pp->Flags & PF_CLIMBING)); pp->Angles.doViewPitch(canslopetilt, pp->Flags & PF_CLIMBING);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -2030,18 +2030,14 @@ void DoPlayerMove(PLAYER* pp)
SlipSlope(pp); SlipSlope(pp);
pp->Angles.doViewYaw(pp->input.actions); pp->Angles.doViewYaw(&pp->input);
if (!SyncInput()) if (SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_TURN_GENERAL);
}
else
{ {
pp->actor->spr.Angles.Yaw += DAngle::fromDeg(pp->input.avel); pp->actor->spr.Angles.Yaw += DAngle::fromDeg(pp->input.avel);
} }
pp->Angles.doYawKeys(&pp->input.actions); pp->Angles.doYawKeys(&pp->input);
UpdatePlayerSpriteAngle(pp); UpdatePlayerSpriteAngle(pp);
pp->lastcursector = pp->cursector; pp->lastcursector = pp->cursector;
@ -2160,17 +2156,13 @@ void DoPlayerMove(PLAYER* pp)
DoPlayerSetWadeDepth(pp); DoPlayerSetWadeDepth(pp);
if (!SyncInput()) if (SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_AIM);
}
else
{ {
//Set pitch directly //Set pitch directly
pp->actor->spr.Angles.Pitch = DAngle::fromDeg(pp->input.horz); pp->actor->spr.Angles.Pitch = DAngle::fromDeg(pp->input.horz);
} }
pp->Angles.doPitchKeys(&pp->input.actions, pp->input.horz); pp->Angles.doPitchKeys(&pp->input);
DoPlayerSlopeTilting(pp); DoPlayerSlopeTilting(pp);
@ -2588,9 +2580,6 @@ void DoPlayerMoveVehicle(PLAYER* pp)
PlaySOsound(pp->sop->mid_sector,SO_IDLE_SOUND); PlaySOsound(pp->sop->mid_sector,SO_IDLE_SOUND);
} }
// force synchronised input here for now.
setForcedSyncInput();
if (PLAYER_MOVING(pp) == 0) if (PLAYER_MOVING(pp) == 0)
pp->Flags &= ~(PF_PLAYER_MOVED); pp->Flags &= ~(PF_PLAYER_MOVED);
else else
@ -2702,14 +2691,8 @@ void DoPlayerMoveVehicle(PLAYER* pp)
} }
else else
{ {
if (!SyncInput()) setForcedSyncInput();
{ DoPlayerTurnVehicle(pp, zz, floordist);
pp->Flags2 |= (PF2_INPUT_CAN_TURN_VEHICLE);
}
else
{
DoPlayerTurnVehicle(pp, pp->actor->spr.Angles.Yaw, pp->input.avel, zz, floordist);
}
auto save_cstat = plActor->spr.cstat; auto save_cstat = plActor->spr.cstat;
plActor->spr.cstat &= ~(CSTAT_SPRITE_BLOCK); plActor->spr.cstat &= ~(CSTAT_SPRITE_BLOCK);
@ -2748,17 +2731,13 @@ void DoPlayerMoveVehicle(PLAYER* pp)
OperateSectorObject(pp->sop, pp->actor->spr.Angles.Yaw, pp->actor->spr.pos.XY()); OperateSectorObject(pp->sop, pp->actor->spr.Angles.Yaw, pp->actor->spr.pos.XY());
pp->cursector = save_sect; // for speed pp->cursector = save_sect; // for speed
if (!SyncInput()) if (SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_AIM);
}
else
{ {
//Set pitch directly //Set pitch directly
pp->actor->spr.Angles.Pitch = DAngle::fromDeg(pp->input.horz); pp->actor->spr.Angles.Pitch = DAngle::fromDeg(pp->input.horz);
} }
pp->Angles.doPitchKeys(&pp->input.actions, pp->input.horz); pp->Angles.doPitchKeys(&pp->input);
DoPlayerSlopeTilting(pp); DoPlayerSlopeTilting(pp);
@ -2781,31 +2760,21 @@ void DoPlayerMoveTurret(PLAYER* pp)
PlaySOsound(pp->sop->mid_sector, SO_IDLE_SOUND); PlaySOsound(pp->sop->mid_sector, SO_IDLE_SOUND);
} }
if (!SyncInput()) setForcedSyncInput();
{ DoPlayerTurnTurret(pp);
pp->Flags2 |= (PF2_INPUT_CAN_TURN_TURRET);
}
else
{
DoPlayerTurnTurret(pp, pp->actor->spr.Angles.Yaw, pp->input.avel);
}
if (PLAYER_MOVING(pp) == 0) if (PLAYER_MOVING(pp) == 0)
pp->Flags &= ~(PF_PLAYER_MOVED); pp->Flags &= ~(PF_PLAYER_MOVED);
else else
pp->Flags |= (PF_PLAYER_MOVED); pp->Flags |= (PF_PLAYER_MOVED);
if (!SyncInput()) if (SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_AIM);
}
else
{ {
//Set pitch directly //Set pitch directly
pp->actor->spr.Angles.Pitch = DAngle::fromDeg(pp->input.horz); pp->actor->spr.Angles.Pitch = DAngle::fromDeg(pp->input.horz);
} }
pp->Angles.doPitchKeys(&pp->input.actions, pp->input.horz); pp->Angles.doPitchKeys(&pp->input);
DoPlayerSlopeTilting(pp); DoPlayerSlopeTilting(pp);
} }
@ -3398,17 +3367,13 @@ void DoPlayerClimb(PLAYER* pp)
// setsprite to players location // setsprite to players location
ChangeActorSect(pp->actor, pp->cursector); ChangeActorSect(pp->actor, pp->cursector);
if (!SyncInput()) if (SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_AIM);
}
else
{ {
//Set pitch directly //Set pitch directly
pp->actor->spr.Angles.Pitch = DAngle::fromDeg(pp->input.horz); pp->actor->spr.Angles.Pitch = DAngle::fromDeg(pp->input.horz);
} }
pp->Angles.doPitchKeys(&pp->input.actions, pp->input.horz); pp->Angles.doPitchKeys(&pp->input);
DoPlayerSlopeTilting(pp); DoPlayerSlopeTilting(pp);
@ -5914,6 +5879,7 @@ void DoPlayerBeginDie(PLAYER* pp)
pp->Flags |= (PF_DEAD); pp->Flags |= (PF_DEAD);
plActor->user.Flags &= ~(SPR_BOUNCE); plActor->user.Flags &= ~(SPR_BOUNCE);
pp->Flags &= ~(PF_HEAD_CONTROL); pp->Flags &= ~(PF_HEAD_CONTROL);
setForcedSyncInput();
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -6006,14 +5972,7 @@ void DoPlayerDeathFollowKiller(PLAYER* pp)
// allow turning // allow turning
if (pp->Flags & (PF_DEAD_HEAD|PF_HEAD_CONTROL)) if (pp->Flags & (PF_DEAD_HEAD|PF_HEAD_CONTROL))
{ {
if (!SyncInput()) pp->actor->spr.Angles.Yaw += DAngle::fromDeg(pp->input.avel);
{
pp->Flags2 |= (PF2_INPUT_CAN_TURN_GENERAL);
}
else
{
pp->actor->spr.Angles.Yaw += DAngle::fromDeg(pp->input.avel);
}
UpdatePlayerSpriteAngle(pp); UpdatePlayerSpriteAngle(pp);
} }
@ -6714,14 +6673,12 @@ void MoveSkipSavePos(void)
MoveSkip4 = (MoveSkip4 + 1) & 3; MoveSkip4 = (MoveSkip4 + 1) & 3;
MoveSkip2 ^= 1; MoveSkip2 ^= 1;
// this must be done before the view is backed up.
Player[myconnectindex].Angles.resetRenderAngles();
// Save off player // Save off player
TRAVERSE_CONNECT(pnum) TRAVERSE_CONNECT(pnum)
{ {
pp = Player + pnum; pp = Player + pnum;
pp->Angles.resetCameraAngles();
pp->actor->backuploc(); pp->actor->backuploc();
pp->obob_z = pp->bob_z; pp->obob_z = pp->bob_z;
pp->opbob_amt = pp->pbob_amt; pp->opbob_amt = pp->pbob_amt;
@ -7000,6 +6957,9 @@ void domovethings(void)
} }
} }
// process weapon bits
processWeapon(pp);
// auto tracking mode for single player multi-game // auto tracking mode for single player multi-game
if (numplayers <= 1 && PlayerTrackingMode && pnum == screenpeek && screenpeek != myconnectindex) if (numplayers <= 1 && PlayerTrackingMode && pnum == screenpeek && screenpeek != myconnectindex)
{ {
@ -7010,18 +6970,13 @@ void domovethings(void)
{ {
WeaponOperate(pp); WeaponOperate(pp);
PlayerOperateEnv(pp); PlayerOperateEnv(pp);
resetForcedSyncInput();
} }
// do for moving sectors // do for moving sectors
DoPlayerSectorUpdatePreMove(pp); DoPlayerSectorUpdatePreMove(pp);
ChopsCheck(pp); ChopsCheck(pp);
// Reset flags used while tying input to framerate
pp->Flags2 &= ~(PF2_INPUT_CAN_AIM|PF2_INPUT_CAN_TURN_GENERAL|PF2_INPUT_CAN_TURN_VEHICLE|PF2_INPUT_CAN_TURN_TURRET);
// disable synchronised input if set by game.
resetForcedSyncInput();
// convert fvel/svel into a vector before performing actions. // convert fvel/svel into a vector before performing actions.
const auto velvect = DVector2(pp->input.fvel, pp->input.svel).Rotated(pp->actor->spr.Angles.Yaw); const auto velvect = DVector2(pp->input.fvel, pp->input.svel).Rotated(pp->actor->spr.Angles.Yaw);
pp->input.fvel = (float)velvect.X; pp->input.fvel = (float)velvect.X;
@ -7563,7 +7518,6 @@ DEFINE_FIELD_X(SWPlayer, PLAYER, circle_camera_dist)
//DEFINE_FIELD_X(SWPlayer, PLAYER, six) //DEFINE_FIELD_X(SWPlayer, PLAYER, six)
//DEFINE_FIELD_X(SWPlayer, PLAYER, siy) //DEFINE_FIELD_X(SWPlayer, PLAYER, siy)
//DEFINE_FIELD_X(SWPlayer, PLAYER, siz) //DEFINE_FIELD_X(SWPlayer, PLAYER, siz)
DEFINE_FIELD_X(SWPlayer, PLAYER, siang)
//DEFINE_FIELD_X(SWPlayer, PLAYER, xvect) //DEFINE_FIELD_X(SWPlayer, PLAYER, xvect)
//DEFINE_FIELD_X(SWPlayer, PLAYER, yvect) //DEFINE_FIELD_X(SWPlayer, PLAYER, yvect)
//DEFINE_FIELD_X(SWPlayer, PLAYER, oxvect) //DEFINE_FIELD_X(SWPlayer, PLAYER, oxvect)

View file

@ -125,7 +125,7 @@ void DoPlayer(void);
void domovethings(void); void domovethings(void);
void InitAllPlayers(void); void InitAllPlayers(void);
void InitMultiPlayerInfo(const DVector3& spawnpos, const DAngle startang); void InitMultiPlayerInfo(const DVector3& spawnpos, const DAngle startang);
void MoveScrollMode2D(PLAYER* pp, ControlInfo* const hidInput); void MoveScrollMode2D(PLAYER* pp, HIDInput* const hidInput);
void DoPlayerDivePalette(PLAYER* pp); void DoPlayerDivePalette(PLAYER* pp);
void DoPlayerNightVisionPalette(PLAYER* pp); void DoPlayerNightVisionPalette(PLAYER* pp);
void DoPlayerStopDiveNoWarp(PLAYER* pp); void DoPlayerStopDiveNoWarp(PLAYER* pp);

View file

@ -460,7 +460,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PLAYER& w, PLAYER*
("six", w.si.X) ("six", w.si.X)
("siy", w.si.Y) ("siy", w.si.Y)
("siz", w.si.Z) ("siz", w.si.Z)
("siang", w.siang)
("xvect", w.vect.X) ("xvect", w.vect.X)
("yvect", w.vect.Y) ("yvect", w.vect.Y)
("friction", w.friction) ("friction", w.friction)
@ -1163,7 +1162,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
InitTimingVars(); InitTimingVars();
PlayClock = SavePlayClock; PlayClock = SavePlayClock;
defineSky(nullptr, pskybits_override, nullptr, 0, parallaxyscale_override / 8192.f); defineSky(nullptr, pskybits_override, nullptr, 0, parallaxyscale_override / 8192.f);
InitNetVars();
screenpeek = myconnectindex; screenpeek = myconnectindex;

View file

@ -688,6 +688,9 @@ class BloodStatusBar : RazeStatusBar
} }
else else
{ {
bool stateNeedsEvenAmt = pPlayer.weaponState == 3 || pPlayer.weaponState == 1;
bool stateNeedsOddAmt = pPlayer.weaponState == 2;
num += stateNeedsEvenAmt && (num % 2) || stateNeedsOddAmt && !(num % 2);
int clip = CalcMagazineAmount(num, 2, pPlayer.weaponState == 1); int clip = CalcMagazineAmount(num, 2, pPlayer.weaponState == 1);
int total = num - clip; int total = num - clip;
String format = String.Format("%d/%d", clip, num - clip); String format = String.Format("%d/%d", clip, num - clip);

View file

@ -151,6 +151,7 @@ class DukeCrane : DukeActor
plr.on_crane = self; plr.on_crane = self;
plr.actor.PlayActorSound("CRANEGRAB"); plr.actor.PlayActorSound("CRANEGRAB");
plr.settargetangle(self.angle + 180); plr.settargetangle(self.angle + 180);
Raze.forceSyncInput();
} }
else else
{ {

View file

@ -47,6 +47,7 @@ class DukeViewscreen : DukeActor
camsprite = self; camsprite = self;
user.newOwner = acti; user.newOwner = acti;
Raze.forceSyncInput();
return true; return true;
} }
} }

View file

@ -303,8 +303,6 @@ struct DukePlayer native
native int max_secret_rooms, secret_rooms, max_actors_killed, actors_killed; native int max_secret_rooms, secret_rooms, max_actors_killed, actors_killed;
native bool resurrected;
// Redneck Rampage additions. Those which did not have names in the reconstructed source got one from either RedneckGDX or RedNukem. // Redneck Rampage additions. Those which did not have names in the reconstructed source got one from either RedneckGDX or RedNukem.
// Items were reordered by size. // Items were reordered by size.
native int stairs; native int stairs;

View file

@ -50,7 +50,7 @@ struct ExhumedPlayer native
native uint16 keys; native uint16 keys;
native int16 nMagic; native int16 nMagic;
native int16 nItem; native int16 nItem;
native uint8 items[8]; native int8 items[8];
native int16 nAmmo[7]; // TODO - kMaxWeapons? native int16 nAmmo[7]; // TODO - kMaxWeapons?
native int16 nPlayerWeapons; native int16 nPlayerWeapons;

View file

@ -198,7 +198,6 @@ struct SWPlayer native
native double hiz,loz; native double hiz,loz;
native double p_ceiling_dist,p_floor_dist; native double p_ceiling_dist,p_floor_dist;
native double circle_camera_dist; native double circle_camera_dist;
native double siang;
native int friction; native int friction;
native int16 slide_ang; native int16 slide_ang;

View file

@ -171,6 +171,7 @@ struct Raze
static double bobval(double angle) { return sin(angle * (360. / 2048)); } static double bobval(double angle) { return sin(angle * (360. / 2048)); }
native static TextureID PickTexture(TextureID texid); native static TextureID PickTexture(TextureID texid);
native static int GetBuildTime(); native static int GetBuildTime();
native static void forceSyncInput();
native static Font PickBigFont(String cmptext = ""); native static Font PickBigFont(String cmptext = "");
native static Font PickSmallFont(String cmptext = ""); native static Font PickSmallFont(String cmptext = "");
native static int SoundEnabled(); native static int SoundEnabled();