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:
parent
ffb5ca5ff1
commit
8fd19cddc0
20 changed files with 158 additions and 60 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -14,6 +14,10 @@ void Flashlight_Toggle(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (self.health <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.flags & FL_FLASHLIGHT) {
|
||||
self.flags &= ~FL_FLASHLIGHT;
|
||||
} else {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue