GS-EntBase: Fix crash with vehicles by networking them separately

from CBaseEntity, which will assign the needed client-side input
method for prediction
This commit is contained in:
Marco Cawthorne 2021-08-28 21:25:38 +02:00
parent 4952e7fbe0
commit 34505bcacf
4 changed files with 124 additions and 3 deletions

View File

@ -941,6 +941,9 @@ CSQC_Ent_Update(float new)
}
me.ReceiveEntity(readfloat());
break;
case ENT_VEHICLE:
basevehicle_readentity(new);
break;
case ENT_PLAYER:
player pl = (player)self;

View File

@ -19,6 +19,9 @@ class CBaseVehicle:CBaseTrigger
#ifdef CLIENT
virtual void(void) PredictPreFrame;
virtual void(void) PredictPostFrame;
virtual void(float, float) ReadEntity;
#else
virtual float(entity, float) SendEntity;
#endif
virtual void(void) PlayerUpdateFlags;

View File

@ -20,6 +20,7 @@ enumflags
VHF_NOATTACK
};
#ifdef CLIENT
void
CBaseVehicle::PredictPreFrame(void)
{
@ -36,6 +37,106 @@ CBaseVehicle::PredictPostFrame(void)
ROLL_BACK(velocity);
}
void
CBaseVehicle::ReadEntity(float fChanged, float new)
{
m_eDriver = findfloat(world, ::entnum, readentitynum());
if (fChanged & BASEFL_CHANGED_ORIGIN) {
origin[0] = readcoord();
origin[1] = readcoord();
origin[2] = readcoord();
}
if (fChanged & BASEFL_CHANGED_ANGLES) {
angles[0] = readshort() / (32767 / 360);
angles[1] = readshort() / (32767 / 360);
angles[2] = readshort() / (32767 / 360);
}
if (fChanged & BASEFL_CHANGED_MODELINDEX) {
setmodelindex(this, readshort());
}
if (fChanged & BASEFL_CHANGED_SOLID) {
solid = readbyte();
}
if (fChanged & BASEFL_CHANGED_MOVETYPE) {
movetype = readbyte();
}
if (fChanged & BASEFL_CHANGED_SIZE) {
mins[0] = readcoord();
mins[1] = readcoord();
mins[2] = readcoord();
maxs[0] = readcoord();
maxs[1] = readcoord();
maxs[2] = readcoord();
}
if (fChanged & BASEFL_CHANGED_VELOCITY) {
velocity[0] = readfloat();
velocity[1] = readfloat();
velocity[2] = readfloat();
}
if (new)
drawmask = MASK_ENGINE;
}
#else
float
CBaseVehicle::SendEntity(entity ePEnt, float fChanged)
{
WriteByte(MSG_ENTITY, ENT_VEHICLE);
WriteFloat(MSG_ENTITY, fChanged);
WriteEntity(MSG_ENTITY, m_eDriver);
/* really trying to get our moneys worth with 23 bits of mantissa */
if (fChanged & BASEFL_CHANGED_ORIGIN) {
WriteCoord(MSG_ENTITY, origin[0]);
WriteCoord(MSG_ENTITY, origin[1]);
WriteCoord(MSG_ENTITY, origin[2]);
}
if (fChanged & BASEFL_CHANGED_ANGLES) {
WriteShort(MSG_ENTITY, angles[0] * 32767 / 360);
WriteShort(MSG_ENTITY, angles[1] * 32767 / 360);
WriteShort(MSG_ENTITY, angles[2] * 32767 / 360);
}
if (fChanged & BASEFL_CHANGED_MODELINDEX) {
WriteShort(MSG_ENTITY, modelindex);
}
if (fChanged & BASEFL_CHANGED_SOLID) {
WriteByte(MSG_ENTITY, solid);
}
if (fChanged & BASEFL_CHANGED_MOVETYPE) {
WriteByte(MSG_ENTITY, movetype);
}
if (fChanged & BASEFL_CHANGED_SIZE) {
WriteCoord(MSG_ENTITY, mins[0]);
WriteCoord(MSG_ENTITY, mins[1]);
WriteCoord(MSG_ENTITY, mins[2]);
WriteCoord(MSG_ENTITY, maxs[0]);
WriteCoord(MSG_ENTITY, maxs[1]);
WriteCoord(MSG_ENTITY, maxs[2]);
}
if (fChanged & BASEFL_CHANGED_VELOCITY) {
WriteFloat(MSG_ENTITY, velocity[0]);
WriteFloat(MSG_ENTITY, velocity[1]);
WriteFloat(MSG_ENTITY, velocity[2]);
}
return (1);
}
#endif
void
CBaseVehicle::PlayerInput(void)
{
@ -83,14 +184,14 @@ CBaseVehicle::PlayerEnter(base_player pl)
pl.movetype = MOVETYPE_NOCLIP;
m_eDriver = (entity)pl;
pl.vehicle = this;
pl.flags |= FL_INVEHICLE;
//pl.flags |= FL_INVEHICLE;
}
void
CBaseVehicle::PlayerLeave(base_player pl)
{
pl.movetype = MOVETYPE_WALK;
pl.flags &= ~FL_INVEHICLE;
//pl.flags &= ~FL_INVEHICLE;
if (m_iVehicleFlags & VHF_FROZEN)
pl.flags &= ~FL_FROZEN;
@ -107,3 +208,16 @@ CBaseVehicle::CBaseVehicle(void)
{
CBaseEntity::CBaseEntity();
}
#ifdef CLIENT
void
basevehicle_readentity(float isnew)
{
CBaseVehicle veh = (CBaseVehicle)self;
float flags = readfloat();
if (isnew)
spawnfunc_CBaseVehicle();
veh.ReadEntity(flags, isnew);
}
#endif

View File

@ -31,7 +31,8 @@ enum
ENT_DECAL,
ENT_OLDCAMERA,
ENT_MONITOR,
ENT_SEPARATOR
ENT_VEHICLE,
ENT_SEPARATOR,
};
/* entity update flags */