Fixed spectator inputs getting stuck and physics being run twice, due to the recent changes to SV_RunClientCommand.
This commit is contained in:
parent
534b249ac4
commit
2c5bf43c58
9 changed files with 109 additions and 112 deletions
Binary file not shown.
|
@ -276,20 +276,22 @@ NSView::UpdateView(void)
|
|||
/* after predraws we can act upon their new positions */
|
||||
switch (GetViewMode()) {
|
||||
case VIEWMODE_FPS:
|
||||
cl.UpdateAliveCam();
|
||||
|
||||
if (Client_InIntermission()) {
|
||||
cl.UpdateIntermissionCam();
|
||||
} else {
|
||||
if (Client_IsDead(pl)) {
|
||||
SetAFOV(cvar("fov"));
|
||||
SetSensitivity(1.0f);
|
||||
pl.UpdateDeathcam();
|
||||
} else {
|
||||
print("alive\n");
|
||||
SetAFOV(cvar("fov") * pl.viewzoom);
|
||||
SetSensitivity(pl.viewzoom);
|
||||
cl.UpdateAliveCam();
|
||||
StairSmooth();
|
||||
View_DrawViewModel();
|
||||
}
|
||||
}
|
||||
|
||||
StairSmooth();
|
||||
SetAFOV(cvar("fov") * pl.viewzoom);
|
||||
SetSensitivity(pl.viewzoom);
|
||||
|
||||
if (Client_IsDead(pl))
|
||||
pl.UpdateDeathcam();
|
||||
else
|
||||
View_DrawViewModel();
|
||||
break;
|
||||
case VIEWMODE_THIRDPERSON:
|
||||
break;
|
||||
|
|
|
@ -245,13 +245,6 @@ View_DrawViewModel(void)
|
|||
Viewmodel_CalcBob();
|
||||
Viewmodel_ApplyBob(m_eViewModel);
|
||||
Viewmodel_ApplyBob(m_eViewModelL);
|
||||
|
||||
/* view roll */
|
||||
if (pl.movetype == MOVETYPE_WALK) {
|
||||
Camera_StrafeRoll(view_angles);
|
||||
Camera_RunBob(view_angles);
|
||||
setproperty(VF_ANGLES, view_angles + pl.punchangle);
|
||||
}
|
||||
} else {
|
||||
m_eViewModelL.origin = pl.m_xrInputLeft.GetOrigin();
|
||||
m_eViewModel.origin = pl.m_xrInputRight.GetOrigin();
|
||||
|
|
|
@ -248,30 +248,13 @@ void
|
|||
SV_RunClientCommand(void)
|
||||
{
|
||||
NSClient cl = (NSClient)self;
|
||||
cl.SharedInputFrame();
|
||||
cl.ServerInputFrame();
|
||||
|
||||
if (self.classname != "player") {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef BOT_INCLUDED
|
||||
/* wait a few seconds, as we may not have been spawned yet */
|
||||
if (clienttype(self) == CLIENTTYPE_BOT) {
|
||||
((bot)self).RunAI();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!Plugin_RunClientCommand()) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* the last thing that happens, so that the game can intercept
|
||||
input globals beforehand */
|
||||
if (self.classname == "player") {
|
||||
player pl = (player)self;
|
||||
pl.Physics_Run();
|
||||
}
|
||||
cl.SharedInputFrame();
|
||||
cl.ServerInputFrame();
|
||||
}
|
||||
|
||||
/** Any 'cmd' from the client get sent here and handled.
|
||||
|
|
|
@ -25,7 +25,7 @@ NSClient:NSNavAI
|
|||
public:
|
||||
void NSClient(void);
|
||||
|
||||
/** Called to deal with the final input handling of the client. */
|
||||
/** Called within the class to deal with the final input handling of the client. */
|
||||
virtual void ProcessInput(void);
|
||||
/** Run once, every frame, before physics are run on the player. */
|
||||
virtual void PreFrame(void);
|
||||
|
@ -39,7 +39,7 @@ public:
|
|||
virtual bool IsDead(void);
|
||||
/** Returns if we're a player. That is a type of client that is built on top of NSClientPlayer. */
|
||||
virtual bool IsPlayer(void);
|
||||
/** Like ClientInputFrame and ServerInputFrame, but run on both client and server at the same time. It is run before ClientInputFrame and ServerInputFrame. */
|
||||
/** Like ClientInputFrame and ServerInputFrame, but run on both client and server at the same time. It is run before ClientInputFrame and ServerInputFrame. When overriding, Make sure to call the super method to enable Nuclide to handle spectator controls properly. */
|
||||
virtual void SharedInputFrame(void);
|
||||
|
||||
/* overrides */
|
||||
|
@ -49,13 +49,13 @@ public:
|
|||
/** Client: Called on the client to give a chance to override input_* variables before networking them takes place. */
|
||||
virtual void ClientInputFrame(void);
|
||||
|
||||
/** Client: Called every single client frame when this client is alive */
|
||||
/** Client: Called every single client frame when this client is alive. You are expected to manipulate the g_view global here, which is of type NSView. */
|
||||
virtual void UpdateAliveCam(void);
|
||||
|
||||
/** Client: Called every single client frame when this client is dead */
|
||||
/** Client: Called every single client frame when this client is dead. You are expected to manipulate the g_view global here, which is of type NSView. */
|
||||
virtual void UpdateDeathcam(void);
|
||||
|
||||
/** Client: Called every single client frame during intermission */
|
||||
/** Client: Called every single client frame during intermission. You are expected to manipulate the g_view global here, which is of type NSView. */
|
||||
virtual void UpdateIntermissionCam(void);
|
||||
|
||||
/* overrides */
|
||||
|
@ -63,7 +63,7 @@ public:
|
|||
#endif
|
||||
|
||||
#ifdef SERVER
|
||||
/** Server: This is where the input* variables arrive after sending them out from the client (see ClientInputFrame).*/
|
||||
/** Server: This is where the input* variables arrive after sending them out from the client (see ClientInputFrame). This is also where we will instruct the server to run physics on the client. */
|
||||
virtual void ServerInputFrame(void);
|
||||
|
||||
/** Set the value of an InfoKey. */
|
||||
|
|
|
@ -45,6 +45,7 @@ public:
|
|||
virtual bool IsRealSpectator(void);
|
||||
virtual bool IsDead(void);
|
||||
virtual bool IsPlayer(void);
|
||||
virtual void SharedInputFrame(void);
|
||||
|
||||
/** Empty & shared between Client and Server. This is run on every player, every frame, to update their animation cycle. */
|
||||
virtual void UpdatePlayerAnimation(float);
|
||||
|
|
|
@ -21,6 +21,17 @@ NSClientPlayer::NSClientPlayer(void)
|
|||
vehicle = __NULL__;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NSClientPlayer::SharedInputFrame(void)
|
||||
{
|
||||
/* if spectator, we want to make sure we call this */
|
||||
if (!Client_InIntermission() && IsFakeSpectator()) {
|
||||
NSClientSpectator::SharedInputFrame();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NSClientPlayer::IsRealSpectator(void)
|
||||
{
|
||||
|
@ -39,7 +50,7 @@ NSClientPlayer::IsDead(void)
|
|||
bool
|
||||
NSClientPlayer::IsPlayer(void)
|
||||
{
|
||||
return (false);
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -279,6 +290,8 @@ void
|
|||
NSClientPlayer::UpdateAliveCam(void)
|
||||
{
|
||||
g_view.SetCameraOrigin(GetEyePos());
|
||||
Camera_RunBob(view_angles);
|
||||
Camera_StrafeRoll(view_angles);
|
||||
g_view.SetCameraAngle(view_angles);
|
||||
|
||||
if (vehicle) {
|
||||
|
@ -551,7 +564,14 @@ NSClientPlayer::PredictPostFrame(void)
|
|||
void
|
||||
NSClientPlayer::ServerInputFrame(void)
|
||||
{
|
||||
#ifdef BOT_INCLUDED
|
||||
/* wait a few seconds, as we may not have been spawned yet */
|
||||
if (clienttype(this) == CLIENTTYPE_BOT) {
|
||||
((bot)this).RunAI();
|
||||
}
|
||||
#endif
|
||||
|
||||
Physics_Run();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -20,7 +20,8 @@ typedef enumflags
|
|||
SPECFL_VELOCITY,
|
||||
SPECFL_TARGET,
|
||||
SPECFL_MODE,
|
||||
SPECFL_FLAGS
|
||||
SPECFL_FLAGS,
|
||||
SPECFL_TYPE,
|
||||
} NSClientSpectatorFlags_t;
|
||||
|
||||
typedef enum
|
||||
|
@ -68,6 +69,7 @@ public:
|
|||
virtual bool IsRealSpectator(void);
|
||||
virtual bool IsDead(void);
|
||||
virtual bool IsPlayer(void);
|
||||
virtual void SharedInputFrame(void);
|
||||
|
||||
/** Call to spectate the next spectating target. */
|
||||
virtual void InputNext(void);
|
||||
|
|
|
@ -64,6 +64,7 @@ NSClientSpectator::IsFakeSpectator(void)
|
|||
void
|
||||
NSClientSpectator::ProcessInput(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
if (input_buttons & INPUT_BUTTON0) {
|
||||
InputNext();
|
||||
} else if (input_buttons & INPUT_BUTTON3) {
|
||||
|
@ -73,9 +74,7 @@ NSClientSpectator::ProcessInput(void)
|
|||
} else {
|
||||
spec_flags &= ~SPECFLAG_BUTTON_RELEASED;
|
||||
}
|
||||
|
||||
input_buttons = 0;
|
||||
//crossprint(sprintf("%d %d %d\n", spec_ent, spec_mode, spec_flags));
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -86,9 +85,23 @@ NSClientSpectator::WarpToTarget(void)
|
|||
setorigin(this, b.origin);
|
||||
}
|
||||
|
||||
void
|
||||
NSClientSpectator::SharedInputFrame(void)
|
||||
{
|
||||
SetSize(g_vec_null, g_vec_null);
|
||||
|
||||
if (spec_mode == SPECMODE_FREE) {
|
||||
SetSolid(SOLID_NOT);
|
||||
SetMovetype(MOVETYPE_NOCLIP);
|
||||
} else {
|
||||
SetSolid(SOLID_NOT);
|
||||
SetMovetype(MOVETYPE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
float
|
||||
NSClientSpectator::SendEntity(entity ePVSent, float flChangedFlags)
|
||||
NSClientSpectator::SendEntity(entity ePVSent, float flChanged)
|
||||
{
|
||||
if (this != ePVSent) {
|
||||
return (0);
|
||||
|
@ -99,28 +112,21 @@ NSClientSpectator::SendEntity(entity ePVSent, float flChangedFlags)
|
|||
}
|
||||
|
||||
WriteByte(MSG_ENTITY, ENT_SPECTATOR);
|
||||
WriteFloat(MSG_ENTITY, flChangedFlags);
|
||||
WriteFloat(MSG_ENTITY, flChanged);
|
||||
|
||||
if (flChangedFlags & SPECFL_ORIGIN) {
|
||||
WriteCoord(MSG_ENTITY, origin[0]);
|
||||
WriteCoord(MSG_ENTITY, origin[1]);
|
||||
WriteCoord(MSG_ENTITY, origin[2]);
|
||||
}
|
||||
SENDENTITY_COORD(origin[0], SPECFL_ORIGIN)
|
||||
SENDENTITY_COORD(origin[1], SPECFL_ORIGIN)
|
||||
SENDENTITY_COORD(origin[2], SPECFL_ORIGIN)
|
||||
|
||||
if (flChangedFlags & SPECFL_VELOCITY) {
|
||||
WriteFloat(MSG_ENTITY, velocity[0]);
|
||||
WriteFloat(MSG_ENTITY, velocity[1]);
|
||||
WriteFloat(MSG_ENTITY, velocity[2]);
|
||||
}
|
||||
SENDENTITY_FLOAT(velocity[0], SPECFL_VELOCITY)
|
||||
SENDENTITY_FLOAT(velocity[1], SPECFL_VELOCITY)
|
||||
SENDENTITY_FLOAT(velocity[2], SPECFL_VELOCITY)
|
||||
|
||||
if (flChangedFlags & SPECFL_TARGET)
|
||||
WriteByte(MSG_ENTITY, spec_ent);
|
||||
|
||||
if (flChangedFlags & SPECFL_MODE)
|
||||
WriteByte(MSG_ENTITY, spec_mode);
|
||||
|
||||
if (flChangedFlags & SPECFL_FLAGS)
|
||||
WriteByte(MSG_ENTITY, spec_flags);
|
||||
SENDENTITY_BYTE(spec_ent, SPECFL_TARGET)
|
||||
SENDENTITY_BYTE(spec_mode, SPECFL_MODE)
|
||||
SENDENTITY_BYTE(spec_flags, SPECFL_FLAGS)
|
||||
SENDENTITY_BYTE(movetype, SPECFL_TYPE)
|
||||
SENDENTITY_BYTE(solid, SPECFL_TYPE)
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
@ -128,7 +134,11 @@ NSClientSpectator::SendEntity(entity ePVSent, float flChangedFlags)
|
|||
void
|
||||
NSClientSpectator::ServerInputFrame(void)
|
||||
{
|
||||
runstandardplayerphysics(this);
|
||||
if (spec_mode == SPECMODE_FREE) {
|
||||
runstandardplayerphysics(this);
|
||||
} else {
|
||||
WarpToTarget();
|
||||
}
|
||||
|
||||
/* since we are not using Physics_Run(), we have to call this manually */
|
||||
ProcessInput();
|
||||
|
@ -151,8 +161,9 @@ NSClientSpectator::ClientInputFrame(void)
|
|||
}
|
||||
|
||||
void
|
||||
NSClientSpectator::ReceiveEntity(float new, float fl)
|
||||
NSClientSpectator::ReceiveEntity(float new, float flChanged)
|
||||
{
|
||||
if (spec_mode == SPECMODE_FREE)
|
||||
if (new == FALSE) {
|
||||
/* Go through all the physics code between the last received frame
|
||||
* and the newest frame and keep the changes this time around instead
|
||||
|
@ -181,27 +192,21 @@ NSClientSpectator::ReceiveEntity(float new, float fl)
|
|||
/* seed for our prediction table */
|
||||
sequence = servercommandframe;
|
||||
|
||||
if (fl & SPECFL_ORIGIN) {
|
||||
origin[0] = readcoord();
|
||||
origin[1] = readcoord();
|
||||
origin[2] = readcoord();
|
||||
}
|
||||
READENTITY_COORD(origin[0], SPECFL_ORIGIN)
|
||||
READENTITY_COORD(origin[1], SPECFL_ORIGIN)
|
||||
READENTITY_COORD(origin[2], SPECFL_ORIGIN)
|
||||
|
||||
if (fl & SPECFL_VELOCITY) {
|
||||
velocity[0] = readfloat();
|
||||
velocity[1] = readfloat();
|
||||
velocity[2] = readfloat();
|
||||
}
|
||||
READENTITY_FLOAT(velocity[0], SPECFL_VELOCITY)
|
||||
READENTITY_FLOAT(velocity[1], SPECFL_VELOCITY)
|
||||
READENTITY_FLOAT(velocity[2], SPECFL_VELOCITY)
|
||||
|
||||
if (fl & SPECFL_TARGET)
|
||||
spec_ent = readbyte();
|
||||
|
||||
if (fl & SPECFL_MODE)
|
||||
spec_mode = readbyte();
|
||||
|
||||
if (fl & SPECFL_FLAGS)
|
||||
spec_flags = readbyte();
|
||||
READENTITY_BYTE(spec_ent, SPECFL_TARGET)
|
||||
READENTITY_BYTE(spec_mode, SPECFL_MODE)
|
||||
READENTITY_BYTE(spec_flags, SPECFL_FLAGS)
|
||||
READENTITY_BYTE(movetype, SPECFL_TYPE)
|
||||
READENTITY_BYTE(solid, SPECFL_TYPE)
|
||||
};
|
||||
|
||||
float
|
||||
NSClientSpectator::predraw(void)
|
||||
{
|
||||
|
@ -216,6 +221,8 @@ NSClientSpectator::InputNext(void)
|
|||
if (spec_flags & SPECFLAG_BUTTON_RELEASED)
|
||||
return;
|
||||
|
||||
spec_flags |= SPECFLAG_BUTTON_RELEASED;
|
||||
|
||||
#if 0
|
||||
float max_edict;
|
||||
|
||||
|
@ -264,7 +271,7 @@ NSClientSpectator::InputNext(void)
|
|||
|
||||
spec_ent = best;
|
||||
#endif
|
||||
spec_flags |= SPECFLAG_BUTTON_RELEASED;
|
||||
|
||||
WarpToTarget();
|
||||
|
||||
if (spec_mode == SPECMODE_FREE)
|
||||
|
@ -276,6 +283,9 @@ NSClientSpectator::InputPrevious(void)
|
|||
{
|
||||
if (spec_flags & SPECFLAG_BUTTON_RELEASED)
|
||||
return;
|
||||
|
||||
spec_flags |= SPECFLAG_BUTTON_RELEASED;
|
||||
|
||||
#if 0
|
||||
float max_edict;
|
||||
|
||||
|
@ -327,7 +337,6 @@ NSClientSpectator::InputPrevious(void)
|
|||
spec_ent = best;
|
||||
#endif
|
||||
|
||||
spec_flags |= SPECFLAG_BUTTON_RELEASED;
|
||||
|
||||
WarpToTarget();
|
||||
|
||||
|
@ -341,6 +350,8 @@ NSClientSpectator::InputMode(void)
|
|||
if (spec_flags & SPECFLAG_BUTTON_RELEASED)
|
||||
return;
|
||||
|
||||
spec_flags |= SPECFLAG_BUTTON_RELEASED;
|
||||
|
||||
NSClient f;
|
||||
#ifdef CLIENT
|
||||
f = (NSClient)findfloat(world, ::entnum, spec_ent);
|
||||
|
@ -356,8 +367,6 @@ NSClientSpectator::InputMode(void)
|
|||
if (spec_mode > SPECMODE_FIRSTPERSON)
|
||||
spec_mode = SPECMODE_FREE;
|
||||
}
|
||||
|
||||
spec_flags |= SPECFLAG_BUTTON_RELEASED;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -436,26 +445,13 @@ NSClientSpectator::EvaluateEntity(void)
|
|||
{
|
||||
/* check for which values have changed in this frame
|
||||
and announce to network said changes */
|
||||
if (origin != origin_net)
|
||||
SetSendFlags(SPECFL_ORIGIN);
|
||||
|
||||
if (velocity != velocity_net)
|
||||
SetSendFlags(SPECFL_VELOCITY);
|
||||
|
||||
if (spec_ent != spec_ent_net)
|
||||
SetSendFlags(SPECFL_TARGET);
|
||||
|
||||
if (spec_mode != spec_mode_net)
|
||||
SetSendFlags(SPECFL_MODE);
|
||||
|
||||
if (spec_flags != spec_flags_net)
|
||||
SetSendFlags(SPECFL_FLAGS);
|
||||
|
||||
SAVE_STATE(origin)
|
||||
SAVE_STATE(velocity)
|
||||
SAVE_STATE(spec_ent)
|
||||
SAVE_STATE(spec_mode)
|
||||
SAVE_STATE(spec_flags)
|
||||
EVALUATE_FIELD(origin, SPECFL_ORIGIN)
|
||||
EVALUATE_FIELD(velocity, SPECFL_VELOCITY)
|
||||
EVALUATE_FIELD(spec_ent, SPECFL_TARGET)
|
||||
EVALUATE_FIELD(spec_mode, SPECFL_MODE)
|
||||
EVALUATE_FIELD(spec_flags, SPECFL_FLAGS)
|
||||
EVALUATE_FIELD(movetype, SPECFL_TYPE)
|
||||
EVALUATE_FIELD(solid, SPECFL_TYPE)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue