GS-EntBase: Add client-side prediction for func_tankmortar.
This commit is contained in:
parent
05fe98e0ca
commit
5578b0e602
5 changed files with 207 additions and 25 deletions
|
@ -927,6 +927,9 @@ CSQC_Ent_Update(float new)
|
|||
case ENT_VEHICLE:
|
||||
basevehicle_readentity(new);
|
||||
break;
|
||||
case ENT_VEH_TANKMORTAR:
|
||||
func_tankmortar_readentity(new);
|
||||
break;
|
||||
case ENT_PLAYER:
|
||||
player pl = (player)self;
|
||||
|
||||
|
|
|
@ -24,14 +24,6 @@ enumflags
|
|||
void
|
||||
CBaseVehicle::UpdateView(void)
|
||||
{
|
||||
vector vecStart, vecEnd;
|
||||
|
||||
pSeat->m_vecPredictedOrigin = origin;
|
||||
makevectors(view_angles);
|
||||
vecStart = [pSeat->m_vecPredictedOrigin[0], pSeat->m_vecPredictedOrigin[1], pSeat->m_vecPredictedOrigin[2] + 16] + (v_right * 4);
|
||||
vecEnd = vecStart + (v_forward * -256) + [0,0,16] + (v_right * 4);
|
||||
traceline(vecStart, vecEnd, FALSE, self);
|
||||
setproperty(VF_ORIGIN, trace_endpos + (v_forward * 16));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -50,7 +50,6 @@ some random sprites needs to be treated additive.
|
|||
This entity was introduced in Half-Life (1998).
|
||||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
/* TODO: Implement these */
|
||||
enumflags
|
||||
{
|
||||
|
@ -84,17 +83,176 @@ class func_tankmortar:CBaseVehicle
|
|||
float m_flFireTime;
|
||||
void(void) func_tankmortar;
|
||||
|
||||
virtual void(void) customphysics;
|
||||
virtual void(void) PlayerInput;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(vector) SpriteSmoke;
|
||||
virtual void(vector) SpriteFlash;
|
||||
|
||||
#ifdef CLIENT
|
||||
virtual void(void) PredictPreFrame;
|
||||
virtual void(void) PredictPostFrame;
|
||||
virtual void(float, float) ReadEntity;
|
||||
virtual void(void) UpdateView;
|
||||
#else
|
||||
virtual float(entity, float) SendEntity;
|
||||
virtual void(void) Respawn;
|
||||
virtual void(string, string) SpawnKey;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifdef CLIENT
|
||||
void
|
||||
func_tankmortar::UpdateView(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
func_tankmortar::PredictPreFrame(void)
|
||||
{
|
||||
SAVE_STATE(angles);
|
||||
SAVE_STATE(origin);
|
||||
SAVE_STATE(velocity);
|
||||
}
|
||||
|
||||
void
|
||||
func_tankmortar::PredictPostFrame(void)
|
||||
{
|
||||
ROLL_BACK(angles);
|
||||
ROLL_BACK(origin);
|
||||
ROLL_BACK(velocity);
|
||||
}
|
||||
|
||||
void
|
||||
func_tankmortar::ReadEntity(float fChanged, float new)
|
||||
{
|
||||
if (fChanged & VEHFL_CHANGED_ORIGIN) {
|
||||
origin[0] = readcoord();
|
||||
origin[1] = readcoord();
|
||||
origin[2] = readcoord();
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_ANGLES) {
|
||||
angles[0] = readshort() / (32767 / 360);
|
||||
angles[1] = readshort() / (32767 / 360);
|
||||
angles[2] = readshort() / (32767 / 360);
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_MODELINDEX) {
|
||||
setmodelindex(this, readshort());
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_SOLID) {
|
||||
solid = readbyte();
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_MOVETYPE) {
|
||||
movetype = readbyte();
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_SIZE) {
|
||||
mins[0] = readcoord();
|
||||
mins[1] = readcoord();
|
||||
mins[2] = readcoord();
|
||||
maxs[0] = readcoord();
|
||||
maxs[1] = readcoord();
|
||||
maxs[2] = readcoord();
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_VELOCITY) {
|
||||
velocity[0] = readfloat();
|
||||
velocity[1] = readfloat();
|
||||
velocity[2] = readfloat();
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_DRIVER) {
|
||||
m_eDriver = findfloat(world, ::entnum, readentitynum());
|
||||
}
|
||||
|
||||
if (new)
|
||||
drawmask = MASK_ENGINE;
|
||||
}
|
||||
#else
|
||||
void
|
||||
func_tankmortar::EvaluateEntity(void)
|
||||
{
|
||||
/* while the engine is still handling physics for these, we can't
|
||||
* predict when origin/angle might change */
|
||||
if (net_origin != origin) {
|
||||
net_origin = origin;
|
||||
SetSendFlags(VEHFL_CHANGED_ORIGIN);
|
||||
}
|
||||
if (net_angles != angles) {
|
||||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
|
||||
net_angles = angles;
|
||||
SetSendFlags(VEHFL_CHANGED_ANGLES);
|
||||
}
|
||||
if (net_velocity != velocity) {
|
||||
net_velocity = velocity;
|
||||
SetSendFlags(VEHFL_CHANGED_VELOCITY);
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
func_tankmortar::SendEntity(entity ePEnt, float fChanged)
|
||||
{
|
||||
WriteByte(MSG_ENTITY, ENT_VEH_TANKMORTAR);
|
||||
WriteFloat(MSG_ENTITY, fChanged);
|
||||
|
||||
/* really trying to get our moneys worth with 23 bits of mantissa */
|
||||
if (fChanged & VEHFL_CHANGED_ORIGIN) {
|
||||
WriteCoord(MSG_ENTITY, origin[0]);
|
||||
WriteCoord(MSG_ENTITY, origin[1]);
|
||||
WriteCoord(MSG_ENTITY, origin[2]);
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_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 & VEHFL_CHANGED_MODELINDEX) {
|
||||
WriteShort(MSG_ENTITY, modelindex);
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_SOLID) {
|
||||
WriteByte(MSG_ENTITY, solid);
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_MOVETYPE) {
|
||||
WriteByte(MSG_ENTITY, movetype);
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_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 & VEHFL_CHANGED_VELOCITY) {
|
||||
WriteFloat(MSG_ENTITY, velocity[0]);
|
||||
WriteFloat(MSG_ENTITY, velocity[1]);
|
||||
WriteFloat(MSG_ENTITY, velocity[2]);
|
||||
}
|
||||
|
||||
if (fChanged & VEHFL_CHANGED_DRIVER) {
|
||||
WriteEntity(MSG_ENTITY, m_eDriver);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
func_tankmortar::SpriteSmoke(vector org)
|
||||
{
|
||||
#ifdef SERVER
|
||||
static void Die(void) {
|
||||
remove(self);
|
||||
}
|
||||
|
@ -109,11 +267,13 @@ func_tankmortar::SpriteSmoke(vector org)
|
|||
smoke.nextthink = time + 0.1f;
|
||||
smoke.scale = m_flSpriteScale;
|
||||
smoke.effects = EF_FLAG2;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
func_tankmortar::SpriteFlash(vector org)
|
||||
{
|
||||
#ifdef SERVER
|
||||
static void Die(void) {
|
||||
remove(self);
|
||||
}
|
||||
|
@ -128,19 +288,24 @@ func_tankmortar::SpriteFlash(vector org)
|
|||
smoke.nextthink = time + 0.1f;
|
||||
smoke.scale = m_flSpriteScale;
|
||||
smoke.effects = EF_FLAG2;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
func_tankmortar::customphysics(void)
|
||||
func_tankmortar::PlayerInput(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
if (m_eDriver && m_eDriver.health <= 0)
|
||||
PlayerLeave((base_player)m_eDriver);
|
||||
#else
|
||||
print("foooo\n");
|
||||
#endif
|
||||
|
||||
if (m_eDriver) {
|
||||
vector wantang, endang;
|
||||
vector aimorg;
|
||||
|
||||
makevectors(m_eDriver.v_angle);
|
||||
makevectors(input_angles);
|
||||
aimorg = m_eDriver.origin + v_forward * 4086;
|
||||
|
||||
/* lerp */
|
||||
|
@ -148,17 +313,14 @@ func_tankmortar::customphysics(void)
|
|||
wantang = v_forward;
|
||||
makevectors(angles);
|
||||
|
||||
endang[0] = Math_Lerp(v_forward[0], wantang[0], frametime);
|
||||
endang[1] = Math_Lerp(v_forward[1], wantang[1], frametime);
|
||||
endang[2] = Math_Lerp(v_forward[2], wantang[2], frametime);
|
||||
endang[0] = Math_Lerp(v_forward[0], wantang[0], input_timelength);
|
||||
endang[1] = Math_Lerp(v_forward[1], wantang[1], input_timelength);
|
||||
endang[2] = Math_Lerp(v_forward[2], wantang[2], input_timelength);
|
||||
angles = vectoangles(endang);
|
||||
PlayerUpdateFlags();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
func_tankmortar::PlayerInput(void)
|
||||
{
|
||||
#ifdef SERVER
|
||||
if (m_flFireTime < time)
|
||||
if (input_buttons & INPUT_BUTTON0) {
|
||||
vector spos;
|
||||
|
@ -191,8 +353,10 @@ func_tankmortar::PlayerInput(void)
|
|||
}
|
||||
|
||||
input_buttons &= ~INPUT_BUTTON0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SERVER
|
||||
void
|
||||
func_tankmortar::Respawn(void)
|
||||
{
|
||||
|
@ -265,6 +429,7 @@ func_tankmortar::SpawnKey(string strKey, string strValue)
|
|||
CBaseTrigger::SpawnKey(strValue, strKey);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
func_tankmortar::func_tankmortar(void)
|
||||
|
@ -273,9 +438,24 @@ func_tankmortar::func_tankmortar(void)
|
|||
|
||||
CBaseVehicle::CBaseVehicle();
|
||||
|
||||
#ifdef SERVER
|
||||
if (m_strSpriteFlash)
|
||||
precache_model(m_strSpriteFlash);
|
||||
if (m_strSpriteSmoke)
|
||||
precache_model(m_strSpriteSmoke);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CLIENT
|
||||
void
|
||||
func_tankmortar_readentity(float isnew)
|
||||
{
|
||||
func_tankmortar veh = (func_tankmortar)self;
|
||||
float flags = readfloat();
|
||||
|
||||
if (isnew)
|
||||
spawnfunc_func_tankmortar();
|
||||
|
||||
veh.ReadEntity(flags, isnew);
|
||||
}
|
||||
#endif
|
|
@ -32,6 +32,7 @@ enum
|
|||
ENT_OLDCAMERA,
|
||||
ENT_MONITOR,
|
||||
ENT_VEHICLE,
|
||||
ENT_VEH_TANKMORTAR,
|
||||
ENT_SEPARATOR,
|
||||
};
|
||||
|
||||
|
|
|
@ -50,10 +50,13 @@ base_player::ReceiveEntity(float new, float fl)
|
|||
origin[2] = readcoord();
|
||||
if (fl & PLAYER_ANGLES_X) {
|
||||
v_angle[0] = pitch = readshort() / (32767 / 360);
|
||||
v_angle[1] = pitch = readshort() / (32767 / 360);
|
||||
v_angle[2] = pitch = readshort() / (32767 / 360);
|
||||
}
|
||||
if (fl & PLAYER_ANGLES_Y) {
|
||||
angles[0] = readshort() / (32767 / 360);
|
||||
angles[1] = readshort() / (32767 / 360);
|
||||
angles[1] = readshort() / (32767 / 360);
|
||||
v_angle[1] = readshort() / (32767 / 360);
|
||||
}
|
||||
if (fl & PLAYER_COLORMAP)
|
||||
colormap = readbyte();
|
||||
|
@ -213,10 +216,10 @@ base_player::EvaluateEntity(void)
|
|||
if (VEC_CHANGED(origin, 2))
|
||||
SetSendFlags(PLAYER_ORIGIN_Z);
|
||||
|
||||
if (VEC_CHANGED(v_angle, 0))
|
||||
if (VEC_CHANGED(v_angle, 0) || VEC_CHANGED(v_angle, 1) || VEC_CHANGED(v_angle, 2))
|
||||
SetSendFlags(PLAYER_ANGLES_X);
|
||||
|
||||
if (VEC_CHANGED(angles, 1))
|
||||
if (VEC_CHANGED(angles, 0) || VEC_CHANGED(angles, 1) || VEC_CHANGED(angles, 2))
|
||||
SetSendFlags(PLAYER_ANGLES_Y);
|
||||
|
||||
if (ATTR_CHANGED(colormap))
|
||||
|
@ -311,10 +314,13 @@ base_player::SendEntity(entity ePEnt, float fChanged)
|
|||
|
||||
if (fChanged & PLAYER_ANGLES_X) {
|
||||
WriteShort(MSG_ENTITY, v_angle[0] * 32767 / 360);
|
||||
WriteShort(MSG_ENTITY, v_angle[1] * 32767 / 360);
|
||||
WriteShort(MSG_ENTITY, v_angle[2] * 32767 / 360);
|
||||
}
|
||||
if (fChanged & PLAYER_ANGLES_Y) {
|
||||
WriteShort(MSG_ENTITY, angles[0] * 32767 / 360);
|
||||
WriteShort(MSG_ENTITY, angles[1] * 32767 / 360);
|
||||
WriteShort(MSG_ENTITY, v_angle[1] * 32767 / 360);
|
||||
WriteShort(MSG_ENTITY, angles[2] * 32767 / 360);
|
||||
}
|
||||
if (fChanged & PLAYER_COLORMAP)
|
||||
WriteByte(MSG_ENTITY, colormap);
|
||||
|
|
Loading…
Reference in a new issue