CLIENT: Player network prediction by eukara

This commit is contained in:
cypress 2023-11-11 20:36:11 -05:00
parent 7f39469359
commit 3ec7db8299
4 changed files with 134 additions and 3 deletions

View file

@ -249,3 +249,8 @@ string build_datetime;
vector gun_kick; vector gun_kick;
float hide_viewmodel; float hide_viewmodel;
// csqc player prediction by eukara
vector playerOrigin;
vector playerOriginOld;
vector playerVelocity;

View file

@ -62,6 +62,7 @@ noref void(float apiver, string enginename, float enginever) CSQC_Init =
precache_sound("sounds/menu/enter.wav"); precache_sound("sounds/menu/enter.wav");
precache_sound("sounds/menu/navigate.wav"); precache_sound("sounds/menu/navigate.wav");
precache_model("models/player.mdl");
registercommand("togglemenu"); registercommand("togglemenu");
registercommand("startwalk"); registercommand("startwalk");
@ -507,11 +508,98 @@ void() Update_Vmodel =
mzlflash.alpha = 0.01; mzlflash.alpha = 0.01;
} }
float Player_PreDraw() =
{
if (self.entnum == player_localentnum) {
self.movetype = MOVETYPE_WALK;
// Prepare rollback
vector vOldOrigin = self.origin;
vector vOldVelocity = self.velocity;
float fOldPMoveFlags = self.pmove_flags;
// Apply physics for every single input-frame that has not yet been
// acknowledged by the server (servercommandframe = last acknowledged frame)
for (int i = servercommandframe + 1; i <= clientcommandframe; i++) {
float flSuccess = getinputstate(i);
if (flSuccess == FALSE) {
continue;
}
// Partial frames are the worst
if (input_timelength == 0) {
break;
}
runstandardplayerphysics(self);
}
// Smooth stair stepping, this has to be done manually!
playerOriginOld = playerOrigin;
if ((self.flags & FL_ONGROUND) && (self.origin_z - playerOriginOld_z > 0)) {
playerOriginOld_z += frametime * 150;
if (playerOriginOld_z > self.origin_z) {
playerOriginOld_z = self.origin_z;
}
if (self.origin_z - playerOriginOld_z > 18) {
playerOriginOld_z = self.origin_z - 18;
}
playerOrigin_z += playerOriginOld_z - self.origin_z;
} else {
playerOriginOld_z = self.origin_z;
}
playerOrigin = [self.origin_x, self.origin_y, playerOriginOld_z];
playerVelocity = self.velocity;
addentity(self);
// Time to roll back
self.origin = vOldOrigin;
setorigin(self, self.origin);
self.velocity = vOldVelocity;
self.pmove_flags = fOldPMoveFlags;
self.movetype = MOVETYPE_NONE;
// Set renderflag for mirrors!
self.renderflags = RF_EXTERNALMODEL;
} else {
addentity(self);
}
return PREDRAW_NEXT;
}
noref void(float isnew) CSQC_Ent_Update = noref void(float isnew) CSQC_Ent_Update =
{ {
float ent_type = readbyte();
if (ent_type == 1) {
if (isnew == TRUE) {
self.classname = "player";
self.solid = SOLID_SLIDEBOX;
self.predraw = Player_PreDraw;
self.drawmask = MASK_ENGINE;
setmodel(self, "models/player.mdl");
}
self.origin_x = readcoord();
self.origin_y = readcoord();
self.origin_z = readcoord();
self.angles_x = readcoord();
self.angles_y = readcoord();
self.angles_z = readcoord();
self.velocity_x = readshort();
self.velocity_y = readshort();
self.velocity_z = readshort();
self.flags = readfloat();
setsize(self, [-16, -16, -32], [16, 16, 40]);
setorigin(self, self.origin);
} else {
if(isnew) if(isnew)
addentity(self); addentity(self);
} }
}
float(__inout vector v) VectorNormalize = float(__inout vector v) VectorNormalize =
{ {
@ -849,6 +937,9 @@ noref void(float width, float height, float menushown) CSQC_UpdateView =
//autoadd entities received from servers for drawing //autoadd entities received from servers for drawing
addentities(MASK_ENGINE); addentities(MASK_ENGINE);
setproperty(VF_ORIGIN, playerOrigin + [ 0, 0, getstatf(STAT_VIEWHEIGHT)]);
//setproperty(VF_ANGLES, view_angles);
//do viewmodel manipulation, purely cosmetic stuff //do viewmodel manipulation, purely cosmetic stuff
if(vmodel) if(vmodel)
{ {

View file

@ -534,6 +534,32 @@ void (float achievement_id, optional entity who) GiveAchievement =
} }
} }
#ifdef FTE
/*
=================
Player_SendEntity
Networks the player info
=================
*/
float Player_SendEntity( entity ePVEnt, float flChanged ) {
WriteByte( MSG_ENTITY, 1 );
WriteCoord( MSG_ENTITY, self.origin_x ); // Position X
WriteCoord( MSG_ENTITY, self.origin_y ); // Position Y
WriteCoord( MSG_ENTITY, self.origin_z ); // Position Z
WriteCoord( MSG_ENTITY, self.angles_x ); // Angle X
WriteCoord( MSG_ENTITY, self.angles_y ); // Angle Y
WriteCoord( MSG_ENTITY, self.angles_z ); // Angle Z
WriteShort( MSG_ENTITY, self.velocity_x ); // Velocity X
WriteShort( MSG_ENTITY, self.velocity_y ); // Velocity X
WriteShort( MSG_ENTITY, self.velocity_z ); // Velocity X
WriteFloat( MSG_ENTITY, self.flags ); // Flags, important for physics
return TRUE;
}
#endif // FTE
void (float achievement_id, float progress_value, optional entity who) UpdateAchievementProgress = void (float achievement_id, float progress_value, optional entity who) UpdateAchievementProgress =
{ {

View file

@ -347,6 +347,14 @@ void() PlayerPreThink =
float player_trace_time; float player_trace_time;
void() PlayerPostThink = void() PlayerPostThink =
{ {
#ifdef FTE
// Network everything
self.SendFlags = 1;
#endif // FTE
if(self.isspec) if(self.isspec)
return; return;
@ -671,6 +679,7 @@ void() PlayerSpawn =
stuffcmd(self, "cl_gunx 8;cl_guny 16;cl_gunz 25\n"); stuffcmd(self, "cl_gunx 8;cl_guny 16;cl_gunz 25\n");
SetRound(self, G_STARTROUND); SetRound(self, G_STARTROUND);
self.viewzoom = 1; self.viewzoom = 1;
self.SendEntity = Player_SendEntity;
self.weapon_animduration = getWeaponDelay(self.weapon, FIRE); self.weapon_animduration = getWeaponDelay(self.weapon, FIRE);
if (G_WORLDTEXT) if (G_WORLDTEXT)