Client: Allow mods to override entity updates of gs-entbase.
prop_vehicle_drivable: Initial work towards suspension.
This commit is contained in:
parent
22ab20a7b4
commit
47a37af545
8 changed files with 707 additions and 585 deletions
|
@ -200,4 +200,8 @@ struct
|
|||
float m_flShakeAmp;
|
||||
|
||||
vector m_vecLag;
|
||||
|
||||
/* vehicles */
|
||||
float m_flVehTransition;
|
||||
vector m_vecVehEntry;
|
||||
} g_seats[4], *pSeat;
|
||||
|
|
|
@ -45,6 +45,7 @@ CSQC_Init(float apilevel, string enginename, float engineversion)
|
|||
registercommand("player_geomtest");
|
||||
registercommand("way_menu");
|
||||
registercommand("dev_explode");
|
||||
registercommand("dev_modeltest");
|
||||
|
||||
/* basic actions */
|
||||
registercommand("+attack");
|
||||
|
@ -660,6 +661,15 @@ CSQC_ConsoleCommand(string sCMD)
|
|||
traceline(getproperty(VF_ORIGIN), getproperty(VF_ORIGIN) + v_forward * 4096, FALSE, pSeat->m_ePlayer);
|
||||
dynamiclight_spawnstatic(trace_endpos + (v_forward * -16), 1024, [1,1,1]);
|
||||
break;
|
||||
case "dev_modeltest":
|
||||
entity mt = spawn();
|
||||
mt.drawmask = MASK_ENGINE;
|
||||
setmodel(mt, argv(1));
|
||||
setsize(mt, [0,0,0], [0,0,0]);
|
||||
setorigin(mt, getproperty(VF_ORIGIN));
|
||||
mt.angles = getproperty(VF_ANGLES);
|
||||
mt.angles[0] = mt.angles[2] = 0;
|
||||
break;
|
||||
case "dev_explode":
|
||||
makevectors(getproperty(VF_ANGLES));
|
||||
traceline(getproperty(VF_ORIGIN), getproperty(VF_ORIGIN) + v_forward * 4096, FALSE, pSeat->m_ePlayer);
|
||||
|
@ -880,6 +890,11 @@ CSQC_Ent_Update(float new)
|
|||
float t;
|
||||
t = readbyte();
|
||||
|
||||
/* client didn't override anything */
|
||||
if (ClientGame_EntityUpdate(t, new)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (t) {
|
||||
case ENT_ENTITY:
|
||||
NSEntity me = (NSEntity)self;
|
||||
|
@ -985,9 +1000,7 @@ CSQC_Ent_Update(float new)
|
|||
ips.ReceiveEntity(new, readfloat());
|
||||
break;
|
||||
default:
|
||||
if (ClientGame_EntityUpdate(t, new) == FALSE) {
|
||||
//error(sprintf("Unknown entity type update received. (%d)\n", t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ class NSEntity:NSTrigger
|
|||
vector net_origin;
|
||||
vector net_angles;
|
||||
vector net_velocity;
|
||||
float net_modelindex;
|
||||
|
||||
string m_parent;
|
||||
|
||||
|
|
|
@ -30,12 +30,24 @@ Point entity defining a 4-wheel vehicle that you can drive.
|
|||
This entity was introduced in Half-Life 2 (2004).
|
||||
*/
|
||||
|
||||
enumflags
|
||||
{
|
||||
VEHFL_DRIVER,
|
||||
VEHFL_MODELINDEX,
|
||||
VEHFL_ORIGIN,
|
||||
VEHFL_ANGLES,
|
||||
VEHFL_VELOCITY,
|
||||
VEHFL_TURNING
|
||||
};
|
||||
|
||||
class prop_vehicle_driveable_wheel
|
||||
{
|
||||
void() prop_vehicle_driveable_wheel;
|
||||
float m_flSuspension;
|
||||
float m_flSuspensionForce;
|
||||
|
||||
#ifdef CLIENT
|
||||
|
||||
vector origin_net;
|
||||
vector velocity_net;
|
||||
vector angles_net;
|
||||
|
@ -43,6 +55,7 @@ class prop_vehicle_driveable_wheel
|
|||
virtual void(void) PredictPostFrame;
|
||||
#endif
|
||||
|
||||
virtual void(float) UpdateSuspension;
|
||||
virtual void(float) Move;
|
||||
virtual void(vector) Bounce;
|
||||
virtual void(float, float m_flTurn) Accel;
|
||||
|
@ -87,6 +100,7 @@ class prop_vehicle_driveable:NSVehicle
|
|||
#else
|
||||
virtual void(void) Respawn;
|
||||
virtual void(void) OnPlayerUse;
|
||||
virtual void(void) EvaluateEntity;
|
||||
virtual float(entity, float) SendEntity;
|
||||
#endif
|
||||
};
|
||||
|
@ -301,6 +315,26 @@ prop_vehicle_driveable_wheel::Accel(float flMoveTime, float m_flTurn)
|
|||
velocity += vehParent.m_vecGravityDir * flMoveTime * serverkeyfloat("phy_gravity") * trace_fraction;
|
||||
}
|
||||
|
||||
void
|
||||
prop_vehicle_driveable_wheel::UpdateSuspension(float flTimeLength)
|
||||
{
|
||||
float flDamp;
|
||||
float flForce;
|
||||
|
||||
if (fabs(m_flSuspension) > 0.001 || fabs(m_flSuspensionForce) > 0.001) {
|
||||
m_flSuspension += m_flSuspensionForce * flTimeLength;
|
||||
|
||||
flForce = bound(0, flTimeLength * 65, 2);
|
||||
flDamp = 1 - (flTimeLength * 4);
|
||||
if (flDamp < 0) {
|
||||
flDamp = 0;
|
||||
}
|
||||
m_flSuspensionForce *= flDamp;
|
||||
m_flSuspensionForce -= m_flSuspension * flForce;
|
||||
m_flSuspension = bound(-15, m_flSuspension, 15);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prop_vehicle_driveable_wheel::Physics(float turnrate, float flTimeLength)
|
||||
{
|
||||
|
@ -311,9 +345,23 @@ prop_vehicle_driveable_wheel::Physics(float turnrate, float flTimeLength)
|
|||
tracebox(owner_pos, mins, maxs, origin, MOVE_NOMONSTERS, owner);
|
||||
setorigin(this, trace_endpos);
|
||||
|
||||
/* see if we're in-air */
|
||||
other = world;
|
||||
tracebox(origin, mins, maxs, origin - [0,0,1], MOVE_OTHERONLY, this);
|
||||
if (!trace_startsolid) {
|
||||
if ((trace_fraction < 1) && (trace_plane_normal[2] > 0.7)) {
|
||||
flags |= FL_ONGROUND;
|
||||
} else {
|
||||
flags &= ~FL_ONGROUND;
|
||||
m_flSuspensionForce += flTimeLength * 200.0;
|
||||
}
|
||||
}
|
||||
|
||||
Accel(flTimeLength / 2, turnrate);
|
||||
Move(flTimeLength);
|
||||
Accel(flTimeLength / 2, turnrate);
|
||||
UpdateSuspension(flTimeLength);
|
||||
print(sprintf("suspension: %d, force: %d\n", m_flSuspension, m_flSuspensionForce));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -405,8 +453,6 @@ prop_vehicle_driveable::RunVehiclePhysics(void)
|
|||
angles[0] = Math_FixDelta(angles[0]);
|
||||
angles[1] = Math_FixDelta(angles[1]);
|
||||
angles[2] = Math_FixDelta(angles[2]);
|
||||
angles[0] = bound(-45, angles[0], 45);
|
||||
angles[2] = bound(-45, angles[2], 45);
|
||||
|
||||
velocity[0] = bound(-1000, velocity[0], 1000);
|
||||
velocity[1] = bound(-1000, velocity[1], 1000);
|
||||
|
@ -504,23 +550,34 @@ prop_vehicle_driveable::Respawn(void)
|
|||
void
|
||||
prop_vehicle_driveable::ReadEntity(float flSendFlags, float flNew)
|
||||
{
|
||||
m_eDriver = findfloat(world, ::entnum, readentitynum());
|
||||
if (flSendFlags & VEHFL_DRIVER) {
|
||||
m_eDriver = findfloat(world, ::entnum, readentitynum());
|
||||
}
|
||||
|
||||
modelindex = readshort();
|
||||
if (flSendFlags & VEHFL_MODELINDEX) {
|
||||
modelindex = readshort();
|
||||
}
|
||||
|
||||
origin[0] = readcoord();
|
||||
origin[1] = readcoord();
|
||||
origin[2] = readcoord();
|
||||
if (flSendFlags & VEHFL_ORIGIN) {
|
||||
origin[0] = readcoord();
|
||||
origin[1] = readcoord();
|
||||
origin[2] = readcoord();
|
||||
}
|
||||
|
||||
angles[0] = readfloat();
|
||||
angles[1] = readfloat();
|
||||
angles[2] = readfloat();
|
||||
if (flSendFlags & VEHFL_ANGLES) {
|
||||
angles[0] = readfloat();
|
||||
angles[1] = readfloat();
|
||||
angles[2] = readfloat();
|
||||
}
|
||||
|
||||
velocity[0] = readfloat();
|
||||
velocity[1] = readfloat();
|
||||
velocity[2] = readfloat();
|
||||
if (flSendFlags & VEHFL_VELOCITY) {
|
||||
velocity[0] = readfloat();
|
||||
velocity[1] = readfloat();
|
||||
velocity[2] = readfloat();
|
||||
}
|
||||
|
||||
m_flTurn = readfloat();
|
||||
if (flSendFlags & VEHFL_TURNING)
|
||||
m_flTurn = readfloat();
|
||||
|
||||
if (flNew) {
|
||||
drawmask = MASK_ENGINE;
|
||||
|
@ -532,29 +589,76 @@ prop_vehicle_driveable::ReadEntity(float flSendFlags, float flNew)
|
|||
}
|
||||
}
|
||||
#else
|
||||
void
|
||||
prop_vehicle_driveable::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_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_ANGLES);
|
||||
}
|
||||
if (net_modelindex != modelindex) {
|
||||
net_modelindex = modelindex;
|
||||
SetSendFlags(VEHFL_MODELINDEX);
|
||||
}
|
||||
if (net_velocity != velocity) {
|
||||
net_velocity = velocity;
|
||||
SetSendFlags(VEHFL_VELOCITY);
|
||||
}
|
||||
if (m_flTurn_net != m_flTurn) {
|
||||
m_flTurn_net = m_flTurn;
|
||||
SetSendFlags(VEHFL_TURNING);
|
||||
}
|
||||
if (m_eDriver_net != m_eDriver) {
|
||||
m_eDriver_net = m_eDriver;
|
||||
SetSendFlags(VEHFL_DRIVER);
|
||||
}
|
||||
}
|
||||
|
||||
float
|
||||
prop_vehicle_driveable::SendEntity(entity ePVSent, float flSendFlags)
|
||||
{
|
||||
WriteByte(MSG_ENTITY, ENT_VEH_4WHEEL);
|
||||
WriteFloat(MSG_ENTITY, flSendFlags);
|
||||
|
||||
WriteEntity(MSG_ENTITY, m_eDriver);
|
||||
if (flSendFlags & VEHFL_DRIVER) {
|
||||
WriteEntity(MSG_ENTITY, m_eDriver);
|
||||
}
|
||||
|
||||
WriteShort(MSG_ENTITY, modelindex);
|
||||
if (flSendFlags & VEHFL_MODELINDEX) {
|
||||
WriteShort(MSG_ENTITY, modelindex);
|
||||
}
|
||||
|
||||
WriteCoord(MSG_ENTITY, origin[0]);
|
||||
WriteCoord(MSG_ENTITY, origin[1]);
|
||||
WriteCoord(MSG_ENTITY, origin[2]);
|
||||
if (flSendFlags & VEHFL_ORIGIN) {
|
||||
WriteCoord(MSG_ENTITY, origin[0]);
|
||||
WriteCoord(MSG_ENTITY, origin[1]);
|
||||
WriteCoord(MSG_ENTITY, origin[2]);
|
||||
}
|
||||
|
||||
WriteFloat(MSG_ENTITY, angles[0]);
|
||||
WriteFloat(MSG_ENTITY, angles[1]);
|
||||
WriteFloat(MSG_ENTITY, angles[2]);
|
||||
if (flSendFlags & VEHFL_ANGLES) {
|
||||
WriteFloat(MSG_ENTITY, angles[0]);
|
||||
WriteFloat(MSG_ENTITY, angles[1]);
|
||||
WriteFloat(MSG_ENTITY, angles[2]);
|
||||
}
|
||||
|
||||
WriteFloat(MSG_ENTITY, velocity[0]);
|
||||
WriteFloat(MSG_ENTITY, velocity[1]);
|
||||
WriteFloat(MSG_ENTITY, velocity[2]);
|
||||
if (flSendFlags & VEHFL_VELOCITY) {
|
||||
WriteFloat(MSG_ENTITY, velocity[0]);
|
||||
WriteFloat(MSG_ENTITY, velocity[1]);
|
||||
WriteFloat(MSG_ENTITY, velocity[2]);
|
||||
}
|
||||
|
||||
if (flSendFlags & VEHFL_TURNING)
|
||||
WriteFloat(MSG_ENTITY, m_flTurn);
|
||||
|
||||
WriteFloat(MSG_ENTITY, m_flTurn);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue