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;
static bool sendPause;
bool pausedWithKey;
bool gamesetinput = false;
@ -1289,6 +1290,12 @@ void CONFIG_ReadCombatMacros()
//==========================================================================
CCMD(pause)
{
sendPause = true;
}
CCMD(snd_reset)
{
Mus_Stop();
@ -1512,6 +1519,12 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Raze, GetBuildTime, I_GetBuildTime)
ACTION_RETURN_INT(I_GetBuildTime());
}
DEFINE_ACTION_FUNCTION_NATIVE(_Raze, forceSyncInput, setForcedSyncInput)
{
setForcedSyncInput();
return 0;
}
DEFINE_ACTION_FUNCTION(_Raze, PickTexture)
{
PARAM_PROLOGUE;

View file

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

View file

@ -46,6 +46,7 @@
#include "quotemgr.h"
#include "gamestruct.h"
#include "statusbar.h"
#include "coreactor.h"
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
@ -235,14 +236,14 @@ ADD_STAT(fps)
ADD_STAT(coord)
{
auto coord = gi->GetCoordinates();
FString out;
if (coord.first.X < DBL_MAX)
if (const auto pActor = gi->getConsoleActor())
{
out.AppendFormat("X: %f ", coord.first.X);
out.AppendFormat("Y: %f ", coord.first.Y);
out.AppendFormat("Z: %f ", coord.first.Z);
out.AppendFormat("Angle: %f\n", coord.second.Degrees());
out.AppendFormat("X: %.4f ", pActor->spr.pos.X);
out.AppendFormat("Y: %.4f ", pActor->spr.pos.Y);
out.AppendFormat("Z: %.4f ", pActor->spr.pos.Z);
out.AppendFormat("Yaw: %.4f ", pActor->spr.Angles.Yaw.Degrees());
out.AppendFormat("Pitch: %.4f\n", pActor->spr.Angles.Pitch.Degrees());
}
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 "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_HORIZOFFCLIMB = DAngle::fromDeg(-38.);
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.))
{
auto sgn = angle.Sgn();
const auto sgn = angle.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;
void updateTurnHeldAmt(double const scaleAdjust)
void updateTurnHeldAmt(const double 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.
int const keymove = 1 << int(!!(inputBuffer->actions & SB_RUN));
float const hidspeed = float(getTicrateScale(YAW_TURNSPEEDS[2]) * turnscale);
float const scaleAdjustf = float(scaleAdjust);
const int keymove = 1 << int(!!(inputBuffer->actions & SB_RUN));
const float hidspeed = float(getTicrateScale(YAW_TURNSPEEDS[2]) * turnscale);
const float scaleAdjustf = float(scaleAdjust);
// determine player input.
auto const 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;
auto const strafing = buttonMap.ButtonDown(gamefunc_Strafe_Right) - buttonMap.ButtonDown(gamefunc_Strafe_Left) - hidInput->dx * scaleAdjustf;
const auto turning = buttonMap.ButtonDown(gamefunc_Turn_Right) - buttonMap.ButtonDown(gamefunc_Turn_Left);
const auto moving = buttonMap.ButtonDown(gamefunc_Move_Forward) - buttonMap.ButtonDown(gamefunc_Move_Backward) + hidInput->joyaxes[JOYAXIS_Forward] * scaleAdjustf;
const auto strafing = buttonMap.ButtonDown(gamefunc_Strafe_Right) - buttonMap.ButtonDown(gamefunc_Strafe_Left) - hidInput->joyaxes[JOYAXIS_Side] * scaleAdjustf;
// process player angle input.
if (!(buttonMap.ButtonDown(gamefunc_Strafe) && allowstrafe))
{
float const turndir = clamp(turning + strafing * !allowstrafe, -1.f, 1.f);
float const turnspeed = float(getTicrateScale(YAW_TURNSPEEDS[keymove]) * turnscale * (isTurboTurnTime() ? 1. : YAW_PREAMBLESCALE));
currInput->avel += hidInput->mouseturnx + (hidInput->dyaw * hidspeed + turndir * turnspeed) * scaleAdjustf;
const float turndir = clamp(turning + strafing * !allowstrafe, -1.f, 1.f);
const float turnspeed = float(getTicrateScale(YAW_TURNSPEEDS[keymove]) * turnscale * (isTurboTurnTime() ? 1. : YAW_PREAMBLESCALE));
currInput->avel += hidInput->mouseturnx - (hidInput->joyaxes[JOYAXIS_Yaw] * hidspeed - turndir * turnspeed) * scaleAdjustf;
if (turndir) updateTurnHeldAmt(scaleAdjust); else resetTurnHeldAmt();
}
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.
if (!(inputBuffer->actions & SB_AIMMODE))
currInput->horz += hidInput->mouseturny + hidInput->dpitch * hidspeed * scaleAdjustf;
currInput->horz += hidInput->mouseturny - hidInput->joyaxes[JOYAXIS_Pitch] * hidspeed * scaleAdjustf;
else
currInput->fvel -= hidInput->mousemovey + hidInput->dpitch * keymove * scaleAdjustf;
currInput->fvel -= hidInput->mousemovey - hidInput->joyaxes[JOYAXIS_Pitch] * keymove * scaleAdjustf;
// process movement input.
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.
//
//---------------------------------------------------------------------------
void PlayerAngles::doPitchKeys(ESyncBits* actions, const bool stopcentering)
void PlayerAngles::doPitchKeys(InputPacket* const input)
{
// Cancel return to center if conditions met.
if (stopcentering) *actions &= ~SB_CENTERVIEW;
if (input->horz)
input->actions &= ~SB_CENTERVIEW;
// 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;
*actions &= ~SB_CENTERVIEW;
pActor->spr.Angles.Pitch += DAngle::fromDeg(getTicrateScale(PITCH_AIMSPEED) * aiming);
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;
*actions |= SB_CENTERVIEW;
pActor->spr.Angles.Pitch += DAngle::fromDeg(getTicrateScale(PITCH_LOOKSPEED) * looking);
input->actions |= SB_CENTERVIEW;
}
// 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 scale = pitch > PITCH_CNTRSINEOFFSET ? (pitch - PITCH_CNTRSINEOFFSET).Cos() : 1.;
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.
@ -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)
{
// currently not spinning, so start a spin
YawSpin = -DAngle180;
}
*actions &= ~SB_TURNAROUND;
input->actions &= ~SB_TURNAROUND;
}
if (YawSpin < nullAngle)
{
// 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;
if (YawSpin > nullAngle)
{
@ -257,37 +297,39 @@ 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
auto rotpt = pos + ang.ToVector() * (!isBlood() ? 32 : 4);
auto tempsect = cursectnum;
const auto rotpt = pActor->spr.pos.XY() + pActor->spr.Angles.Yaw.ToVector() * (!isBlood() ? 32 : 4);
auto tempsect = actorsect;
updatesector(rotpt, &tempsect);
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
// your sector, unless it's Blood.
double const j = getflorzofslopeptr(cursectnum, pos);
double const k = getflorzofslopeptr(!isBlood() ? cursectnum : tempsect, rotpt);
const double j = getflorzofslopeptr(actorsect, pActor->spr.pos.XY());
const double k = getflorzofslopeptr(!isBlood() ? actorsect : tempsect, rotpt);
// If extended point is in same sector as you or the slopes
// of the sector of the extended point and your sector match
// closely (to avoid accidently looking straight out when
// you're at the edge of a sector line) then adjust horizon
// 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));
}
}
}
}
if (climbing)
if (cl_slopetilting && climbing)
{
// tilt when climbing but you can't even really tell it.
if (ViewAngles.Pitch > PITCH_HORIZOFFCLIMB)
@ -301,7 +343,6 @@ void PlayerAngles::doViewPitch(const DVector2& pos, DAngle const ang, bool const
// 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 ||
ViewAngles.Roll.Degrees() != 0.0f)
@ -324,10 +365,10 @@ void PlayerAngles::doViewYaw(const ESyncBits actions)
scaletozero(ViewAngles.Roll, YAW_LOOKRETURN);
// 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.Roll += DAngle::fromDeg(getTicrateScale(YAW_ROTATESPEED)) * looking;
ViewAngles.Yaw += DAngle::fromDeg(getTicrateScale(YAW_LOOKINGSPEED) * 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())
{
w.resetRenderAngles();
w.resetCameraAngles();
}
}
return arc;

