Add UpdateView() to CBaseVehicle, to let vehicles override the

camera properties in CSQC_UpdateView before rendering.
This commit is contained in:
Marco Cawthorne 2021-09-01 15:17:35 +02:00
parent 0bc83d289d
commit 57f1408b8c
6 changed files with 105 additions and 33 deletions

View File

@ -298,14 +298,13 @@ CSQC_UpdateView(float w, float h, float focus)
} else {
if (self.classname == "player") {
pl = (player)self;
setproperty(VF_ORIGIN, pSeat->m_vecPredictedOrigin + pl.view_ofs);
if (pl.flags & FL_INVEHICLE) {
CBaseVehicle veh = (CBaseVehicle)pl.vehicle;
pSeat->m_vecPredictedOrigin = veh.origin;
makevectors(view_angles);
vector vStart = [pSeat->m_vecPredictedOrigin[0], pSeat->m_vecPredictedOrigin[1], pSeat->m_vecPredictedOrigin[2] + 16] + (v_right * 4);
vector vEnd = vStart + (v_forward * -256) + [0,0,16] + (v_right * 4);
traceline(vStart, vEnd, FALSE, self);
setproperty(VF_ORIGIN, trace_endpos + (v_forward * 16));
if (veh.UpdateView)
veh.UpdateView();
} else if (pl.health) {
if (autocvar_cl_thirdperson == TRUE) {
makevectors(view_angles);
@ -313,11 +312,7 @@ CSQC_UpdateView(float w, float h, float focus)
vector vEnd = vStart + (v_forward * -48) + [0,0,16] + (v_right * 4);
traceline(vStart, vEnd, FALSE, self);
setproperty(VF_ORIGIN, trace_endpos + (v_forward * 5));
} else {
setproperty(VF_ORIGIN, pSeat->m_vecPredictedOrigin + pl.view_ofs);
}
} else {
setproperty(VF_ORIGIN, pSeat->m_vecPredictedOrigin);
}
if (pSeat->m_flShakeDuration > 0.0) {

View File

@ -239,7 +239,6 @@ View_PlayAnimation(int iSequence)
{
pSeat->m_eViewModel.frame = (float)iSequence;
player pl = (player)pSeat->m_ePlayer;
pl.weapontime = 0.0f;
}
int

View File

@ -8,6 +8,7 @@ class CBaseVehicle:CBaseTrigger
vector m_vecMoveValues;
entity m_eDriver;
entity m_eDriver_net;
void(void) CBaseVehicle;
vector m_vecPlayerPos;
@ -20,6 +21,7 @@ class CBaseVehicle:CBaseTrigger
virtual void(void) PredictPreFrame;
virtual void(void) PredictPostFrame;
virtual void(float, float) ReadEntity;
virtual void(void) UpdateView;
#else
virtual float(entity, float) SendEntity;
#endif
@ -29,4 +31,16 @@ class CBaseVehicle:CBaseTrigger
virtual void(base_player) PlayerEnter;
virtual void(base_player) PlayerLeave;
virtual void() PlayerInput;
};
};
enumflags
{
VEHFL_CHANGED_ORIGIN,
VEHFL_CHANGED_ANGLES,
VEHFL_CHANGED_MODELINDEX,
VEHFL_CHANGED_SOLID,
VEHFL_CHANGED_MOVETYPE,
VEHFL_CHANGED_SIZE,
VEHFL_CHANGED_VELOCITY,
VEHFL_CHANGED_DRIVER
};

View File

@ -21,6 +21,19 @@ enumflags
};
#ifdef CLIENT
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
CBaseVehicle::PredictPreFrame(void)
{
@ -40,33 +53,31 @@ CBaseVehicle::PredictPostFrame(void)
void
CBaseVehicle::ReadEntity(float fChanged, float new)
{
m_eDriver = findfloat(world, ::entnum, readentitynum());
if (fChanged & BASEFL_CHANGED_ORIGIN) {
if (fChanged & VEHFL_CHANGED_ORIGIN) {
origin[0] = readcoord();
origin[1] = readcoord();
origin[2] = readcoord();
}
if (fChanged & BASEFL_CHANGED_ANGLES) {
if (fChanged & VEHFL_CHANGED_ANGLES) {
angles[0] = readshort() / (32767 / 360);
angles[1] = readshort() / (32767 / 360);
angles[2] = readshort() / (32767 / 360);
}
if (fChanged & BASEFL_CHANGED_MODELINDEX) {
if (fChanged & VEHFL_CHANGED_MODELINDEX) {
setmodelindex(this, readshort());
}
if (fChanged & BASEFL_CHANGED_SOLID) {
if (fChanged & VEHFL_CHANGED_SOLID) {
solid = readbyte();
}
if (fChanged & BASEFL_CHANGED_MOVETYPE) {
if (fChanged & VEHFL_CHANGED_MOVETYPE) {
movetype = readbyte();
}
if (fChanged & BASEFL_CHANGED_SIZE) {
if (fChanged & VEHFL_CHANGED_SIZE) {
mins[0] = readcoord();
mins[1] = readcoord();
mins[2] = readcoord();
@ -75,50 +86,75 @@ CBaseVehicle::ReadEntity(float fChanged, float new)
maxs[2] = readcoord();
}
if (fChanged & BASEFL_CHANGED_VELOCITY) {
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
CBaseVehicle::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;
SendFlags |= 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;
SendFlags |= VEHFL_CHANGED_ANGLES;
}
if (net_velocity != velocity) {
net_velocity = velocity;
SendFlags |= VEHFL_CHANGED_VELOCITY;
}
}
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) {
if (fChanged & VEHFL_CHANGED_ORIGIN) {
WriteCoord(MSG_ENTITY, origin[0]);
WriteCoord(MSG_ENTITY, origin[1]);
WriteCoord(MSG_ENTITY, origin[2]);
}
if (fChanged & BASEFL_CHANGED_ANGLES) {
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 & BASEFL_CHANGED_MODELINDEX) {
if (fChanged & VEHFL_CHANGED_MODELINDEX) {
WriteShort(MSG_ENTITY, modelindex);
}
if (fChanged & BASEFL_CHANGED_SOLID) {
if (fChanged & VEHFL_CHANGED_SOLID) {
WriteByte(MSG_ENTITY, solid);
}
if (fChanged & BASEFL_CHANGED_MOVETYPE) {
if (fChanged & VEHFL_CHANGED_MOVETYPE) {
WriteByte(MSG_ENTITY, movetype);
}
if (fChanged & BASEFL_CHANGED_SIZE) {
if (fChanged & VEHFL_CHANGED_SIZE) {
WriteCoord(MSG_ENTITY, mins[0]);
WriteCoord(MSG_ENTITY, mins[1]);
WriteCoord(MSG_ENTITY, mins[2]);
@ -127,12 +163,16 @@ CBaseVehicle::SendEntity(entity ePEnt, float fChanged)
WriteCoord(MSG_ENTITY, maxs[2]);
}
if (fChanged & BASEFL_CHANGED_VELOCITY) {
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
@ -184,14 +224,18 @@ CBaseVehicle::PlayerEnter(base_player pl)
pl.movetype = MOVETYPE_NOCLIP;
m_eDriver = (entity)pl;
pl.vehicle = this;
//pl.flags |= FL_INVEHICLE;
pl.flags |= FL_INVEHICLE;
#ifdef SERVER
SendFlags |= VEHFL_CHANGED_DRIVER;
#endif
}
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;
@ -201,6 +245,10 @@ CBaseVehicle::PlayerLeave(base_player pl)
pl.vehicle = __NULL__;
m_eDriver = __NULL__;
#ifdef SERVER
SendFlags |= VEHFL_CHANGED_DRIVER;
#endif
}
void

View File

@ -14,7 +14,7 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*QUAKED info_particle_system (1 0 0) (-8 -8 -8) (8 8 8)
/*QUAKED info_particle_system (1 0 0) (-8 -8 -8) (8 8 8) PSFL_STARTACTIVE
An entity that's spawns particles from the engine's particle system.
-------- KEYS --------

View File

@ -108,6 +108,22 @@ precache_model(string m)
return prior(m);
}
/* this could probably be a lot better, use this from now on so that it can be improved later */
noref int input_sequence;
float
pseudorandom()
{
float a = (float)input_sequence % 5;
float b = (float)input_sequence % 8;
float c = (float)input_sequence % 4;
float d = (float)input_sequence % 13;
float f = (float)input_sequence % 70;
print(sprintf("random %f\n", (a+b+c+d+f) / 100.0f));
/* like the engine its random(), never return 0, never return 1 */
return bound(0.01, (a+b+c+d+f) / 100.0f, 0.99f);
}
__wrap void
setmodel(entity ent, string mname)
{