Improved Q2 player model support, interpolation, etc.

This commit is contained in:
Marco Cawthorne 2019-08-07 10:58:56 -07:00
parent 8891e84e18
commit 21c8c88ec8
7 changed files with 80 additions and 23 deletions

View file

@ -74,6 +74,10 @@ void player::gun_offset(void)
setorigin(this.p_model, this.origin - ofs);
}
#ifdef VALVE
string Weapons_GetPlayermodel(int);
#endif
void player::draw(void)
{
if (!this.p_model) {
@ -82,6 +86,7 @@ void player::draw(void)
this.p_model.owner = this;
}
this.subblendfrac =
this.subblend2frac = this.pitch / 90;
/* Only bother updating the model if the weapon has changed */
@ -89,6 +94,8 @@ void player::draw(void)
if (this.activeweapon) {
#ifdef CSTRIKE
setmodel(this.p_model, sPModels[this.activeweapon - 1]);
#else
setmodel(this. p_model, Weapons_GetPlayermodel(this.activeweapon));
#endif
} else {
setmodel(this.p_model, "");
@ -162,7 +169,7 @@ void player::draw(void)
}
/* Turn torso */
this.subblendfrac = (a)/-120;
this.bonecontrol2 = (a)/-120;
/* Correct the legs */
this.angles[1] -= a;
@ -211,27 +218,45 @@ float player::predraw(void)
removeentity(this);
removeentity(this.p_model);
}
return PREDRAW_NEXT;
}
void player::set_model(void)
{
int i = tokenizebyseparator(getplayerkeyvalue(entnum-1, "model"), "/");
string out;
#ifdef VALVE
string modelout;
string skinpath;
string skinout;
int i;
i = tokenizebyseparator(getplayerkeyvalue(entnum-1, "model"), "/");
if (i == 1) {
playertype = 0;
out = sprintf("models/player/%s/%s.mdl", argv(0), argv(0));
print(sprintf("HL Player: %s\n", out));
playertype = PLAYERTYPE_HL;
modelout = sprintf("models/player/%s/%s.mdl", argv(0), argv(0));
} else {
playertype = 1;
out = sprintf("players/%s/tris.md2", argv(0));
print(sprintf("Q2 Player: %s\n", out));
playertype = PLAYERTYPE_Q2;
modelout = sprintf("players/%s/tris.md2", argv(0));
skinout = sprintf("players/%s/%s.pcx", argv(0), argv(1));
skinpath = sprintf("players/%s/%s.skin", argv(0), argv(1));
/* If the skin doesn't exist, make sure we fail */
if (whichpack(skinout)) {
} else {
print( sprintf( "Skin %s does not exist.\n", skinout ) );
skinpath = __NULL__;
skinout = __NULL__;
modelout = __NULL__;
}
}
if (whichpack(out))
setmodel(this, out);
else
if (modelout && whichpack(modelout)) {
setmodel(this, modelout);
if (playertype == PLAYERTYPE_Q2) {
setcustomskin(this, skinpath, sprintf("replace \"\" \"%s\"", skinout));
}
} else {
setmodel(this, "models/player.mdl");
playertype = PLAYERTYPE_HL;
}
#endif
}

View file

@ -39,8 +39,15 @@ void Player_ReadEntity(float flIsNew)
pl.viewzoom = readfloat();
pl.jumptime = readfloat();
pl.teleport_time = readfloat();
pl.baseframe = readbyte();
pl.frame = readbyte();
if (pl.playertype == 0) {
pl.baseframe = readbyte();
pl.frame = readbyte();
} else {
readbyte();
readbyte();
}
pl.a_ammo1 = readbyte();
pl.a_ammo2 = readbyte();
pl.a_ammo3 = readbyte();

View file

@ -182,7 +182,7 @@ void View_DrawViewModel(void)
return;
}
if (cvar("r_drawviewmodel") == 0) {
if (cvar("r_drawviewmodel") == 0 || autocvar_cl_thirdperson == TRUE) {
return;
}

View file

@ -87,5 +87,6 @@ string Weapons_GetWorldmodel(int id);
void Weapons_UpdateAmmo(player pl, int a1, int a2, int a3);
void Weapons_ReloadWeapon(player pl, .int mag, .int ammo, int max);
#else
string Weapons_GetPlayermodel(int id);
void Weapons_HUDPic(int w, int s, vector pos);
#endif

View file

@ -15,6 +15,7 @@
.float frame_last;
.float baseframe_last;
#else
.float subblendfrac;
.float subblend2frac;
#endif
@ -28,15 +29,31 @@ void Animation_Print( string sWow ) {
void Animation_Q2PlayerUpdate_Run(int id)
{
if (self.frame_time > time) {
#ifdef CSQC
/* Interpolation */
self.lerpfrac -= clframetime * 10;
if (self.lerpfrac < 0.0) {
self.lerpfrac = 0.0f;
}
if (self.frame_time > cltime) {
return;
}
if (self.frame >= q2_anims[id].start && self.frame <= q2_anims[id].end) {
self.frame += q2_anims[id].start;
/* Next animationf rame inbound, reset interpolation */
self.frame2 = self.frame;
self.lerpfrac = 1.0f;
/* Either advance frame (if we're in framgroup) or start new one */
if (self.frame >= q2_anims[id].start && self.frame < q2_anims[id].end) {
self.frame += 1;
} else {
self.frame = q2_anims[id].start;
}
self.frame_time = time + 0.1f;
/* Q2 runs at 10 Hz */
self.frame_time = cltime + 0.1f;
#endif
}
void Animation_Q2PlayerUpdate(void)
@ -68,6 +85,7 @@ depending on what the player is doing
*/
void Animation_PlayerUpdate( void ) {
self.basebone = 16;
#ifdef SSQC
// TODO: Make this faster
if ( self.frame_time < time ) {
@ -143,7 +161,7 @@ void Animation_PlayerUpdate( void ) {
self.baseframe1time = 0.0f;
}
self.bonecontrol1 = self.angles[0];
self.subblend2frac = self.angles[0];
#endif
self.angles[0] = self.angles[2] = 0;
@ -160,6 +178,7 @@ void Animation_PlayerUpdate( void ) {
#ifdef SSQC
// On the CSQC it's done in Player.c
self.subblendfrac =
self.subblend2frac = self.v_angle[0] / 90;
#endif
}

View file

@ -132,6 +132,10 @@ enum {
Q2ANIM_DEATH3,
};
void Animation_PlayerTop(float);
enum {
PLAYERTYPE_HL,
PLAYERTYPE_Q2
};
void Animation_PlayerTop(float);
void Animation_PlayerTopTemp(float, float);

View file

@ -85,5 +85,6 @@ string Weapons_GetWorldmodel(int id);
void Weapons_UpdateAmmo(player pl, int a1, int a2, int a3);
void Weapons_ReloadWeapon(player pl, .int mag, .int ammo, int max);
#else
string Weapons_GetPlayermodel(int id);
void Weapons_HUDPic(int w, int s, vector pos);
#endif