View file

@ -1,34 +1,29 @@
#pragma once
#include "m_fixed.h"
#include "gamecvars.h"
#include "gamestruct.h"
#include "serializer.h"
#include "gamefuncs.h"
#include "packet.h"
struct PlayerAngles
{
// Player viewing angles, separate from the camera.
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.
DAngle YawSpin;
friend FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def);
friend void getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet);
// Prototypes.
void doPitchKeys(ESyncBits* actions, const bool stopcentering);
void doYawKeys(ESyncBits* actions);
void doViewPitch(const DVector2& pos, DAngle const ang, bool const aimmode, bool const canslopetilt, sectortype* const cursectnum, bool const climbing = false);
void doViewYaw(const ESyncBits actions);
void doPitchKeys(InputPacket* const input);
void doYawKeys(InputPacket* const input);
void doViewPitch(const bool canslopetilt, const bool climbing = false);
void doViewYaw(InputPacket* const input);
// General methods.
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;
}
DAngle getPitchWithView()
@ -37,25 +32,29 @@ struct PlayerAngles
}
// Render angle functions.
const DRotator& getCameraAngles() const
{
return CameraAngles;
}
DRotator getRenderAngles(const double interpfrac)
{
// 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);
return angles;
}
void updateRenderAngles(const double interpfrac)
void updateCameraAngles(const double interpfrac)
{
// Apply the current interpolated angle state to the render angles.
const auto lerpAngles = interpolatedvalue(pActor->PrevAngles, pActor->spr.Angles, interpfrac);
RenderAngles += lerpAngles - PrevLerpAngles;
CameraAngles += lerpAngles - PrevLerpAngles;
PrevLerpAngles = lerpAngles;
}
void resetRenderAngles()
void resetCameraAngles()
{
// Apply any last remaining ticrate angle updates and reset variables.
RenderAngles += pActor->spr.Angles - PrevLerpAngles;
PrevLerpAngles = pActor->spr.Angles = RenderAngles;
CameraAngles += pActor->spr.Angles - PrevLerpAngles;
PrevLerpAngles = pActor->spr.Angles = CameraAngles;
PrevViewAngles = ViewAngles;
}
@ -68,14 +67,14 @@ struct PlayerAngles
}
auto getWeaponOffsets(const double interpfrac)
{
// Push the Y down a bit since the weapon is at the edge of the screen.
auto offsets = getCrosshairOffsets(interpfrac); offsets.first.Y *= 4.;
// 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.; offsets.second = nullAngle;
return offsets;
}
private:
// Private data which should never be accessed publically.
DRotator PrevLerpAngles;
// Private data which should never be accessed publicly.
DRotator PrevLerpAngles, CameraAngles;
DCoreActor* pActor;
};
@ -83,7 +82,8 @@ class FSerializer;
FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def);
void updateTurnHeldAmt(double const scaleAdjust);
void updateTurnHeldAmt(const double scaleAdjust);
bool isTurboTurnTime();
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;
class DCoreActor;
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
{
@ -69,7 +72,6 @@ struct GameInterface
virtual void LoadTextureInfo(TilesetBuildInfo& info) {}
virtual void SetupSpecialTextures(TilesetBuildInfo&) {}
virtual void loadPalette();
virtual void clearlocalinputstate() {}
virtual void UpdateScreenSize() {}
virtual void FreeLevelData();
virtual void FreeGameData() {}
@ -87,9 +89,8 @@ struct GameInterface
virtual void SerializeGameState(FSerializer& arc) {}
virtual void DrawPlayerSprite(const DVector2& origin, bool onteam) {}
virtual void SetAmbience(bool on) {}
virtual std::pair<DVector3, DAngle> GetCoordinates() { return {}; }
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 ErrorCleanup() {}
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 DAngle playerPitchMin() { 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 SwitchCoopView() { Printf("Unsupported command\n"); }
virtual void ToggleShowWeapon() { Printf("Unsupported command\n"); }

View file

@ -48,7 +48,6 @@
static int WeaponToSend = 0;
ESyncBits ActionsToSend = 0;
static int dpad_lock = 0;
bool sendPause;
bool crouch_toggle;
// 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();
@ -142,7 +141,7 @@ void InputState::ClearAllInput()
{
ActionsToSend = 0;
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)
{
@ -195,34 +194,6 @@ int32_t handleevents(void)
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;
}
CCMD(pause)
{
sendPause = true;
}
CCMD(warptocoords)
{
if (netgame)
@ -365,7 +331,7 @@ CCMD(warptocoords)
}
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;
}
if (gamestate != GS_LEVEL)
@ -373,20 +339,14 @@ CCMD(warptocoords)
Printf("warptocoords: must be in a level\n");
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)
@ -404,84 +364,87 @@ CCMD(show_weapon)
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;
if (hidInput && buttonMap.ButtonDown(gamefunc_Dpad_Select))
{
// 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;
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;
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;
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;
// This eats the controller input for regular use
hidInput->dx = 0;
hidInput->dz = 0;
hidInput->dyaw = 0;
// This eats the controller inputBuffer-> for regular use
hidInput->joyaxes[JOYAXIS_Side] = 0;
hidInput->joyaxes[JOYAXIS_Forward] = 0;
hidInput->joyaxes[JOYAXIS_Yaw] = 0;
}
else dpad_lock = 0;
input.actions |= ActionsToSend;
inputBuffer->actions |= ActionsToSend;
ActionsToSend = 0;
if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && hidInput->dz > 0))
input.actions |= SB_AIM_UP;
if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && hidInput->joyaxes[JOYAXIS_Forward] > 0))
inputBuffer->actions |= SB_AIM_UP;
if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && hidInput->dz < 0)))
input.actions |= SB_AIM_DOWN;
if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && hidInput->joyaxes[JOYAXIS_Forward] < 0)))
inputBuffer->actions |= SB_AIM_DOWN;
if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming))
hidInput->dz = 0;
hidInput->joyaxes[JOYAXIS_Forward] = 0;
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)
input.actions |= SB_CROUCH;
inputBuffer->actions |= SB_CROUCH;
if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch))
{
crouch_toggle = !crouch_toggle && crouchable;
if (crouchable) buttonMap.ClearButton(gamefunc_Toggle_Crouch);
crouch_toggle = !crouch_toggle;
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;
if (buttonMap.ButtonDown(gamefunc_Fire))
input.actions |= SB_FIRE;
inputBuffer->actions |= SB_FIRE;
if (buttonMap.ButtonDown(gamefunc_Alt_Fire))
input.actions |= SB_ALTFIRE;
inputBuffer->actions |= SB_ALTFIRE;
if (buttonMap.ButtonDown(gamefunc_Open))
{
if (isBlood()) buttonMap.ClearButton(gamefunc_Open);
input.actions |= SB_OPEN;
inputBuffer->actions |= SB_OPEN;
}
if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)))
input.actions |= SB_RUN;
inputBuffer->actions |= SB_RUN;
if (!in_mousemode && !buttonMap.ButtonDown(gamefunc_Mouse_Aiming))
input.actions |= SB_AIMMODE;
inputBuffer->actions |= SB_AIMMODE;
if (buttonMap.ButtonDown(gamefunc_Look_Up))
input.actions |= SB_LOOK_UP;
inputBuffer->actions |= SB_LOOK_UP;
if (buttonMap.ButtonDown(gamefunc_Look_Down))
input.actions |= SB_LOOK_DOWN;
inputBuffer->actions |= SB_LOOK_DOWN;
if (buttonMap.ButtonDown(gamefunc_Look_Left))
input.actions |= SB_LOOK_LEFT;
inputBuffer->actions |= SB_LOOK_LEFT;
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"
struct ControlInfo
struct HIDInput
{
float dx;
float dy;
float dz;
float dyaw;
float dpitch;
float droll;
float joyaxes[NUM_JOYAXIS];
float mouseturnx;
float mouseturny;
float mousemovex;
@ -50,7 +45,7 @@ public:
g_mousePos.Y += y;
}
void GetMouseDelta(ControlInfo* hidInput);
void GetMouseDelta(HIDInput* hidInput);
void ClearAllInput();
bool CheckAllInput()
@ -63,7 +58,6 @@ public:
extern InputState inputState;
ControlInfo CONTROL_GetInput();
int32_t handleevents(void);
enum GameFunction_t
@ -102,7 +96,7 @@ enum GameFunction_t
};
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 bool gamesetinput;
@ -116,6 +110,12 @@ inline float backendinputscale()
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.

View file

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

View file

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

View file

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

View file

@ -2574,7 +2574,7 @@ static void ConcussSprite(DBloodActor* source, DBloodActor* actor, const DVector
if (mass > 0)
{
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);
}
}

View file

@ -60,8 +60,8 @@ AISTATE zombie13AC2C = { kAiStateOther, 11, nStandClient, 0, entryEZombie, NULL,
void HackSeqCallback(int, DBloodActor* actor)
{
if (!actor->ValidateTarget(__FUNCTION__)) return;
auto target = actor->GetTarget();
if (!target) return;
DUDEINFO* pDudeInfo = getDudeInfo(actor->spr.type);
DUDEINFO* pDudeInfoT = getDudeInfo(target->spr.type);
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
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;
@ -439,14 +439,12 @@ void GameInterface::Ticker()
PLAYER* pPlayer = &gPlayer[myconnectindex];
// this must be done before the view is backed up.
pPlayer->Angles.resetRenderAngles();
// disable synchronised input if set by game.
resetForcedSyncInput();
for (int i = connecthead; i >= 0; i = connectpoint2[i])
{
gPlayer[i].Angles.resetCameraAngles();
viewBackupView(i);
playerProcess(&gPlayer[i]);
}

View file

@ -111,7 +111,6 @@ struct GameInterface : public ::GameInterface
void app_init() override;
void SerializeGameState(FSerializer& arc) override;
void loadPalette() override;
void clearlocalinputstate() override;
bool GenerateSavePic() override;
void FreeLevelData() override;
void FreeGameData() override;
@ -119,9 +118,7 @@ struct GameInterface : public ::GameInterface
void MenuOpened() override;
void MenuClosed() override;
bool CanSave() override;
std::pair<DVector3, DAngle> GetCoordinates() override;
void UpdateSounds() override;
void GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet = nullptr) override;
void Ticker() override;
void DrawBackground() 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;
DAngle playerPitchMin() override { return DAngle::fromDeg(54.575); }
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 SwitchCoopView() 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)
{
// 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;
if (cl_weaponsway)

View file

@ -31,20 +31,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
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()
{
if (gamestate != GS_LEVEL) return;

View file

@ -1499,20 +1499,6 @@ int ActionScan(PLAYER* pPlayer, HitInfo* out)
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)
{
// force synchronised input upon death.
setForcedSyncInput();
bool bSeqStat = playerSeqPlaying(pPlayer, 16);
DBloodActor* fragger = pPlayer->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;
}
pPlayer->Angles.doViewYaw(pInput->actions);
pPlayer->Angles.doViewYaw(pInput);
if (SyncInput())
{
pPlayer->actor->spr.Angles.Yaw += DAngle::fromDeg(pInput->avel);
}
pPlayer->Angles.doYawKeys(&pInput->actions);
pPlayer->Angles.doYawKeys(pInput);
if (!(pInput->actions & SB_JUMP))
pPlayer->cantJump = 0;
@ -1822,8 +1811,9 @@ void ProcessInput(PLAYER* pPlayer)
pPlayer->actor->spr.Angles.Pitch = DAngle::fromDeg(pInput->horz);
}
pPlayer->Angles.doPitchKeys(&pInput->actions, pInput->horz);
doslopetilting(pPlayer);
const int florhit = pPlayer->actor->hit.florhit.type;
pPlayer->Angles.doViewPitch(actor->xspr.height < 16 && (florhit == kHitSector || florhit == 0));
pPlayer->Angles.doPitchKeys(pInput);
pPlayer->slope = pPlayer->actor->spr.Angles.Pitch.Tan();
if (pInput->actions & SB_INVPREV)

View file

