Propagation of some of the weapon variables needed for prediction. Resetting of map entities for when a solo player spawns (risky, but needs testing!)

This commit is contained in:
Marco Cawthorne 2019-08-21 15:49:35 -07:00
parent ffb5ca5ff1
commit 8fd19cddc0
20 changed files with 158 additions and 60 deletions

View file

@ -22,14 +22,14 @@ void Predict_PreFrame(player pl)
pl.netflags = pl.flags;
pl.netjumptime = pl.jumptime;
pl.netteleport_time = pl.teleport_time;
#ifdef VALVE
//pl.net_w_attack_next = pl.w_attack_next;
//pl.net_w_idle_next = pl.w_idle_next;
pl.net_w_attack_next = pl.w_attack_next;
pl.net_w_idle_next = pl.w_idle_next;
pl.net_ammo1 = pl.a_ammo1;
pl.net_ammo2 = pl.a_ammo2;
pl.net_ammo3 = pl.a_ammo3;
//pl.net_weapontime = pSeat->eViewModel.frame1time;
pl.net_weapontime = pl.weapontime;
#endif
//self.netpmove_flags = self.pmove_flags;
@ -37,8 +37,9 @@ void Predict_PreFrame(player pl)
//we want to predict an exact copy of the data in the new packet
/*for (; self.pmove_frame <= servercommandframe; self.pmove_frame++) {
float flSuccess = getinputstate(self.pmove_frame);*/
for ( int i = servercommandframe + 1; i <= clientcommandframe; i++ ) {
for ( int i = pl.sequence + 1; i <= clientcommandframe; i++ ) {
float flSuccess = getinputstate( i );
input_sequence = i;
if (flSuccess == FALSE) {
continue;
}
@ -60,8 +61,8 @@ void Predict_PreFrame(player pl)
Predict_PostFrame
We're part way through parsing new player data.
Propagate our pmove state to whatever the current frame before its stomped on
(so any non-networked state updates locally).
Rewind our pmove state back to before we started predicting.
(to give consistent state instead of accumulating errors)
=================
*/
void Predict_PostFrame(player pl)
@ -73,13 +74,12 @@ void Predict_PostFrame(player pl)
pl.teleport_time = pl.netteleport_time;
#ifdef VALVE
//pl.w_attack_next = pl.net_w_attack_next;
//pl.w_idle_next = pl.net_w_idle_next;
pl.w_attack_next = pl.net_w_attack_next;
pl.w_idle_next = pl.net_w_idle_next;
pl.a_ammo1 = pl.net_ammo1;
pl.a_ammo2 = pl.net_ammo2;
pl.a_ammo3 = pl.net_ammo3;
//pSeat->eViewModel.frame1time = pl.net_weapontime;
//pSeat->eViewModel.frame2time = pl.net_weapontime;
pl.weapontime = pl.net_weapontime;
#endif
//self.pmove_flags = self.netpmove_flags;

View file

@ -70,6 +70,8 @@ void HUD_DrawWeaponSelect_Back(void)
void HUD_DrawWeaponSelect_Trigger(void)
{
player pl = (player)pSeat->ePlayer;
pl.activeweapon = pSeat->fHUDWeaponSelected;
sendevent("PlayerSwitchWeapon", "f", pSeat->fHUDWeaponSelected);
sound(pSeat->ePlayer, CHAN_ITEM, "common/wpn_select.wav", 0.5f, ATTN_NONE);
pSeat->fHUDWeaponSelected = pSeat->fHUDWeaponSelectTime = 0;

View file

@ -6,6 +6,19 @@
*
****/
//FOR DEBUGGING ONLY, remove when prediction is trusted (along with the extra network bloat).
static void warnifdiff(string name, __inout float expected, float got)
{
//this should only fire from prediction misses.
//this hopefully only happens when the server's anti-time-banking logic does its thing, or for things caused by other players/ents getting in the way.
if (expected != got)
print(sprintf("%s differs, expected %g, got %g\n", name, expected, got));
//enable the following line if you want to see if it actually makes a difference.
//expected = got;
}
void Player_ReadEntity(float flIsNew)
{
player pl = (player)self;
@ -16,37 +29,56 @@ void Player_ReadEntity(float flIsNew)
pl.drawmask = MASK_ENGINE;
pl.customphysics = Empty;
setsize( pl, VEC_HULL_MIN, VEC_HULL_MAX );
}
pl.modelindex = readshort();
print(sprintf("Player %g is csqc ent %i\n", pl.entnum, pl));
}
else
{
if (pl.entnum == player_localentnum) //FIXME: splitscreen
{
pSeat = &seats[0]; //FIXME: splitscreen
for (int i = pl.sequence+1; i <= servercommandframe; i++)
{
if (!getinputstate(i))
break; //erk?... too old?
input_sequence = i;
QPhysics_Run(pl);
}
//any differences in things that are read below are now officially from prediction misses.
}
}
pl.sequence = servercommandframe;
pl.modelindex = readshort(); //make conditional
pl.origin[0] = readcoord();
pl.origin[1] = readcoord();
pl.origin[2] = readcoord();
pl.origin[2] = readcoord(); //make conditional
pl.pitch = readfloat();
pl.angles[1] = readfloat();
pl.angles[2] = readfloat();
pl.velocity[0] = readcoord();
pl.velocity[1] = readcoord();
pl.velocity[2] = readcoord();
pl.flags = readfloat();
pl.activeweapon = readbyte();
pl.weapontime = readfloat();
pl.g_items = readfloat();
pl.health = readbyte();
pl.armor = readbyte();
pl.movetype = readbyte();
pl.view_ofs[2] = readfloat();
pl.viewzoom = readfloat();
pl.jumptime = readfloat();
pl.teleport_time = readfloat();
pl.flags = readfloat(); //make mostly conditional
pl.activeweapon = readbyte(); //make conditional
warnifdiff("weapontime", pl.weapontime, readfloat()); //remove
pl.g_items = readfloat(); //make conditional
pl.health = readbyte(); //make conditional
pl.armor = readbyte(); //make conditional
pl.movetype = readbyte(); //make conditional
pl.view_ofs[2] = readfloat(); //make conditional
pl.viewzoom = readfloat(); //remove? or make conditional
warnifdiff("jumptime", pl.jumptime, readfloat()); //remove
warnifdiff("teletime", pl.teleport_time, readfloat()); //remove
pl.baseframe = readbyte();
pl.frame = readbyte();
pl.baseframe = readbyte(); //make conditional
pl.frame = readbyte(); //make conditional
pl.a_ammo1 = readbyte();
pl.a_ammo2 = readbyte();
pl.a_ammo3 = readbyte();
//pl.w_attack_next = readfloat();
//pl.w_idle_next = readfloat();
pl.a_ammo1 = readbyte(); //make conditional
pl.a_ammo2 = readbyte(); //make conditional
pl.a_ammo3 = readbyte(); //make conditional
warnifdiff("attack_next", pl.w_attack_next, readfloat()); //remove
warnifdiff("idle_next", pl.w_idle_next, readfloat()); //remove
setorigin( pl, pl.origin );
}

View file

@ -193,7 +193,7 @@ void View_DrawViewModel(void)
float fBaseTime = eViewModel.frame1time;
eViewModel.frame2time = pl.weapontime;
eViewModel.frame1time = pl.weapontime;
//processmodelevents(eViewModel.modelindex, eViewModel.frame, fBaseTime, eViewModel.frame1time, Event_ProcessModel);
processmodelevents(eViewModel.modelindex, eViewModel.frame, fBaseTime, eViewModel.frame1time, Event_ProcessModel);
}
makevectors(view_angles);

