X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fclient%2Fcsqcmodel_hooks.qc;h=c4a5b39a6b27c77d0b8829d0658f513195f760b7;hp=a0a6e150e373dee3a051e175a75e8842cd4a4618;hb=52ae1315c1851e595d12ffc13e2407dee0b24e5e;hpb=7b976c2b363a9f5b8d17373c7ef290aa0c498372 diff --git a/qcsrc/client/csqcmodel_hooks.qc b/qcsrc/client/csqcmodel_hooks.qc index a0a6e150e..c4a5b39a6 100644 --- a/qcsrc/client/csqcmodel_hooks.qc +++ b/qcsrc/client/csqcmodel_hooks.qc @@ -14,6 +14,9 @@ void CSQCPlayer_LOD_Apply(void) string modelname = self.model; string s; + vector mi = self.mins; + vector ma = self.maxs; + // set modelindex self.lodmodelindex0 = self.modelindex; self.lodmodelindex1 = self.modelindex; @@ -39,6 +42,7 @@ void CSQCPlayer_LOD_Apply(void) } setmodel(self, modelname); // make everything normal again + setsize(self, mi, ma); } // apply LOD @@ -53,8 +57,8 @@ void CSQCPlayer_LOD_Apply(void) } else { - float distance = vlen(self.origin - other.origin); - float f = (distance + 100.0) * autocvar_cl_playerdetailreduction; + float distance = vlen(self.origin - view_origin); + float f = (distance * current_viewzoom + 100.0) * autocvar_cl_playerdetailreduction; f *= 1.0 / bound(0.01, view_quality, 1); if(f > autocvar_cl_loddistance2) self.modelindex = self.lodmodelindex2; @@ -117,6 +121,7 @@ void CSQCPlayer_ForceModel_Apply(float islocalplayer) { entity e; e = spawn(); + precache_model(cvar_defstring("_cl_playermodel")); setmodel(e, cvar_defstring("_cl_playermodel")); forceplayermodels_goodmodel = e.model; forceplayermodels_goodmodelindex = e.modelindex; @@ -128,12 +133,15 @@ void CSQCPlayer_ForceModel_Apply(float islocalplayer) { if(islocalplayer) { - // trust server's idea of "own player model" - forceplayermodels_modelisgoodmodel = self.forceplayermodels_isgoodmodel; - forceplayermodels_model = self.forceplayermodels_savemodel; - forceplayermodels_modelindex = self.forceplayermodels_savemodelindex; - forceplayermodels_skin = self.forceplayermodels_saveskin; - forceplayermodels_attempted = 1; + if(!isdemo()) // this is mainly cheat protection; not needed for demos + { + // trust server's idea of "own player model" + forceplayermodels_modelisgoodmodel = self.forceplayermodels_isgoodmodel; + forceplayermodels_model = self.forceplayermodels_savemodel; + forceplayermodels_modelindex = self.forceplayermodels_savemodelindex; + forceplayermodels_skin = self.forceplayermodels_saveskin; + forceplayermodels_attempted = 1; + } } } @@ -165,7 +173,17 @@ void CSQCPlayer_ForceModel_Apply(float islocalplayer) } // apply it - if(autocvar_cl_forcemyplayermodel != "" && forceplayermodels_myisgoodmodel && islocalplayer) + float isfriend; + float cm; + cm = self.forceplayermodels_savecolormap; + cm = (cm >= 1024) ? cm : (stof(getplayerkeyvalue(self.colormap - 1, "colors")) + 1024); + + if(teamplay) + isfriend = (cm == 1024 + 17 * myteam); + else + isfriend = islocalplayer; + + if(autocvar_cl_forcemyplayermodel != "" && forceplayermodels_myisgoodmodel && isfriend) { self.model = forceplayermodels_mymodel; self.modelindex = forceplayermodels_mymodelindex; @@ -191,7 +209,56 @@ void CSQCPlayer_ForceModel_Apply(float islocalplayer) } // forceplayercolors too - if(!teamplay) + if(teamplay) + { + // own team's color is never forced + float forcecolor_friend = 0; + float forcecolor_enemy = 0; + float teams_count = 0; + entity tm; + + for(tm = teams.sort_next; tm; tm = tm.sort_next) + if(tm.team != FL_SPECTATOR) + ++teams_count; + + if(autocvar_cl_forcemyplayercolors) + forcecolor_friend = 1024 + autocvar_cl_forcemyplayercolors; + if(autocvar_cl_forceplayercolors && teams_count == 2) + forcecolor_enemy = 1024 + autocvar__cl_color; + + if(forcecolor_enemy && !forcecolor_friend) + { + // only enemy color is forced? + // verify it is not equal to the friend color + if(forcecolor_enemy == 1024 + 17 * myteam) + forcecolor_enemy = 0; + } + + if(forcecolor_friend && !forcecolor_enemy) + { + // only friend color is forced? + // verify it is not equal to the enemy color + for(tm = teams.sort_next; tm; tm = tm.sort_next) + // note: we even compare against our own team. + // if we rejected because we matched our OWN team color, + // this is not bad; we then simply keep our color as is + // anyway. + if(forcecolor_friend == 1024 + 17 * tm.team) + forcecolor_friend = 0; + } + + if(cm == 1024 + 17 * myteam) + { + if(forcecolor_friend) + self.colormap = forcecolor_friend; + } + else + { + if(forcecolor_enemy) + self.colormap = forcecolor_enemy; + } + } + else { if(autocvar_cl_forcemyplayercolors && islocalplayer) self.colormap = 1024 + autocvar_cl_forcemyplayercolors; @@ -227,7 +294,7 @@ void CSQCPlayer_FallbackFrame_PostUpdate(float isnew) if(isnew) { #define FIX_FRAMETIME(f,ft) \ - if(IS_DEAD_FRAME(self.f)) \ + if(IS_DEAD_FRAME(self.f) && self.ft != 0 && self.death_time != 0) \ { \ self.ft = self.death_time; \ } @@ -242,6 +309,8 @@ float CSQCPlayer_FallbackFrame(float f) { if(frameduration(self.modelindex, f) > 0) return f; // goooooood + if(frameduration(self.modelindex, 1) <= 0) + return f; // this is a static model. We can't fix it if we wanted to switch(f) { case 23: return 11; // anim_melee -> anim_shoot @@ -284,6 +353,7 @@ void CSQCModel_AutoTagIndex_Apply(void) } // recursive predraw call to fix issues with forcemodels and LOD if bone indexes mismatch + if(self.tag_entity.classname == "csqcmodel") { entity oldself = self; self = self.tag_entity; @@ -302,6 +372,7 @@ void CSQCModel_AutoTagIndex_Apply(void) { // the best part is: IT EXISTS if(substring(self.model, 0, 17) == "models/weapons/v_") + { if(substring(self.tag_entity.model, 0, 17) == "models/weapons/h_") { self.tag_index = gettagindex(self.tag_entity, "weapon"); @@ -315,14 +386,15 @@ void CSQCModel_AutoTagIndex_Apply(void) dprint("h_ model lacks weapon attachment, but v_ model is attached to it\n"); } } - - if(substring(self.model, 0, 17) == "models/weapons/v_") - if(substring(self.tag_entity.model, 0, 14) == "models/player/") + else if(self.tag_entity.isplayermodel) { - self.tag_index = gettagindex(self.tag_entity, "tag_weapon"); + self.tag_index = gettagindex(self.tag_entity, "weapon"); + if(!self.tag_index) + self.tag_index = gettagindex(self.tag_entity, "tag_weapon"); if(!self.tag_index) self.tag_index = gettagindex(self.tag_entity, "bip01 r hand"); } + } if(substring(self.tag_entity.model, 0, 17) == "models/weapons/v_") { @@ -371,6 +443,7 @@ void CSQCModel_Effects_PostUpdate(void) if(self.csqcmodel_teleported) Projectile_ResetTrail(self.origin); } +.float snd_looping; void CSQCModel_Effects_Apply(void) { float eff = self.csqcmodel_effects; @@ -442,6 +515,28 @@ void CSQCModel_Effects_Apply(void) if(self.csqcmodel_effects & CSQCMODEL_EF_RESPAWNGHOST) self.renderflags |= RF_ADDITIVE; // also special in CSQCPlayer_GlowMod_Apply + + if(self.csqcmodel_modelflags & MF_ROCKET) + { + if(!self.snd_looping) + { + sound(self, CH_TRIGGER_SINGLE, "misc/jetpack_fly.wav", VOL_BASE, autocvar_g_jetpack_attenuation); + self.snd_looping = CH_TRIGGER_SINGLE; + } + } + else + { + if(self.snd_looping) + { + sound(self, self.snd_looping, "misc/null.wav", VOL_BASE, autocvar_g_jetpack_attenuation); + self.snd_looping = 0; + } + } +} + +void CSQCPlayer_Precache() +{ + precache_sound("misc/jetpack_fly.wav"); } // FEATURE: auto glowmod @@ -512,7 +607,7 @@ void CSQCModel_Hook_PreUpdate(float isnew, float isplayer, float islocalplayer) void CSQCModel_Hook_PostUpdate(float isnew, float isplayer, float islocalplayer) { // is it a player model? (shared state) - self.isplayermodel = (substring(self.model, 0, 14) == "models/player/"); + self.isplayermodel = (substring(self.model, 0, 14) == "models/player/" || substring(self.model, 0, 17) == "models/ok_player/"); // save values set by server if(self.isplayermodel)