@ -309,9 +309,8 @@ void qavProcessTicker(QAV* const pQAV, int* duration, int* lastTick)
{
if (*duration > 0)
{
auto thisTick = I_GetTime(pQAV->ticrate);
auto numTicks = thisTick - (*lastTick);
if (numTicks)
const auto thisTick = I_GetTime(pQAV->ticrate);
if (const auto numTicks = thisTick - (*lastTick))
{
*lastTick = thisTick;
*duration -= pQAV->ticksPerFrame * numTicks;
@ -328,11 +327,15 @@ 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)
{
// Process if not paused.
// Process clock based on QAV's ticrate and last tick value.
if (!paused)
{
// Process clock based on QAV's ticrate and last tick value.
qavProcessTicker(pQAV, &pPlayer->qavTimer, &pPlayer->qavLastTick);
}
else
{
pPlayer->qavLastTick = I_GetTime(pQAV->ticrate);
}
if (pPlayer->weaponTimer == 0 && pPlayer->qavTimer == 0 && !ignoreWeaponTimer)
{
@ -350,12 +353,7 @@ void qavProcessTimer(PLAYER* const pPlayer, QAV* const pQAV, int* duration, doub
{
// Apply normal values.
*duration = pQAV->duration - pPlayer->qavTimer;
*interpfrac = !cl_interpolate || cl_capfps ? 1. : I_GetTimeFrac(pQAV->ticrate);
}
}
else
{
*interpfrac = 1.;
*interpfrac = !cl_interpolate || cl_capfps || paused ? 1. : I_GetTimeFrac(pQAV->ticrate);
}
}

View file

@ -582,7 +582,7 @@ void viewDrawScreen(bool sceneonly)
else interpfrac = 1.;
// update render angles.
pPlayer->Angles.updateRenderAngles(interpfrac);
pPlayer->Angles.updateCameraAngles(interpfrac);
if (cl_interpolate)
{
@ -774,13 +774,6 @@ bool GameInterface::GenerateSavePic()
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);
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;

View file

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

View file

@ -118,22 +118,6 @@ static int ccmd_spawn(CCmdFuncPtr parm)
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()
{
if (gamestate != GS_LEVEL) return;

View file

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

View file

@ -19,13 +19,14 @@
BEGIN_DUKE_NS
extern player_struct ps[MAXPLAYERS];
struct GameInterface : public ::GameInterface
{
const char* Name() override { return "Duke"; }
void app_init() override;
void loadPalette() override;
void SetupSpecialTextures(TilesetBuildInfo& info) override;
void clearlocalinputstate() override;
bool GenerateSavePic() override;
void PlayHudSound() override;
GameStats getStats() override;
@ -36,10 +37,9 @@ struct GameInterface : public ::GameInterface
FSavegameInfo GetSaveSig() override;
double SmallFontScale() override { return isRR() ? 0.5 : 1.; }
void SerializeGameState(FSerializer& arc) override;
std::pair<DVector3, DAngle> GetCoordinates() override;
void ExitFromMenu() 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 Startup() override;
void DrawBackground() override;
@ -51,7 +51,8 @@ struct GameInterface : public ::GameInterface
void NewGame(MapRecord* map, int skill, bool) 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;
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 SwitchCoopView() override;
void ToggleShowWeapon() override;

View file

@ -402,7 +402,6 @@ void GameInterface::app_init()
//Net_SendClientInfo();
setupbackdrop();
SetupGameButtons();
InitCheats();
checkcommandline();
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()
{
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.);
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,
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;
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);
break;
@ -621,7 +621,7 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor,
break;
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);
break;
@ -2268,7 +2268,6 @@ int ParseState::parse(void)
ps[g_p].wackedbyactor = nullptr;
ps[g_p].shield_amount = gs.max_armour_amount;
ps[g_p].dead_flag = 0;
ps[g_p].resurrected = false;
ps[g_p].pals.a = 0;
ps[g_p].footprintcount = 0;
ps[g_p].weapreccnt = 0;

View file

@ -70,7 +70,10 @@ void GameInterface::Ticker()
everyothertime++;
// 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.
resetForcedSyncInput();
@ -86,8 +89,6 @@ void GameInterface::Ticker()
movedummyplayers();//ST 13
for (int i = connecthead; i >= 0; i = connectpoint2[i])
{
if (playrunning())
{
auto p = &ps[i];
if (p->pals.a > 0)
@ -98,7 +99,6 @@ void GameInterface::Ticker()
fi.processinput(i);
fi.checksectors(i);
}
}
fi.think();

View file

@ -234,8 +234,7 @@ inline bool playrunning()
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->GetActor()->spr.pos.XY(), p->GetActor()->spr.Angles.Yaw, p->aim_mode == 0, canslopetilt, p->cursector);
p->Angles.doViewPitch(p->aim_mode == 0 && p->on_ground && p->cursector->lotag != ST_2_UNDERWATER);
}
//---------------------------------------------------------------------------
@ -354,4 +353,14 @@ inline void processinputvel(int snum)
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

View file

@ -44,9 +44,6 @@ EXTERN_CVAR(Float, m_yaw)
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.
@ -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.
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 (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->last_extra = p->GetActor()->spr.extra;
p->resurrected = true;
}
else if (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))
p->interface_toggle_flag = 0;
#ifndef __MOBILE__
else if (p->interface_toggle_flag == 0)
{
#else
//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.
if (paused) return;
@ -523,40 +535,9 @@ enum
enum
{
MAXVELMOTO = 120,
VEHICLETURN = 20
};
//---------------------------------------------------------------------------
//
// 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;
}
}
static constexpr float VEHICLETURN = (20.f * 360.f / 2048.f);
//---------------------------------------------------------------------------
//
@ -564,36 +545,34 @@ 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;
if (p->MotoSpeed == 0 || !p->on_ground)
{
resetTurnHeldAmt();
if (kbdLeft || hidInput->mouseturnx < 0 || hidInput->dyaw < 0)
if (p->vehTurnLeft)
{
p->TiltStatus -= (float)factor;
if (p->TiltStatus < -10)
p->TiltStatus = -10;
}
else if (kbdRight || hidInput->mouseturnx > 0 || hidInput->dyaw > 0)
else if (p->vehTurnRight)
{
p->TiltStatus += (float)factor;
if (p->TiltStatus > 10)
p->TiltStatus = 10;
}
}
else
else if (p->vehTurnLeft || p->vehTurnRight || p->moto_drink)
{
if (kbdLeft || kbdRight || p->moto_drink || hidInput->mouseturnx || hidInput->dyaw)
{
double const velScale = 3. / 10;
auto const baseVel = (buttonMap.ButtonDown(gamefunc_Move_Backward) || hidInput->dz < 0) && p->MotoSpeed <= 0 ? -VEHICLETURN : VEHICLETURN;
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 (kbdLeft || p->moto_drink < 0 || hidInput->mouseturnx < 0 || hidInput->dyaw < 0)
if (p->vehTurnLeft || p->moto_drink < 0)
{
p->TiltStatus -= (float)factor;
@ -604,15 +583,15 @@ static FAngle motoApplyTurn(player_struct* p, ControlInfo* const hidInput, bool
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.);
turnvel -= Sgn(baseVel) * sqrtf(abs(p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * -(hidInput->mouseturnx / factor) * (7.f / 20.f));
if (hidInput->dyaw < 0)
turnvel += (p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * hidInput->dyaw;
if (hidInput->joyaxes[JOYAXIS_Yaw] > 0)
turnvel += (p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * hidInput->joyaxes[JOYAXIS_Yaw];
updateTurnHeldAmt(factor);
}
if (kbdRight || p->moto_drink > 0 || hidInput->mouseturnx > 0 || hidInput->dyaw > 0)
if (p->vehTurnRight || p->moto_drink > 0)
{
p->TiltStatus += (float)factor;
@ -623,10 +602,10 @@ static FAngle motoApplyTurn(player_struct* p, ControlInfo* const hidInput, bool
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.);
turnvel += Sgn(baseVel) * sqrtf(abs(p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * (hidInput->mouseturnx / factor) * (7.f / 20.f));
if (hidInput->dyaw > 0)
turnvel += (p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * hidInput->dyaw;
if (hidInput->joyaxes[JOYAXIS_Yaw] < 0)
turnvel += (p->MotoSpeed > 0 ? baseVel : baseVel * velScale) * hidInput->joyaxes[JOYAXIS_Yaw];
updateTurnHeldAmt(factor);
}
@ -640,12 +619,11 @@ static FAngle motoApplyTurn(player_struct* p, ControlInfo* const hidInput, bool
else if (p->TiltStatus < 0)
p->TiltStatus += (float)factor;
}
}
if (fabs(p->TiltStatus) < factor)
p->TiltStatus = 0;
return FAngle::fromBuild(turnvel * factor);
return turnvel * factor;
}
//---------------------------------------------------------------------------
@ -654,19 +632,17 @@ 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;
if (p->MotoSpeed)
if (p->MotoSpeed && (p->vehTurnLeft || p->vehTurnRight || p->moto_drink))
{
if (kbdLeft || kbdRight || p->moto_drink || hidInput->mouseturnx || hidInput->dyaw)
{
double const velScale = !p->NotOnWater? 1. : 6. / 19.;
auto const baseVel = +VEHICLETURN * velScale;
const float velScale = !p->NotOnWater? 1.f : (6.f / 19.f);
const float baseVel = VEHICLETURN * velScale;
if (kbdLeft || p->moto_drink < 0 || hidInput->mouseturnx < 0 || hidInput->dyaw < 0)
if (p->vehTurnLeft || p->moto_drink < 0)
{
if (!p->NotOnWater)
{
@ -679,15 +655,15 @@ static FAngle boatApplyTurn(player_struct *p, ControlInfo* const hidInput, bool
turnvel -= isTurboTurnTime() ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx < 0)
turnvel -= Sgn(baseVel) * sqrt(abs(baseVel) * -(hidInput->mouseturnx / factor) * 2.);
turnvel -= Sgn(baseVel) * sqrtf(abs(baseVel) * -(hidInput->mouseturnx / factor) * (7.f / 20.f));
if (hidInput->dyaw < 0)
turnvel += baseVel * hidInput->dyaw;
if (hidInput->joyaxes[JOYAXIS_Yaw] > 0)
turnvel += baseVel * hidInput->joyaxes[JOYAXIS_Yaw];
updateTurnHeldAmt(factor);
}
if (kbdRight || p->moto_drink > 0 || hidInput->mouseturnx > 0 || hidInput->dyaw > 0)
if (p->vehTurnRight || p->moto_drink > 0)
{
if (!p->NotOnWater)
{
@ -700,10 +676,10 @@ static FAngle boatApplyTurn(player_struct *p, ControlInfo* const hidInput, bool
turnvel += isTurboTurnTime() ? baseVel : baseVel * velScale;
if (hidInput->mouseturnx > 0)
turnvel += Sgn(baseVel) * sqrt(abs(baseVel) * (hidInput->mouseturnx / factor) * 2.);
turnvel += Sgn(baseVel) * sqrtf(abs(baseVel) * (hidInput->mouseturnx / factor) * (7.f / 20.f));
if (hidInput->dyaw > 0)
turnvel += baseVel * hidInput->dyaw;
if (hidInput->joyaxes[JOYAXIS_Yaw] < 0)
turnvel += baseVel * hidInput->joyaxes[JOYAXIS_Yaw];
updateTurnHeldAmt(factor);
}
@ -717,21 +693,11 @@ static FAngle boatApplyTurn(player_struct *p, ControlInfo* const hidInput, bool
else if (p->TiltStatus < 0)
p->TiltStatus += (float)factor;
}
}
else if (!p->NotOnWater)
{
resetTurnHeldAmt();
if (p->TiltStatus > 0)
p->TiltStatus -= (float)factor;
else if (p->TiltStatus < 0)
p->TiltStatus += (float)factor;
}
if (fabs(p->TiltStatus) < factor)
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 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
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->vehTurnRight = kbdRight || hidInput->mouseturnx > 0 || hidInput->dyaw > 0;
p->vehTurnLeft = kbdLeft || hidInput->mouseturnx < 0 || hidInput->joyaxes[JOYAXIS_Yaw] > 0;
p->vehTurnRight = kbdRight || hidInput->mouseturnx > 0 || hidInput->joyaxes[JOYAXIS_Yaw] < 0;
if (p->OnBoat || !p->moto_underwater)
{
p->vehForwardScale = min((buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) + hidInput->dz, 1.f);
p->vehReverseScale = min(buttonMap.ButtonDown(gamefunc_Move_Backward) + -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->joyaxes[JOYAXIS_Forward], 1.f);
p->vehBraking = buttonMap.ButtonDown(gamefunc_Run);
}
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;
}
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);
loc.avel += input.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;
}
}
inputBuffer->fvel = clamp<float>((float)p->MotoSpeed, -(MAXVELMOTO >> 3), MAXVELMOTO) * (1.f / 40.f);
inputBuffer->avel += currInput->avel;
}
@ -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];
InputPacket input{};
processInputBits(p, hidInput);
if (isRRRA() && (p->OnMotorcycle || p->OnBoat))
{
processVehicleInput(p, hidInput, input, scaleAdjust);
processVehicleInput(p, hidInput, inputBuffer, currInput, scaleAdjust);
}
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 actor = p->GetActor();
// lock input when dead.
setForcedSyncInput();
if (p->dead_flag == 0)
{
if (actor->spr.pal != 1)
@ -726,7 +729,7 @@ void playerJump(int snum, double floorz, double ceilingz)
void player_struct::apply_seasick()
{
if (isRRRA() && SeaSick && (dead_flag == 0 || (dead_flag && resurrected)))
if (isRRRA() && SeaSick && (dead_flag == 0))
{
if (SeaSick < 250)
{
@ -958,6 +961,8 @@ bool movementBlocked(player_struct *p)
p->hard_landing ||
p->access_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()));
}

View file

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

View file

@ -2160,7 +2160,7 @@ static void movement(int snum, ESyncBits actions, sectortype* psect, double floo
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);
}
@ -3353,22 +3353,21 @@ void processinput_r(int snum)
p->spritebridge = 0;
shrunk = (pact->spr.scale.Y < 0.125);
double tempfz;
if (pact->clipdist == 16)
{
getzrange(p->GetActor()->getPosWithOffsetZ(), psectp, &ceilingz, chz, &floorz, clz, 10.1875, CLIPMASK0);
tempfz = getflorzofslopeptr(psectp, p->GetActor()->getPosWithOffsetZ());
}
else
{
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());
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)
psectlotag = 0;
@ -3501,6 +3500,7 @@ void processinput_r(int snum)
if (p->newOwner != nullptr)
{
setForcedSyncInput();
p->vel.X = p->vel.Y = 0;
pact->vel.X = 0;
@ -3518,7 +3518,10 @@ void processinput_r(int snum)
auto oldpos = p->GetActor()->opos;
if (p->on_crane != nullptr)
{
setForcedSyncInput();
goto HORIZONLY;
}
p->playerweaponsway(pact->vel.X);
@ -3560,13 +3563,14 @@ void processinput_r(int snum)
p->psectlotag = psectlotag;
//Do the quick lefts and rights
p->Angles.doViewYaw(actions);
p->Angles.doViewYaw(&p->sync);
if (movementBlocked(p))
{
doubvel = 0;
p->vel.X = 0;
p->vel.Y = 0;
setForcedSyncInput();
}
else if (SyncInput())
{
@ -3577,7 +3581,7 @@ void processinput_r(int snum)
p->GetActor()->spr.Angles.Yaw += p->adjustavel(PlayerInputAngVel(snum));
}
p->Angles.doYawKeys(&actions);
p->Angles.doYawKeys(&p->sync);
purplelavacheck(p);
if (p->spritebridge == 0 && pact->insector())
@ -3818,7 +3822,7 @@ HORIZONLY:
}
// RBG***
SetActor(pact, p->GetActor()->spr.pos);
SetActor(pact, pact->spr.pos);
if (psectlotag == 800 && (!isRRRA() || !p->lotag800kill))
{
@ -3915,12 +3919,17 @@ HORIZONLY:
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->Angles.doPitchKeys(&actions, GetPlayerHorizon(snum).Sgn());
p->Angles.doPitchKeys(&p->sync);
p->checkhardlanding();

View file

@ -91,7 +91,6 @@ void resetplayerstats(int snum)
gFullMap = 0;
p->dead_flag = 0;
p->resurrected = false;
p->wackedbyactor = nullptr;
p->falling_counter = 0;
p->quick_kick = 0;
@ -503,11 +502,10 @@ void resetpspritevars(int g, const DVector3& startpos, const DAngle startang)
int aimmode[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);
newActor->spr.Angles.Pitch = DAngle::fromDeg(-17.354);
newActor->viewzoffset = -gs.playerheight;
newActor->backuploc();
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];
// update render angles.
p->Angles.updateRenderAngles(interpfrac);
p->Angles.updateCameraAngles(interpfrac);
if (automapMode == am_full || !p->insector())
return;

View file

@ -151,7 +151,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
.Array("weaprecs", w.weaprecs, w.weapreccnt)
("interface_toggle_flag", w.interface_toggle_flag)
("dead_flag", w.dead_flag)
("resurrected", w.resurrected)
("show_empty_weapon", w.show_empty_weapon)
("scuba_amount", w.scuba_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;
bool resurrected;
// 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.
int stairs;
@ -347,6 +345,11 @@ struct player_struct
{
bobpos = GetActor()->spr.pos.XY();
}
bool centeringView()
{
return (sync.actions & SB_CENTERVIEW) && abs(GetActor()->spr.Angles.Pitch.Degrees()) > 2.2370;
}
};
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, max_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, detonate_count)
//DEFINE_FIELD_X(DukePlayer, player_struct, noise.X)

View file

@ -27,10 +27,16 @@ BEGIN_PS_NS
// anims
enum
{
kAnimFlag1 = (1 << 2),
kAnimLoop = (1 << 4)
};
void InitAnims();
void DestroyAnim(DExhumedActor* nAnim);
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 BuildExplosion(DExhumedActor* actor);
void BuildSplash(DExhumedActor* actor, sectortype* pSector);

View file

@ -54,6 +54,30 @@ void InitAnims()
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)
{
if (pActor)

View file

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

View file

@ -56,10 +56,6 @@ enum {
kSectLava = 0x4000,
};
extern DVector3 initpos;
extern DAngle inita;
extern sectortype* initsectp;
extern int nCurChunkNum;
// 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 "engine.h"
#include "exhumed.h"
#include "aistuff.h"
#include "sequence.h"
#include "names.h"
#include "player.h"
@ -66,7 +67,6 @@ IMPLEMENT_POINTERS_END
size_t MarkMove();
size_t MarkBullets();
size_t MarkInput();
size_t MarkItems();
size_t MarkLighting();
size_t MarkObjects();
@ -80,7 +80,6 @@ size_t MarkRunlist();
static void markgcroots()
{
MarkBullets();
MarkInput();
MarkItems();
MarkLighting();
MarkObjects();
@ -103,8 +102,6 @@ void InitCheats();
int EndLevel = 0;
InputPacket localInput;
////////
void ResetEngine()
@ -151,8 +148,6 @@ int nEnergyTowers = 0;
int nCfgNetPlayers = 0;
int lLocalCodes = 0;
bool bCoordinates = false;
int nNetTime = -1;
@ -375,28 +370,44 @@ void GameInterface::Ticker()
}
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.
PlayerList[nLocalPlayer].Angles.resetRenderAngles();
UpdatePlayerSpriteAngle(&PlayerList[nLocalPlayer]);
pPlayer->Angles.resetCameraAngles();
// disable synchronised input if set by game.
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++)
{
// Velocities are stored as Q14.18
lPlayerVel += inputvect;
lPlayerVel *= 0.953125;
pPlayer->vel += inputvect;
pPlayer->vel *= 0.953125;
}
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;
for (i = 6; i > 0; i--)
@ -404,16 +415,16 @@ void GameInterface::Ticker()
nItem--;
if (nItem < 0) nItem = 5;
if (PlayerList[nLocalPlayer].items[nItem] != 0)
if (pPlayer->items[nItem] != 0)
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;
for (i = 6; i > 0; i--)
@ -421,57 +432,57 @@ void GameInterface::Ticker()
nItem++;
if (nItem == 6) nItem = 0;
if (PlayerList[nLocalPlayer].items[nItem] != 0)
if (pPlayer->items[nItem] != 0)
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++)
{
if (localInput.isItemUsed(i))
if (pInput.isItemUsed(i))
{
localInput.clearItemUsed(i);
if (PlayerList[nLocalPlayer].items[i] > 0)
pInput.clearItemUsed(i);
if (pPlayer->items[i] > 0)
{
if (nItemMagic[i] <= PlayerList[nLocalPlayer].nMagic)
if (nItemMagic[i] <= pPlayer->nMagic)
{
sPlayerInput[nLocalPlayer].nItem = i;
pPlayer->nCurrentItem = i;
break;
}
}
}
}
auto currWeap = PlayerList[nLocalPlayer].nCurrentWeapon;
int weap2 = localInput.getNewWeapon();
auto currWeap = pPlayer->nCurrentWeapon;
int weap2 = pInput.getNewWeapon();
if (weap2 == WeaponSel_Next)
{
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++;
if (newWeap > 6) newWeap = 0;
}
localInput.setNewWeapon(newWeap + 1);
pInput.setNewWeapon(newWeap + 1);
}
else if (weap2 == WeaponSel_Prev)
{
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--;
}
localInput.setNewWeapon(newWeap + 1);
pInput.setNewWeapon(newWeap + 1);
}
else if (weap2 == WeaponSel_Alt)
{
@ -479,21 +490,10 @@ void GameInterface::Ticker()
}
// make weapon selection persist until it gets used up.
int weap = sPlayerInput[nLocalPlayer].getNewWeapon();
if (weap2 <= 0 || weap2 > 7) sPlayerInput[nLocalPlayer].SetNewWeapon(weap);
int weap = pInput.getNewWeapon();
if (weap2 <= 0 || weap2 > 7) pInput.setNewWeapon(weap);
auto oldactions = sPlayerInput[nLocalPlayer].actions;
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;
pPlayer->pTarget = Ra[nLocalPlayer].pTarget = bestTarget;
PlayClock += 4;
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;
}
UnlinkIgnitedAnim(actor);
actor->Destroy();
}
@ -691,13 +692,6 @@ bool GameInterface::CanSave()
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 "serialize_obj.h"
#include "texturemanager.h"
#include "player.h"
BEGIN_PS_NS
@ -211,7 +212,6 @@ struct GameInterface : public ::GameInterface
const char* Name() override { return "Exhumed"; }
void app_init() override;
void SetupSpecialTextures(TilesetBuildInfo& info) override;
void clearlocalinputstate() override;
void loadPalette() override;
bool GenerateSavePic() override;
void MenuOpened() override;
@ -225,7 +225,6 @@ struct GameInterface : public ::GameInterface
void DrawBackground() override;
void Render() override;
//void DrawWeapons() override;
void GetInput(ControlInfo* const hidInput, double const scaleAdjust, InputPacket* packet = nullptr) override;
void Startup() override;
const char* GenericCheat(int player, int cheat) 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;
DAngle playerPitchMin() 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 processSprites(tspriteArray& tsprites, const DVector3& view, DAngle viewang, double interpfrac) override;
int GetCurrentSkill() override;
std::pair<DVector3, DAngle> GetCoordinates() override;
void StartSoundEngine() override;
::GameStats getStats() override;