View file

@ -231,6 +231,7 @@ void Game_Worldspawn(void)
precache_model("models/player/vip/vip.mdl");
precache_model("models/w_c4.mdl");
precache_sound("misc/null.wav");
precache_sound("hostage/hos1.wav");
precache_sound("hostage/hos2.wav");
precache_sound("hostage/hos3.wav");

View file

@ -14,6 +14,10 @@ void Flashlight_Toggle(void)
}
}
if (self.health <= 0) {
return;
}
if (self.flags & FL_FLASHLIGHT) {
self.flags &= ~FL_FLASHLIGHT;
} else {

View file

@ -11,6 +11,19 @@ void Empty(void) {}
void Game_ClientConnect(void)
{
bprint(PRINT_HIGH, sprintf("%s connected\n", self.netname));
int playercount = 0;
for (entity eFind = world; (eFind = find(eFind, classname, "player"));) {
playercount++;
}
/* We're the first. */
if (playercount == 0) {
for (entity a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) {
CBaseEntity caw = (CBaseEntity)a;
caw.Respawn();
}
}
}
void Game_ClientDisconnect(void)

View file

@ -19,6 +19,21 @@ float Game_ConsoleCmd(string cmd)
void Game_Worldspawn(void)
{
precache_model("models/player.mdl");
Weapons_Init();
precache_model("models/w_weaponbox.mdl");
precache_sound("misc/null.wav");
precache_sound("fvox/flatline.wav");
/* TODO: Scan and precache models/player/.mdl */
precache_model("models/player/barney/barney.mdl");
precache_model("models/player/gman/gman.mdl");
precache_model("models/player/gordon/gordon.mdl");
precache_model("models/player/hgrunt/hgrunt.mdl");
precache_model("models/player/scientist/scientist.mdl");
precache_model("models/player/zombie/zombie.mdl");
precache_model("models/player/helmet/helmet.mdl");
precache_model("models/player/recon/recon.mdl");
precache_model("models/player/robo/robo.mdl");
Weapons_Init();
SHData_Parse(mapname);
}

View file

@ -11,6 +11,19 @@ void Empty(void) {}
void Game_ClientConnect(void)
{
bprint(PRINT_HIGH, sprintf("%s connected\n", self.netname));
int playercount = 0;
for (entity eFind = world; (eFind = find(eFind, classname, "player"));) {
playercount++;
}
/* We're the first. */
if (playercount == 0) {
for (entity a = world; (a = findfloat(a, gflags, GF_CANRESPAWN));) {
CBaseEntity caw = (CBaseEntity)a;
caw.Respawn();
}
}
}
void Game_ClientDisconnect(void)

View file

@ -19,6 +19,7 @@ void Player_Death(int hit)
pl.movetype = MOVETYPE_NONE;
pl.solid = SOLID_NOT;
pl.takedamage = DAMAGE_NO;
pl.flags &= ~FL_FLASHLIGHT;
pl.health = pl.armor = pl.activeweapon = pl.g_items = 0;
pl.think = PutClientInServer;
@ -138,8 +139,8 @@ float Player_SendEntity(entity ePEnt, float fChanged)
WriteByte(MSG_ENTITY, pl.a_ammo1);
WriteByte(MSG_ENTITY, pl.a_ammo2);
WriteByte(MSG_ENTITY, pl.a_ammo3);
//WriteFloat(MSG_ENTITY, pl.w_attack_next);
//WriteFloat(MSG_ENTITY, pl.w_idle_next);
WriteFloat(MSG_ENTITY, pl.w_attack_next);
WriteFloat(MSG_ENTITY, pl.w_idle_next);
return TRUE;
}

