From d6e1463fd113457fdf9f6ece4e0a86688989697e Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 6 Jan 2012 17:42:27 +0100 Subject: [PATCH] forcemodels: handle missing model better --- qcsrc/client/View.qc | 2 + qcsrc/client/csqcmodel_hooks.qc | 81 +++++++++++++++++++++++------- qcsrc/client/main.qh | 1 + qcsrc/common/csqcmodel_settings.qh | 2 +- qcsrc/server/cl_weaponsystem.qc | 4 -- 5 files changed, 67 insertions(+), 23 deletions(-) diff --git a/qcsrc/client/View.qc b/qcsrc/client/View.qc index 556859a46..5ab52d5f1 100644 --- a/qcsrc/client/View.qc +++ b/qcsrc/client/View.qc @@ -372,6 +372,8 @@ void CSQC_UpdateView(float w, float h) vector vf_size, vf_min; float a; + ++framecount; + hud = getstati(STAT_HUD); if(checkextension("DP_CSQC_MINFPS_QUALITY")) diff --git a/qcsrc/client/csqcmodel_hooks.qc b/qcsrc/client/csqcmodel_hooks.qc index 92b8983b3..3c7368301 100644 --- a/qcsrc/client/csqcmodel_hooks.qc +++ b/qcsrc/client/csqcmodel_hooks.qc @@ -1,3 +1,5 @@ +void CSQCModel_Hook_PreDraw(); + .float isplayermodel; // FEATURE: LOD @@ -12,13 +14,6 @@ void CSQCPlayer_LOD_Apply(void) string modelname = self.model; string s; - if(!fexists(modelname)) - { - print(sprintf(_("Trying to use non existing model %s. "), modelname)); - modelname = cvar_defstring("_cl_playermodel"); - print(sprintf(_("Reverted to %s.\n"), modelname)); - } - // set modelindex self.lodmodelindex0 = self.modelindex; self.lodmodelindex1 = self.modelindex; @@ -72,17 +67,27 @@ void CSQCPlayer_LOD_Apply(void) // FEATURE: forcemodel (MUST be called BEFORE LOD!) string forceplayermodels_model; +float forceplayermodels_modelisgoodmodel; float forceplayermodels_modelindex; float forceplayermodels_skin; string forceplayermodels_mymodel; +float forceplayermodels_myisgoodmodel; float forceplayermodels_mymodelindex; float forceplayermodels_attempted; + .string forceplayermodels_savemodel; .float forceplayermodels_savemodelindex; .float forceplayermodels_saveskin; .float forceplayermodels_savecolormap; + +.string forceplayermodels_isgoodmodel_mdl; +.float forceplayermodels_isgoodmodel; + +string forceplayermodels_goodmodel; +float forceplayermodels_goodmodelindex; + void CSQCPlayer_ForceModel_PreUpdate(void) { self.model = self.forceplayermodels_savemodel; @@ -96,19 +101,38 @@ void CSQCPlayer_ForceModel_PostUpdate(void) self.forceplayermodels_savemodelindex = self.modelindex; self.forceplayermodels_saveskin = self.skin; self.forceplayermodels_savecolormap = self.colormap; + + if(self.forceplayermodels_savemodel != self.forceplayermodels_isgoodmodel_mdl) + { + self.forceplayermodels_isgoodmodel = fexists(self.forceplayermodels_savemodel); + self.forceplayermodels_isgoodmodel_mdl = self.forceplayermodels_savemodel; + if(!self.forceplayermodels_isgoodmodel) + print(sprintf("Warning: missing model %s has been used\n", self.forceplayermodels_savemodel)); + } } void CSQCPlayer_ForceModel_Apply(float islocalplayer) { - // first, try finding it from the server + // which one is ALWAYS good? + if not(forceplayermodels_goodmodel) + { + entity e; + e = spawn(); + setmodel(e, cvar_defstring("_cl_playermodel")); + forceplayermodels_goodmodel = e.model; + forceplayermodels_goodmodelindex = e.modelindex; + remove(e); + } + // first, try finding it from the server if(self.forceplayermodels_savemodelindex && self.forceplayermodels_savemodel != "null") { if(islocalplayer) { // trust server's idea of "own player model" - forceplayermodels_model = self.model; - forceplayermodels_modelindex = self.modelindex; - forceplayermodels_skin = self.skin; + forceplayermodels_modelisgoodmodel = self.forceplayermodels_isgoodmodel; + forceplayermodels_model = self.forceplayermodels_savemodel; + forceplayermodels_modelindex = self.forceplayermodels_savemodelindex; + forceplayermodels_skin = self.forceplayermodels_saveskin; forceplayermodels_attempted = 1; } } @@ -122,6 +146,7 @@ void CSQCPlayer_ForceModel_Apply(float islocalplayer) entity e; e = spawn(); setmodel(e, autocvar__cl_playermodel); // this is harmless, see below + forceplayermodels_modelisgoodmodel = fexists(e.model); forceplayermodels_model = e.model; forceplayermodels_modelindex = e.modelindex; forceplayermodels_skin = autocvar__cl_playerskin; @@ -133,30 +158,37 @@ void CSQCPlayer_ForceModel_Apply(float islocalplayer) entity e; e = spawn(); setmodel(e, autocvar_cl_forcemyplayermodel); // this is harmless, see below + forceplayermodels_myisgoodmodel = fexists(e.model); forceplayermodels_mymodel = e.model; forceplayermodels_mymodelindex = e.modelindex; remove(e); } // apply it - if(autocvar_cl_forcemyplayermodel != "" && forceplayermodels_mymodelindex && self.entnum == player_localnum + 1) + if(autocvar_cl_forcemyplayermodel != "" && forceplayermodels_myisgoodmodel && self.entnum == player_localnum + 1) { self.model = forceplayermodels_mymodel; self.modelindex = forceplayermodels_mymodelindex; self.skin = autocvar_cl_forcemyplayerskin; } - else if(autocvar_cl_forceplayermodels && forceplayermodels_modelindex) + else if(autocvar_cl_forceplayermodels && forceplayermodels_modelisgoodmodel) { self.model = forceplayermodels_model; self.modelindex = forceplayermodels_modelindex; self.skin = forceplayermodels_skin; } - else + else if(self.forceplayermodels_isgoodmodel) { self.model = self.forceplayermodels_savemodel; self.modelindex = self.forceplayermodels_savemodelindex; self.skin = self.forceplayermodels_saveskin; } + else + { + self.model = forceplayermodels_goodmodel; + self.modelindex = forceplayermodels_goodmodelindex; + self.skin = self.forceplayermodels_saveskin; + } // forceplayercolors too if(!teamplay) @@ -260,6 +292,15 @@ void CSQCModel_AutoTagIndex_Apply(void) self.tag_entity = findfloat(world, entnum, self.tag_networkentity); changed = 1; } + + // recursive predraw call to fix issues with forcemodels and LOD if bone indexes mismatch + { + entity oldself = self; + self = self.tag_entity; + CSQCModel_Hook_PreDraw(); + self = oldself; + } + if(self.tag_entity.modelindex != self.tag_entity_lastmodelindex) { self.tag_entity_lastmodelindex = self.tag_entity.modelindex; @@ -410,8 +451,13 @@ void CSQCModel_Effects_Apply(void) } // general functions -void CSQCModel_Hook_PreDraw(float isplayer, float islocalplayer) +.float csqcmodel_predraw_run; +void CSQCModel_Hook_PreDraw() { + if(self.csqcmodel_predraw_run == framecount) + return; + self.csqcmodel_predraw_run = framecount; + if(!self.modelindex || self.model == "null") { self.drawmask = 0; @@ -423,13 +469,12 @@ void CSQCModel_Hook_PreDraw(float isplayer, float islocalplayer) if(self.isplayermodel) // this checks if it's a player MODEL! { CSQCPlayer_GlowMod_Apply(); - CSQCPlayer_ForceModel_Apply(islocalplayer); + CSQCPlayer_ForceModel_Apply(self.entnum == player_localnum + 1); CSQCPlayer_LOD_Apply(); CSQCPlayer_FallbackFrame_Apply(); } - if(!isplayer) // this checks if it's a player SLOT! - CSQCModel_AutoTagIndex_Apply(); + CSQCModel_AutoTagIndex_Apply(); CSQCModel_Effects_Apply(); } diff --git a/qcsrc/client/main.qh b/qcsrc/client/main.qh index 9349d9c5c..43e7b6499 100644 --- a/qcsrc/client/main.qh +++ b/qcsrc/client/main.qh @@ -158,3 +158,4 @@ entity entcs_receiver[255]; // 255 is the engine limit on maxclients float hud; float view_quality; +float framecount; diff --git a/qcsrc/common/csqcmodel_settings.qh b/qcsrc/common/csqcmodel_settings.qh index e0dfce4ca..34d0634c4 100644 --- a/qcsrc/common/csqcmodel_settings.qh +++ b/qcsrc/common/csqcmodel_settings.qh @@ -37,7 +37,7 @@ #define CSQCMODEL_HOOK_POSTUPDATE \ CSQCModel_Hook_PostUpdate(isnew, isplayer, islocalplayer); #define CSQCMODEL_HOOK_PREDRAW \ - CSQCModel_Hook_PreDraw(isplayer, islocalplayer); + CSQCModel_Hook_PreDraw(); #define CSQCPLAYER_HOOK_POSTCAMERASETUP // force updates of player entities that often even if unchanged diff --git a/qcsrc/server/cl_weaponsystem.qc b/qcsrc/server/cl_weaponsystem.qc index 4a35f481b..3b69e13eb 100644 --- a/qcsrc/server/cl_weaponsystem.qc +++ b/qcsrc/server/cl_weaponsystem.qc @@ -607,10 +607,6 @@ void CL_ExteriorWeaponentity_Think() } else setattachment(self, self.owner, "bip01 r hand"); - - // if that didn't find a tag, hide the exterior weapon model - if (!self.tag_index) - self.model = ""; } self.effects = self.owner.effects; if(sv_pitch_min == sv_pitch_max) -- 2.39.2