View file

@ -838,9 +838,9 @@ loc_flag:
nHeight += h;
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.
assert(t->sector());
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];
int8_t nShade = initsectp->ceilingshade;
int8_t nShade = PlayerList[nLocalPlayer].pActor->sector()->ceilingshade;
int nDouble = PlayerList[nLocalPlayer].nDouble;
int nPal = kPalNormal;

View file

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

View file

@ -25,92 +25,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
BEGIN_PS_NS
PlayerInput sPlayerInput[kMaxPlayers];
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
size_t MarkInput()
{
for (auto& p : sPlayerInput)
{
GC::Mark(p.pTarget);
}
return kMaxPlayers;
}
void ClearSpaceBar(int nPlayer)
{
sPlayerInput[nPlayer].actions &= SB_OPEN;
PlayerList[nPlayer].input.actions &= SB_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

View file

@ -29,36 +29,7 @@ enum {
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);
int GetLocalInput();
extern PlayerInput sPlayerInput[];
extern InputPacket localInput;
extern int lLocalCodes;
END_PS_NS

View file

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

View file

@ -936,17 +936,6 @@ void MoveSector(sectortype* pSector, DAngle nAngle, DVector2& nVel)
}
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)
{
for (int i = 0; i < kMaxChannels; i++)
@ -81,13 +62,17 @@ static int osdcmd_doors(CCmdFuncPtr parm)
static int osdcmd_spawn(CCmdFuncPtr parm)
{
auto pActor = PlayerList[nLocalPlayer].pActor;
if (parm->numparms != 1) return CCMD_SHOWHELP;
if (!pActor) return CCMD_SHOWHELP;
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);
else if (!stricmp(c, "spider")) BuildSpider(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, "lava")) BuildLava(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.pPlayerFloorSprite);
GC::Mark(p.pPlayerGrenade);
GC::Mark(p.pTarget);
}
GC::MarkArray(nNetStartSprite, kMaxPlayers);
return 5 * kMaxPlayers;
return 6 * kMaxPlayers;
}
//---------------------------------------------------------------------------
@ -437,8 +438,7 @@ void RestartPlayer(int nPlayer)
plr->ototalvel = plr->totalvel = 0;
memset(&sPlayerInput[nPlayer], 0, sizeof(PlayerInput));
sPlayerInput[nPlayer].nItem = -1;
PlayerList[nPlayer].nCurrentItem = -1;
plr->nDeathType = 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)
{
int nPlayer = RunData[ev->nRun].nObjIndex;
@ -860,7 +849,7 @@ bool CheckMovingBlocks(int nPlayer, Collision& nMove, DVector3& spr_pos, sectort
{
PlayerList[nPlayer].pPlayerPushSect = sect;
DVector2 vel = sPlayerInput[nPlayer].vel;
DVector2 vel = PlayerList[nPlayer].vel;
auto nMyAngle = vel.Angle().Normalized360();
setsectinterpolate(sect);
@ -911,12 +900,12 @@ void AIPlayer::Tick(RunListEvent* ev)
int nAction = 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);
sPlayerInput[nPlayer].nItem = -1;
UseItem(nPlayer, PlayerList[nPlayer].nCurrentItem);
PlayerList[nPlayer].nCurrentItem = -1;
}
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:
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);
UpdatePlayerSpriteAngle(&PlayerList[nPlayer]);
PlayerList[nPlayer].Angles.doYawKeys(&PlayerList[nLocalPlayer].input);
// player.zvel is modified within Gravity()
double zVel = pPlayerActor->vel.Z;
@ -1011,7 +999,7 @@ void AIPlayer::Tick(RunListEvent* ev)
auto playerPos = pPlayerActor->spr.pos.XY();
DVector2 vect = sPlayerInput[nPlayer].vel;
DVector2 vect = PlayerList[nPlayer].vel;
double zz = pPlayerActor->vel.Z;
if (pPlayerActor->vel.Z > 32)
@ -1079,7 +1067,7 @@ void AIPlayer::Tick(RunListEvent* ev)
pPlayerActor->spr.Angles = DRotator(nullAngle, GetAngleToSprite(pPlayerActor, pSpiritSprite), nullAngle);
pPlayerActor->backupang();
sPlayerInput[nPlayer].vel.Zero();
PlayerList[nPlayer].vel.Zero();
pPlayerActor->vel.Zero();
if (nFreeze < 1)
@ -1223,7 +1211,7 @@ sectdone:
int var_5C = pViewSect->Flag & kSectUnderwater;
auto actions = sPlayerInput[nPlayer].actions;
auto actions = PlayerList[nPlayer].input.actions;
// loc_1AEF5:
if (PlayerList[nPlayer].nHealth > 0)
@ -2433,7 +2421,7 @@ sectdone:
// loc_1BE70:
// 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)
{
@ -2477,12 +2465,12 @@ sectdone:
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->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)
{
PlayerList[nPlayer].nThrust.Zero();
@ -2629,7 +2609,7 @@ sectdone:
{
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);
}