View file

@ -19,5 +19,20 @@ float Game_ConsoleCmd(string cmd)
void Game_Worldspawn(void)
{
precache_model("models/player.mdl");
precache_model("models/w_weaponbox.mdl");
precache_sound("misc/null.wav");
precache_sound("fvox/flatline.wav");
/* TODO: Scan and precache models/player/.mdl */
precache_model("models/player/barney/barney.mdl");
precache_model("models/player/gman/gman.mdl");
precache_model("models/player/gordon/gordon.mdl");
precache_model("models/player/hgrunt/hgrunt.mdl");
precache_model("models/player/scientist/scientist.mdl");
precache_model("models/player/zombie/zombie.mdl");
precache_model("models/player/helmet/helmet.mdl");
precache_model("models/player/recon/recon.mdl");
precache_model("models/player/robo/robo.mdl");
Weapons_Init();
}

View file

@ -721,15 +721,9 @@ void PMove_Run(void)
#ifdef VALVE
player pl = (player)self;
pl.w_attack_next -= input_timelength;
pl.w_idle_next -= input_timelength;
pl.weapontime += input_timelength;
if (pl.w_attack_next <= 0) {
pl.w_attack_next = 0;
}
if (pl.w_idle_next <= 0) {
pl.w_idle_next = 0;
}
pl.w_attack_next = max(0, pl.w_attack_next-input_timelength);
pl.w_idle_next = max(0, pl.w_idle_next-input_timelength);
pl.weapontime += input_timelength;
#endif
Game_Input();

View file

@ -1,4 +1,4 @@
int input_sequence;
class player
{
float health;
@ -56,6 +56,8 @@ class player
int net_ammo1;
int net_ammo2;
int net_ammo3;
int sequence;
virtual void() gun_offset;
virtual void() draw;
virtual float() predraw;

View file

@ -28,9 +28,11 @@ void w_cannon_precache(void)
precache_sound("cannon/fire.wav");
precache_sound("cannon/open.wav");
}
string w_cannon_vmodel(void)
void w_cannon_updateammo(player pl)
{
return "models/v_cannon.mdl";
#ifdef SSQC
Weapons_UpdateAmmo(pl, pl.cannon_mag, pl.ammo_buckshot, __NULL__);
#endif
}
string w_cannon_pmodel(void)
{
@ -218,7 +220,7 @@ weapon_t w_cannon =
w_cannon_crosshair,
w_cannon_precache,
w_cannon_pickup,
w_cannon_vmodel,
w_cannon_updateammo,
__NULL__,
w_cannon_pmodel,
w_cannon_deathmsg,

View file

@ -29,9 +29,11 @@ void w_chainsaw_precache(void)
precache_model("models/p_saw.mdl");
}
string w_chainsaw_vmodel(void)
void w_chainsaw_updateammo(player pl)
{
return "models/v_chainsaw.mdl";
#ifdef SSQC
Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__);
#endif
}
string w_chainsaw_pmodel(void)
{
@ -157,7 +159,7 @@ weapon_t w_chainsaw =
__NULL__,
w_chainsaw_precache,
__NULL__,
w_chainsaw_vmodel,
w_chainsaw_updateammo,
__NULL__,
w_chainsaw_pmodel,
w_chainsaw_deathmsg,

View file

@ -30,9 +30,11 @@ void w_hammer_precache(void)
precache_model("models/v_hammer.mdl");
}
string w_hammer_vmodel(void)
void w_hammer_updateammo(player pl)
{
return "models/v_hammer.mdl";
#ifdef SSQC
Weapons_UpdateAmmo(pl, __NULL__, __NULL__, __NULL__);
#endif
}
string w_hammer_pmodel(void)
{
@ -217,7 +219,7 @@ weapon_t w_hammer =
__NULL__,
w_hammer_precache,
__NULL__,
w_hammer_vmodel,
w_hammer_updateammo,
__NULL__,
w_hammer_pmodel,
w_hammer_deathmsg,

View file

@ -1,3 +1,4 @@
int input_sequence;
class player
{
float health;
@ -53,6 +54,7 @@ class player
int net_ammo1;
int net_ammo2;
int net_ammo3;
int sequence;
virtual void() gun_offset;
virtual void() draw;

View file

@ -73,7 +73,7 @@ void w_crowbar_primary(void)
vector src = pl.origin + pl.view_ofs;
traceline(src, src + (v_forward * 32), FALSE, pl);
int r = floor(random(0,3));
int r = (float)input_sequence%3;
switch (r) {
case 0:
Weapons_ViewAnimation(trace_fraction >= 1 ? CROWBAR_ATTACK1MISS:CROWBAR_ATTACK1HIT);

View file

@ -110,7 +110,7 @@ void w_handgrenade_throw(void)
void w_handgrenade_draw(void)
{
Weapons_SetModel("models/v_crowbar.mdl");
Weapons_SetModel("models/v_grenade.mdl");
Weapons_ViewAnimation(HANDGRENADE_DRAW);
#ifdef SSQC
player pl = (player)self;

View file

@ -38,9 +38,7 @@ void Weapons_Draw(void)
if (g_weapons[i].draw != __NULL__) {
g_weapons[i].draw();
}
#ifdef CSQC
View_UpdateWeapon(pSeat->eViewModel, pSeat->eMuzzleflash);
#else
#ifdef SSQC
if (g_weapons[i].updateammo != __NULL__) {
g_weapons[i].updateammo(pl);
}