Kill src/client/player.qc. We now have overridable methods dedicated for updating player animations, attachments and more inside NSClientPlayer.

Some of these APIs are still subject to change but they're being deployed in TW 1.35 right now.
This commit is contained in:
Marco Cawthorne 2022-11-01 19:12:40 -07:00
parent 2945e1f65d
commit 843dcc8284
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
12 changed files with 190 additions and 105 deletions

View File

@ -57,6 +57,8 @@ private:
vector m_vecClientAngle;
bool m_bSetClientAngle;
bool m_bDrawLocalPlayer;
public:
void NSView(void);
@ -82,6 +84,8 @@ public:
virtual void SetViewSize(vector);
virtual void SetViewTarget(NSEntity);
virtual void SetClientOwner(NSClient);
virtual void SetDrawLocalPlayer(bool);
virtual void SetCameraOrigin(vector);
virtual void SetCameraAngle(vector);

View File

@ -38,8 +38,11 @@ NSView::SetupView(void)
setproperty(VF_AFOV, m_flFieldOfView);
setsensitivityscaler(m_flSensitivity);
/* this will hide said entity */
setproperty(VF_VIEWENTITY, player_localentnum);
/* if yes, draw everything. */
if (m_bDrawLocalPlayer)
setproperty(VF_VIEWENTITY, 0);
else
setproperty(VF_VIEWENTITY, player_localentnum);
/* handle camera override */
if (pSeat->m_flCameraTime > time || pSeat->m_flCameraTime == -1) {
@ -69,6 +72,12 @@ NSView::RenderView(void)
renderscene();
}
void
NSView::SetDrawLocalPlayer(bool choice)
{
m_bDrawLocalPlayer = choice;
}
void
NSView::StairSmooth(void)
{

View File

@ -11,7 +11,6 @@ voice.qc
fade.qc
titles.qc
text.qc
player.qc
predict.qc
entities.qc
modelevent.qc

View File

@ -1,101 +0,0 @@
/*
* Copyright (c) 2016-2022 Vera Visions LLC.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
void
player::draw(void)
{
/* mouth flapping */
this.bonecontrol5 = getplayerkeyfloat(this.entnum - 1, "voiploudness");
#if 0
/* DEBUG! */
if (cvar("bonetest") == 1) {
this.bonecontrol1 = cvar("bonecontrol1");
this.bonecontrol2 = cvar("bonecontrol2");
this.bonecontrol3 = cvar("bonecontrol3");
this.bonecontrol4 = cvar("bonecontrol4");
this.bonecontrol5 = cvar("bonecontrol5");
this.subblendfrac = cvar("subblendfrac");
this.subblend2frac = cvar("subblend2frac");
this.basesubblendfrac = cvar("basesubblendfrac");
this.basesubblend2frac = cvar("basesubblend2frac");
}
#endif
}
float
player::predraw(void)
{
int this_us = 0;
super::predraw();
/* run animations regardless of rendering the player */
draw();
/* make sure we're enabling shadow rendering on us */
effects &= ~EF_NOSHADOW;
NSClient cl = (NSClient)pSeat->m_ePlayer;
RenderFire();
/* it's either us or us spectating */
if (Client_IsSpectator(cl)) {
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;
if (entnum == spec.spec_ent && spec.spec_mode == SPECMODE_FIRSTPERSON) {
this_us = 1;
}
} else {
if (entnum == player_localentnum) {
this_us = 1;
}
}
if (this_us && flags & FL_INVEHICLE) {
NSVehicle veh = (NSVehicle)vehicle;
if (veh)
this_us = veh.HidePlayermodel();
}
if (autocvar_cl_thirdperson == TRUE || !this_us) {
renderflags &= ~RF_EXTERNALMODEL;
Voice_Draw3D(this);
Player_PreDraw(this, TRUE);
if (p_model) {
p_model.renderflags &= ~RF_EXTERNALMODEL;
addentity(p_model);
}
//addentity(this);
} else {
renderflags |= RF_EXTERNALMODEL;
Player_PreDraw(this, FALSE);
if (p_model) {
p_model.renderflags |= RF_EXTERNALMODEL;
addentity(p_model);
}
addentity(this);
}
return (PREDRAW_NEXT);
}
void
player::postdraw(void)
{
}

View File

@ -33,3 +33,6 @@ float Client_IsPlayer(NSClient cl);
float Client_InIntermission(void);
string Util_GetKeyString(string);
bool Client_InVehicle(void);

View File

@ -47,6 +47,13 @@ Client_IsPlayer(NSClient cl)
return cl.IsPlayer();
}
bool
Client_InVehicle(void)
{
player pl = (player)pSeat->m_ePlayer;
return (pl.vehicle != world) ? true : false;
}
/*
=================
Util_GetKeyString

View File

@ -16,6 +16,8 @@
void TraceAttack_FireBullets(int iShots, vector vecPos, int iDamage, vector vecSpread, int iWeapon);
void TraceAttack_FireBulletsWithDecal(int iShots, vector vecPos, int iDamage, vector vecSpread, int iWeapon, string strDecalGroup);
#ifdef BULLETPENETRATION
void TraceAttack_SetPenetrationPower(int power);
#endif
@ -37,6 +39,8 @@ private:
entity m_eOwner;
float m_flRange;
vector m_vecOrigin;
//int m_iDecalGroup;
string m_strDecalGroup;
/* bullet penetration */
#ifdef BULLETPENETRATION
@ -68,6 +72,9 @@ public:
virtual void SetRange(float);
/** Sets the owner responsible for the trace. */
virtual void SetOwner(entity);
/** Sets the decal group used by the trace attack */
virtual void SetDecalGroup(string);
#ifdef BULLETPENETRATION
/** Sets the maximum thickness that the trace is not allowed to penetrate.

View File

@ -122,6 +122,8 @@ NSTraceAttack::_FireSingle(vector vecPos, vector vecAngles, float flDamage, floa
/* impact per bullet */
if (trace_ent.iBleeds == 0) {
if (m_strDecalGroup)
DecalGroups_Place(m_strDecalGroup, trace_endpos);
SurfData_Impact(trace_ent, trace_surfaceflagsi, trace_endpos, trace_plane_normal);
}
@ -250,6 +252,12 @@ NSTraceAttack::SetOwner(entity eOwner)
m_eOwner = eOwner;
}
void
NSTraceAttack::SetDecalGroup(string strGroupName)
{
//int m_iDecalGroup = DecalGroups_NumForName(strGroupName);
m_strDecalGroup = strGroupName;
}
#ifdef BULLETPENETRATION
void
@ -271,6 +279,8 @@ NSTraceAttack::NSTraceAttack(void)
m_iMultiValue = 0;
m_iMultiBody = 0;
m_flRange = 8196;
//m_iDecalGroup = -1;
m_strDecalGroup = __NULL__;
#ifdef BULLETPENETRATION
m_flMaxThickness = 5.0f;
@ -296,6 +306,23 @@ TraceAttack_FireBullets(int iShots, vector vecPos, int iDamage, vector vecSpread
g_traceAttack.Fire();
}
void
TraceAttack_FireBulletsWithDecal(int iShots, vector vecPos, int iDamage, vector vecSpread, int iWeapon, string strDecalGroup)
{
if (!g_traceAttack) {
g_traceAttack = spawn(NSTraceAttack);
}
g_traceAttack.SetShots(iShots);
g_traceAttack.SetOrigin(vecPos);
g_traceAttack.SetDamage(iDamage);
g_traceAttack.SetSpread(vecSpread);
g_traceAttack.SetWeapon(iWeapon);
g_traceAttack.SetOwner(self);
g_traceAttack.SetDecalGroup(strDecalGroup);
g_traceAttack.Fire();
}
#ifdef BULLETPENETRATION
void
TraceAttack_SetRangeModifier(float units)

View File

@ -90,6 +90,9 @@ NSClientPlayer:NSClientSpectator
virtual bool(void) IsDead;
virtual bool(void) IsPlayer;
/** Empty & shared between Client and Server. This is run on every player, every frame, to update their animation cycle. */
virtual void UpdatePlayerAnimation(void);
#ifdef CLIENT
int sequence;
@ -106,6 +109,15 @@ NSClientPlayer:NSClientSpectator
virtual void(void) PredictPostFrame;
virtual void(void) ClientInputFrame;
virtual void(void) UpdateAliveCam;
virtual float predraw(void);
virtual void postdraw(void);
/** Empty. Updates the bone controller responsible for mouth movement. */
virtual void UpdatePlayerJaw(float);
/** Empty. This is run on every player, every frame to update attachments. */
virtual void UpdatePlayerAttachments(bool);
#else
int voted;
int step;

View File

@ -138,7 +138,118 @@ NSClientPlayer::ClientInput(void)
Game_Input((player)this);
}
/* this is where it gets mod specific really fast,
as some models may not even support skeletal animation */
void
NSClientPlayer::UpdatePlayerAnimation(void)
{
}
#ifdef CLIENT
void
NSClientPlayer::UpdatePlayerJaw(float voip_volume)
{
}
void
NSClientPlayer::UpdatePlayerAttachments(bool visible)
{
}
float
NSClientPlayer::predraw(void)
{
bool localplayer = false;
NSClient cl = (NSClient)pSeat->m_ePlayer;
/* figure out if this is the local player. it's either us or us spectating */
if (Client_IsSpectator(cl)) {
NSClientSpectator spec = (NSClientSpectator)pSeat->m_ePlayer;
if (entnum == spec.spec_ent && spec.spec_mode == SPECMODE_FIRSTPERSON) {
localplayer = true;
}
} else {
if (entnum == player_localentnum) {
localplayer = true;
}
}
/* make sure we're enabling shadow rendering on us! */
effects &= ~EF_NOSHADOW;
/* always advance the player animation in some way */
UpdatePlayerAnimation();
/* mouth flapping */
UpdatePlayerJaw(getplayerkeyfloat(this.entnum - 1, "voiploudness"));
/* apply any necessary filters from NSRenderableEntity */
RenderFXPass();
/* apply any fire effects, if we're burning (we're of type NSSurfacePropEntity that can burn) */
RenderFire();
/* if we're inside of a vehicle, it may want to hide or show us regardless */
if (localplayer && flags & FL_INVEHICLE) {
NSVehicle veh = (NSVehicle)vehicle;
if (veh)
localplayer = veh.HidePlayermodel();
}
/* if we're forcing third-person.. or this is not us - render this player */
if (autocvar_cl_thirdperson == TRUE || !localplayer) {
/* mark as not-mirror-only */
renderflags &= ~RF_EXTERNALMODEL;
/* same for our attachment */
if (p_model)
p_model.renderflags &= ~RF_EXTERNALMODEL;
/* let mods override attachments and whatnot */
UpdatePlayerAttachments(true);
/* draw a 3D voice blob over its head */
Voice_Draw3D(this);
/* force drawing us if it's our local player and we're meant to show */
if (entnum == player_localentnum)
g_view.SetDrawLocalPlayer(true);
/* sucks we can't draw a shadow on this thing, maybe in the future when FTEQW allows it */
if (p_model)
addentity(p_model);
} else { /* we're doing first person stuff */
/* flags that the model appear in mirrors only */
renderflags |= RF_EXTERNALMODEL;
/* ditto */
if (p_model)
p_model.renderflags |= RF_EXTERNALMODEL;
/* give mods a chance to de-render attachments */
UpdatePlayerAttachments(false);
/* this is here just to make sure our view hides us if it's the local player */
if (entnum == player_localentnum)
g_view.SetDrawLocalPlayer(false);
}
/* this needs to be called absolutely last */
/* we're calling this so that the shadow can still be drawn */
addentity(this);
return (PREDRAW_NEXT);
}
void
NSClientPlayer::postdraw(void)
{
}
void
NSClientPlayer::VehicleRelink(void)
{

View File

@ -29,6 +29,7 @@
/* public API */
void DecalGroups_Init(void);
void DecalGroups_Place(string group, vector org);
int DecalGroups_NumForName(string group);
#ifdef CLIENT
void DecalGroups_Receive(void);

View File

@ -159,11 +159,17 @@ DecalGroups_PlaceGroupID(int index, vector org)
}
#endif
int
DecalGroups_NumForName(string group)
{
return (int)hash_get(g_hashdecalgroup, group, -1);
}
void
DecalGroups_Place(string group, vector org)
{
int index;
index = (int)hash_get(g_hashdecalgroup, group, -1);
index = (int)hash_get(g_hashdecalgroup, strtolower(group), -1);
#ifdef SERVER
/* on the server we only need to tell the clients in the PVS