View file

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

View file

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

View file

@ -196,7 +196,7 @@ void DoSpiritHead()
static int dimSectCount = 0;
auto pSpiritSpr = pSpiritSprite;
sPlayerInput[0].actions |= SB_CENTERVIEW;
PlayerList[0].input.actions |= SB_CENTERVIEW;
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;
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;
}
else

View file

@ -191,9 +191,9 @@ void BuildSnake(int nPlayer, double zVal)
if (hitactor && hitactor->spr.statnum >= 90 && hitactor->spr.statnum <= 199) {
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();

View file

@ -433,9 +433,9 @@ void EXSoundEngine::CalcPosVel(int type, const void* source, const float pt[3],
Snake* pSnake = &SnakeList[nSnakeCam];
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);
@ -500,6 +500,8 @@ void GameInterface::UpdateSounds()
if (nFreeze)
return;
const auto pActor = PlayerList[nLocalPlayer].pActor;
DVector3 pos;
DAngle ang;
if (nSnakeCam > -1)
@ -508,10 +510,10 @@ void GameInterface::UpdateSounds()
pos = pSnake->pSprites[0]->spr.pos;
ang = pSnake->pSprites[0]->spr.Angles.Yaw;
}
else
else if (pActor)
{
pos = initpos;
ang = inita;
pos = pActor->spr.pos;
ang = pActor->spr.Angles.Yaw;
}
SoundListener listener;
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;
// update render angles.
pPlayer->Angles.updateRenderAngles(interpfrac);
UpdatePlayerSpriteAngle(pPlayer);
pPlayer->Angles.updateCameraAngles(interpfrac);
if (nSnakeCam >= 0 && !sceneonly)
{
@ -250,6 +249,8 @@ void DrawView(double interpfrac, bool sceneonly)
}
}
const auto ampos = nCamerapos.XY();
if (nSnakeCam >= 0 && !sceneonly)
{
nCameraangles.Pitch = nullAngle;
@ -340,12 +341,6 @@ void DrawView(double interpfrac, bool sceneonly)
if (ang2.Degrees() < 0)
ang2 = -ang2;
if (ang2 > mapangle(10))
{
inita -= ang2 * (1. / 8.);
return;
}
if (bSubTitles)
{
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

View file

@ -312,10 +312,13 @@ void DoShadows(tspriteArray& tsprites, tspritetype* tsp, double viewz)
scale = tsp->scale;
}
loz = DoShadowFindGroundPoint(tsp);
if (ownerActor->user.lowActor && (ownerActor->user.lowActor->spr.cstat & (CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR)))
{
loz = ownerActor->user.loz;
if (ownerActor->user.lowActor)
{
if (!(ownerActor->user.lowActor->spr.cstat & (CSTAT_SPRITE_ALIGNMENT_WALL | CSTAT_SPRITE_ALIGNMENT_FLOOR)))
{
loz = DoShadowFindGroundPoint(tsp);
}
}
// 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))
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))
{
@ -800,7 +803,7 @@ static void analyzesprites(tspriteArray& tsprites, const DVector3& viewpos, doub
}
tsp->pos = pos;
tsp->Angles.Yaw = pp->siang;
tsp->Angles.Yaw = pp->Angles.getCameraAngles().Yaw;
//continue;
}
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)
{
const int Y_STEP = 7;
@ -1239,10 +1229,11 @@ void drawscreen(PLAYER* pp, double interpfrac, bool sceneonly)
}
// update render angles.
pp->Angles.updateRenderAngles(interpfrac);
pp->Angles.updateCameraAngles(interpfrac);
// Get initial player position, interpolating if required.
DVector3 tpos = camerapp->actor->getRenderPos(interpfrac);
DVector2 ampos = tpos.XY();
DRotator tangles = camerapp->Angles.getRenderAngles(interpfrac);
sectortype* tsect = camerapp->cursector;
@ -1260,7 +1251,6 @@ void drawscreen(PLAYER* pp, double interpfrac, bool sceneonly)
}
pp->si = tpos.plusZ(-pp->actor->getOffsetZ());
pp->siang = tangles.Yaw;
QuakeViewChange(camerapp, tpos, tangles.Yaw);
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;
@ -1455,7 +1445,7 @@ bool GameInterface::DrawAutomapPlayer(const DVector2& mxy, const DVector2& cpos,
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);
// This repeat scale is correct.

View file

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

View file

@ -567,8 +567,6 @@ enum
PF_TANK = (BIT(29)), // Doin the tank thang
PF_WEAPON_DOWN = (BIT(31)),
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_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
void ScreenCaptureKeys(void); // draw.c
void computergetinput(int snum,InputPacket *syn); // jplayer.c
void SetupMirrorTiles(void); // rooms.c
bool FAF_Sector(sectortype* sect); // rooms.c
double GetZadjustment(sectortype* sect,short hitag); // rooms.c
@ -1663,53 +1659,6 @@ extern int ChopTics;
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
#include "swactor.h"
@ -1744,7 +1693,6 @@ struct PLAYER
double circle_camera_dist;
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!
@ -1892,11 +1840,6 @@ struct PLAYER
uint8_t WpnReloadState;
double getViewHeightDiff()
{
return actor->viewzoffset + height;
}
void posZset(const double val)
{
actor->spr.pos.Z = val - actor->viewzoffset;
@ -1906,6 +1849,52 @@ struct PLAYER
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
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
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)
{
PlayClock = 0;
@ -80,13 +70,13 @@ enum
//
//---------------------------------------------------------------------------
static void processWeapon(PLAYER* const pp)
void processWeapon(PLAYER* const pp)
{
DSWActor* plActor = pp->actor;
if (plActor == nullptr) return;
int i;
if (loc.getNewWeapon() == WeaponSel_Next)
if (pp->input.getNewWeapon() == WeaponSel_Next)
{
int next_weapon = plActor->user.WeaponNum + 1;
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 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;
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

View file

@ -385,11 +385,9 @@ void so_updateinterpolations(void) // Stick at beginning of domovethings
for (sop = SectorObject, interp = so_interpdata;
sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++)
{
bool skip = !SyncInput() && (sop->track == SO_TURRET);
if (SO_EMPTY(sop) || skip)
if (SO_EMPTY(sop))
continue;
if (interp->tic < interp->lasttic)
interp->tic += synctics;
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;
sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++)
{
bool skip = !SyncInput() && (sop->track == SO_TURRET);
if (SO_EMPTY(sop) || skip)
if (SO_EMPTY(sop))
continue;
for (i = 0; i < interp->numinterpolations; i++)
{
auto actorofang = interp->data[i].actorofang;
@ -472,8 +468,7 @@ void so_dointerpolations(double interpfrac) // Stick at beg
for (sop = SectorObject, interp = so_interpdata;
sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++)
{
bool skip = !SyncInput() && (sop->track == SO_TURRET);
if (SO_EMPTY(sop) || skip)
if (SO_EMPTY(sop))
continue;
// 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;
sop < &SectorObject[MAX_SECTOR_OBJECTS]; sop++, interp++)
{
bool skip = !SyncInput() && (sop->track == SO_TURRET);
if (SO_EMPTY(sop) || skip)
if (SO_EMPTY(sop))
continue;
for (i = 0, data = interp->data; i < interp->numinterpolations; i++, data++)

View file

@ -74,7 +74,6 @@ struct gNET
extern gNET gNet;
void UpdateInputs(void);
void InitNetVars(void);
void InitTimingVars(void);
void InitNetPlayerOptions(void);
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)
{
char base[80];

View file

@ -152,7 +152,6 @@ void DoPlayerFly(PLAYER* pp);
void DoPlayerBeginClimb(PLAYER* pp);
void DoPlayerClimb(PLAYER* pp);
void DoPlayerBeginDie(PLAYER* pp);
void DoPlayerDie(PLAYER* pp);
// void DoPlayerBeginOperateBoat(PLAYER* pp);
void DoPlayerBeginOperateVehicle(PLAYER* pp);
void DoPlayerBeginOperate(PLAYER* pp);
@ -180,6 +179,7 @@ int GetOverlapSector2(const DVector2& pos, sectortype** over, sectortype** under
void PlayerToRemote(PLAYER* pp);
void PlayerRemoteInit(PLAYER* pp);
void PlayerSpawnPosition(PLAYER* pp);
void processWeapon(PLAYER* const pp);
extern short target_ang;
@ -1491,7 +1491,7 @@ void DoPlayerSetWadeDepth(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)
@ -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;
if (sop->drive_angspeed)
{
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
{
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))
{
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;
SECTOR_OBJECT* sop = pp->sop;
@ -1608,18 +1608,18 @@ void DoPlayerTurnTurret(PLAYER* pp, DAngle& plyaw, float avel)
if (sop->drive_angspeed)
{
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
{
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)
{
@ -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)
{
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);
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));
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(canslopetilt, pp->Flags & PF_CLIMBING);
}
//---------------------------------------------------------------------------
@ -2030,18 +2030,14 @@ void DoPlayerMove(PLAYER* pp)
SlipSlope(pp);
pp->Angles.doViewYaw(pp->input.actions);
pp->Angles.doViewYaw(&pp->input);
if (!SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_TURN_GENERAL);
}
else
if (SyncInput())
{
pp->actor->spr.Angles.Yaw += DAngle::fromDeg(pp->input.avel);
}
pp->Angles.doYawKeys(&pp->input.actions);
pp->Angles.doYawKeys(&pp->input);
UpdatePlayerSpriteAngle(pp);
pp->lastcursector = pp->cursector;
@ -2160,17 +2156,13 @@ void DoPlayerMove(PLAYER* pp)
DoPlayerSetWadeDepth(pp);
if (!SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_AIM);
}
else
if (SyncInput())
{
//Set pitch directly
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);
@ -2588,9 +2580,6 @@ void DoPlayerMoveVehicle(PLAYER* pp)
PlaySOsound(pp->sop->mid_sector,SO_IDLE_SOUND);
}
// force synchronised input here for now.
setForcedSyncInput();
if (PLAYER_MOVING(pp) == 0)
pp->Flags &= ~(PF_PLAYER_MOVED);
else
@ -2702,14 +2691,8 @@ void DoPlayerMoveVehicle(PLAYER* pp)
}
else
{
if (!SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_TURN_VEHICLE);
}
else
{
DoPlayerTurnVehicle(pp, pp->actor->spr.Angles.Yaw, pp->input.avel, zz, floordist);
}
setForcedSyncInput();
DoPlayerTurnVehicle(pp, zz, floordist);
auto save_cstat = plActor->spr.cstat;
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());
pp->cursector = save_sect; // for speed
if (!SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_AIM);
}
else
if (SyncInput())
{
//Set pitch directly
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);
@ -2781,31 +2760,21 @@ void DoPlayerMoveTurret(PLAYER* pp)
PlaySOsound(pp->sop->mid_sector, SO_IDLE_SOUND);
}
if (!SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_TURN_TURRET);
}
else
{
DoPlayerTurnTurret(pp, pp->actor->spr.Angles.Yaw, pp->input.avel);
}
setForcedSyncInput();
DoPlayerTurnTurret(pp);
if (PLAYER_MOVING(pp) == 0)
pp->Flags &= ~(PF_PLAYER_MOVED);
else
pp->Flags |= (PF_PLAYER_MOVED);
if (!SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_AIM);
}
else
if (SyncInput())
{
//Set pitch directly
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);
}
@ -3398,17 +3367,13 @@ void DoPlayerClimb(PLAYER* pp)
// setsprite to players location
ChangeActorSect(pp->actor, pp->cursector);
if (!SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_AIM);
}
else
if (SyncInput())
{
//Set pitch directly
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);
@ -5914,6 +5879,7 @@ void DoPlayerBeginDie(PLAYER* pp)
pp->Flags |= (PF_DEAD);
plActor->user.Flags &= ~(SPR_BOUNCE);
pp->Flags &= ~(PF_HEAD_CONTROL);
setForcedSyncInput();
}
//---------------------------------------------------------------------------
@ -6005,15 +5971,8 @@ void DoPlayerDeathFollowKiller(PLAYER* pp)
// allow turning
if (pp->Flags & (PF_DEAD_HEAD|PF_HEAD_CONTROL))
{
if (!SyncInput())
{
pp->Flags2 |= (PF2_INPUT_CAN_TURN_GENERAL);
}
else
{
pp->actor->spr.Angles.Yaw += DAngle::fromDeg(pp->input.avel);
}
UpdatePlayerSpriteAngle(pp);
}
@ -6714,14 +6673,12 @@ void MoveSkipSavePos(void)
MoveSkip4 = (MoveSkip4 + 1) & 3;
MoveSkip2 ^= 1;
// this must be done before the view is backed up.
Player[myconnectindex].Angles.resetRenderAngles();
// Save off player
TRAVERSE_CONNECT(pnum)
{
pp = Player + pnum;
pp->Angles.resetCameraAngles();
pp->actor->backuploc();
pp->obob_z = pp->bob_z;
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
if (numplayers <= 1 && PlayerTrackingMode && pnum == screenpeek && screenpeek != myconnectindex)
{
@ -7010,18 +6970,13 @@ void domovethings(void)
{
WeaponOperate(pp);
PlayerOperateEnv(pp);
resetForcedSyncInput();
}
// do for moving sectors
DoPlayerSectorUpdatePreMove(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.
const auto velvect = DVector2(pp->input.fvel, pp->input.svel).Rotated(pp->actor->spr.Angles.Yaw);
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, siy)
//DEFINE_FIELD_X(SWPlayer, PLAYER, siz)
DEFINE_FIELD_X(SWPlayer, PLAYER, siang)
//DEFINE_FIELD_X(SWPlayer, PLAYER, xvect)
//DEFINE_FIELD_X(SWPlayer, PLAYER, yvect)
//DEFINE_FIELD_X(SWPlayer, PLAYER, oxvect)

View file

@ -125,7 +125,7 @@ void DoPlayer(void);
void domovethings(void);
void InitAllPlayers(void);
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 DoPlayerNightVisionPalette(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)
("siy", w.si.Y)
("siz", w.si.Z)
("siang", w.siang)
("xvect", w.vect.X)
("yvect", w.vect.Y)
("friction", w.friction)
@ -1163,7 +1162,6 @@ void GameInterface::SerializeGameState(FSerializer& arc)
InitTimingVars();
PlayClock = SavePlayClock;
defineSky(nullptr, pskybits_override, nullptr, 0, parallaxyscale_override / 8192.f);
InitNetVars();
screenpeek = myconnectindex;

View file

@ -688,6 +688,9 @@ class BloodStatusBar : RazeStatusBar
}
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 total = 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.actor.PlayActorSound("CRANEGRAB");
plr.settargetangle(self.angle + 180);
Raze.forceSyncInput();
}
else
{

View file

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

View file

@ -303,8 +303,6 @@ struct DukePlayer native
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.
// Items were reordered by size.
native int stairs;

View file

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

View file

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

View file

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