From: Rudolf Polzer Date: Wed, 21 Dec 2011 20:48:47 +0000 (+0100) Subject: rename some stuff X-Git-Tag: xonotic-v0.6.0~74^2~75^2~4 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=b0659144455bf0b8004bc007bdc241125d6f4bb7;p=xonotic%2Fxonotic-data.pk3dir.git rename some stuff --- diff --git a/qcsrc/client/progs.src b/qcsrc/client/progs.src index 9507161fe..7f31cacf2 100644 --- a/qcsrc/client/progs.src +++ b/qcsrc/client/progs.src @@ -22,7 +22,7 @@ Defs.qc autocvars.qh -../csqcmodel/interpolate.qh +../csqcmodellib/interpolate.qh teamradar.qh hud.qh scoreboard.qh @@ -37,10 +37,10 @@ tturrets.qh ../server/movelib.qc main.qh vehicles/vehicles.qh -../csqcmodel/settings.qh -../csqcmodel/common.qh -../csqcmodel/cl_model.qh -../csqcmodel/cl_player.qh +../common/csqcmodel_settings.qh +../csqcmodellib/common.qh +../csqcmodellib/cl_model.qh +../csqcmodellib/cl_player.qh projectile.qh sortlist.qc @@ -62,8 +62,8 @@ projectile.qc gibs.qc damage.qc casings.qc -../csqcmodel/cl_model.qc -../csqcmodel/cl_player.qc +../csqcmodellib/cl_model.qc +../csqcmodellib/cl_player.qc effects.qc wall.qc modeleffects.qc @@ -77,7 +77,7 @@ shownames.qc announcer.qc Main.qc View.qc -../csqcmodel/interpolate.qc +../csqcmodellib/interpolate.qc waypointsprites.qc movetypes.qc prandom.qc diff --git a/qcsrc/common/csqcmodel_settings.qh b/qcsrc/common/csqcmodel_settings.qh new file mode 100644 index 000000000..257676db7 --- /dev/null +++ b/qcsrc/common/csqcmodel_settings.qh @@ -0,0 +1,84 @@ +// define this if svqc code wants to use .frame2 and .lerpfrac +#define CSQCMODEL_HAVE_TWO_FRAMES + +// don't define this ever +//#define CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW + +// a hack for Xonotic +#ifdef CSQC +# define TAG_ENTITY_NAME tag_networkentity +# define TAG_ENTITY_TYPE float +.float tag_networkentity; +#else +# define TAG_ENTITY_NAME tag_entity +# define TAG_ENTITY_TYPE entity +#endif + +// add properties you want networked to CSQC here +#define CSQCMODEL_EXTRAPROPERTIES \ + CSQCMODEL_PROPERTY(1, float, ReadShort, WriteShort, colormap) \ + CSQCMODEL_PROPERTY(2, float, ReadInt24_t, WriteInt24_t, effects) \ + CSQCMODEL_PROPERTY(4, float, ReadByte, WriteByte, modelflags) \ + CSQCMODEL_PROPERTY_SCALED(8, float, ReadByte, WriteByte, alpha, 255, 0, 255) \ + CSQCMODEL_PROPERTY(16, float, ReadByte, WriteByte, skin) \ + CSQCMODEL_IF(isplayer) \ + CSQCMODEL_ENDIF \ + CSQCMODEL_IF(!isplayer) \ + CSQCMODEL_PROPERTY(32, TAG_ENTITY_TYPE, ReadShort, WriteEntity, TAG_ENTITY_NAME) \ + CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_x, 255, 0, 255) \ + CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_y, 255, 0, 255) \ + CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_z, 255, 0, 255) \ + CSQCMODEL_ENDIF +// TODO get rid of colormod/glowmod here, find good solution for nex charge glowmod hack; also get rid of some useless properties on non-players that only exist for CopyBody + +// add hook function calls here +#define CSQCMODEL_HOOK_PREUPDATE \ + CSQCModel_Hook_PreUpdate(isplayer, islocalplayer); +#define CSQCMODEL_HOOK_POSTUPDATE \ + CSQCModel_Hook_PostUpdate(isplayer, islocalplayer); +#define CSQCMODEL_HOOK_PREDRAW \ + CSQCModel_Hook_PreDraw(isplayer, islocalplayer); +#define CSQCPLAYER_HOOK_POSTCAMERASETUP + +#define CSQCPLAYER_FORCE_UPDATES 0.25 + +// mod must define: +//vector PL_MIN = ...; +//vector PL_MAX = ...; +//vector PL_VIEW_OFS = ...; +//vector PL_CROUCH_MIN = ...; +//vector PL_CROUCH_MAX = ...; +//vector PL_CROUCH_VIEW_OFS = ...; + +#ifdef SVQC +# ifdef NO_LEGACY_NETWORKING +# define CSQCMODEL_AUTOINIT() CSQCModel_LinkEntity() +# define CSQCMODEL_AUTOUPDATE() CSQCModel_CheckUpdate() +# else +.float iscsqcmodel; +float autocvar_sv_use_csqc_players; +# define CSQCMODEL_AUTOINIT() \ + if(autocvar_sv_use_csqc_players) \ + { \ + CSQCModel_LinkEntity(); \ + self.iscsqcmodel = 1; \ + } \ + else \ + self.iscsqcmodel = 0 +# define CSQCMODEL_AUTOUPDATE() \ + if(autocvar_sv_use_csqc_players && !self.iscsqcmodel) \ + { \ + CSQCModel_LinkEntity(); \ + self.iscsqcmodel = 1; \ + } \ + if(!autocvar_sv_use_csqc_players && self.iscsqcmodel) \ + { \ + CSQCModel_UnlinkEntity(); \ + self.iscsqcmodel = 0; \ + } \ + if(self.iscsqcmodel) \ + CSQCModel_CheckUpdate() +# endif +#endif + +#define CSQCMODEL_EF_INVISIBLE EF_SELECTABLE diff --git a/qcsrc/csqcmodel/cl_model.qc b/qcsrc/csqcmodel/cl_model.qc deleted file mode 100644 index 03226613b..000000000 --- a/qcsrc/csqcmodel/cl_model.qc +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -var float autocvar_cl_lerpanim_maxdelta_framegroups = 0.1; -var float autocvar_cl_nolerp = 0; - -.float csqcmodel_lerpfrac; -.float csqcmodel_lerpfrac2; -.float csqcmodel_lerpfractime; -.float csqcmodel_lerpfrac2time; - -void CSQCModel_InterpolateAnimation_PreNote(float sf) -{ -#ifdef CSQCMODEL_HAVE_TWO_FRAMES - if(sf & CSQCMODEL_PROPERTY_FRAME) - { - self.frame3 = self.frame; - self.frame3time = self.frame1time; - } - if(sf & CSQCMODEL_PROPERTY_FRAME2) - { - self.frame4 = self.frame2; - self.frame4time = self.frame2time; - } - if(sf & CSQCMODEL_PROPERTY_LERPFRAC) - { - self.csqcmodel_lerpfrac2 = self.csqcmodel_lerpfrac; - self.csqcmodel_lerpfrac2time = self.csqcmodel_lerpfractime; - self.lerpfrac = self.csqcmodel_lerpfrac; - } -#else - if(sf & CSQCMODEL_PROPERTY_FRAME) - { - self.frame2 = self.frame; - self.frame2time = self.frame1time; - } -#endif -} - -void CSQCModel_InterpolateAnimation_Note(float sf) -{ -#ifdef CSQCMODEL_HAVE_TWO_FRAMES - if(sf & CSQCMODEL_PROPERTY_FRAME) - { - self.frame1time = time; - } - if(sf & CSQCMODEL_PROPERTY_FRAME2) - { - self.frame2time = time; - } - if(sf & CSQCMODEL_PROPERTY_LERPFRAC) - { - self.csqcmodel_lerpfrac = self.lerpfrac; - self.csqcmodel_lerpfractime = time; - } -#else - if(sf & CSQCMODEL_PROPERTY_FRAME) - { - self.frame1time = time; - } -#endif -} - -void CSQCModel_InterpolateAnimation_Do() -{ -#ifdef CSQCMODEL_HAVE_TWO_FRAMES - if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0)) - { - self.lerpfrac = self.csqcmodel_lerpfrac; - self.lerpfrac3 = 0; - self.lerpfrac4 = 0; - } - else - { - float l13, l24, llf; - float l24_13; - - if(self.frame3time == 0) // if frame1/3 were not previously displayed, only frame1 can make sense - l13 = 1; - else - l13 = bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); - - if(self.frame4time == 0) // if frame2/4 were not previously displayed, only frame2 can make sense - l24 = 1; - else - l24 = bound(0, (time - self.frame2time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); - - if(self.csqcmodel_lerpfrac2time == 0) // if there is no old lerpfrac (newly displayed model), only lerpfrac makes sense - llf = 1; - else - llf = bound(0, (time - self.csqcmodel_lerpfractime) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); - - l24_13 = self.csqcmodel_lerpfrac * llf + self.csqcmodel_lerpfrac2 * (1 - llf); - - self.lerpfrac = l24 * l24_13; - self.lerpfrac4 = (1 - l24) * l24_13; - self.lerpfrac3 = (1 - l13) * (1 - l24_13); - - if(l24_13 == 0) // if frames 2/4 are not displayed, clear their frametime - { - self.frame2time = 0; - self.frame4time = 0; - } - - if(l24_13 == 1) // if frames 1/3 are not displayed, clear their frametime - { - self.frame1time = 0; - self.frame3time = 0; - } - } -#else - if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0)) - { - self.lerpfrac = 0; - } - else - { - self.lerpfrac = 1 - bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); - } -#endif -} - -void CSQCModel_Draw() -{ - // some nice flags for CSQCMODEL_IF and the hooks - float isplayer = (self.entnum >= 1 && self.entnum <= maxclients); - float islocalplayer = (self.entnum == player_localnum + 1); - float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1)); - - // we don't do this for the local player as that one is already handled - // by CSQCPlayer_SetCamera() - if(!CSQCPlayer_IsLocalPlayer()) - InterpolateOrigin_Do(); - - // TODO csqcplayers: run prediction here too - CSQCModel_InterpolateAnimation_Do(); - - { CSQCMODEL_HOOK_PREDRAW } - - // inherit draw flags easily - entity root = self; - while(root.tag_entity) - root = root.tag_entity; - if(self != root) - { - self.renderflags &~= RF_EXTERNALMODEL | RF_VIEWMODEL; - self.renderflags |= (root.renderflags & (RF_EXTERNALMODEL | RF_VIEWMODEL)); - } - - // we're drawn, now teleporting is over - self.csqcmodel_teleported = 0; -} - -void CSQCModel_Read() -{ - float sf; - sf = ReadShort(); - - // some nice flags for CSQCMODEL_IF and the hooks - float isplayer = (self.entnum >= 1 && self.entnum <= maxclients); - float islocalplayer = (self.entnum == player_localnum + 1); - float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1)); - - self.iflags |= IFLAG_ANGLES; // interpolate angles too - - { CSQCMODEL_HOOK_PREUPDATE } - - CSQCPlayer_PreUpdate(); - InterpolateOrigin_Undo(); - CSQCModel_InterpolateAnimation_PreNote(sf); - -#define CSQCMODEL_IF(cond) if(cond) { -#define CSQCMODEL_ENDIF } -#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ - if(sf & flag) \ - self.f = r(); -#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \ - if(sf & flag) \ - self.f = r() / s; - ALLPROPERTIES -#undef CSQCMODEL_PROPERTY_SCALED -#undef CSQCMODEL_PROPERTY -#undef CSQCMODEL_ENDIF -#undef CSQCMODEL_IF - - if(sf & CSQCMODEL_PROPERTY_MODELINDEX) - setmodelindex(self, self.modelindex); // this retrieves the .model key and sets mins/maxs/absmin/absmax - - if(sf & CSQCMODEL_PROPERTY_TELEPORTED) - { - self.iflags |= IFLAG_TELEPORTED; - self.csqcmodel_teleported = 1; - } - - CSQCModel_InterpolateAnimation_Note(sf); - InterpolateOrigin_Note(); - CSQCPlayer_PostUpdate(); - - { CSQCMODEL_HOOK_POSTUPDATE } - -#ifdef CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW - InterpolateOrigin_Do(); - CSQCModel_InterpolateAnimation_Do(); -#endif - - // relink - setorigin(self, self.origin); - - // set obvious render flags -#ifdef COMPAT_XON050_ENGINE - if(self.entnum == player_localentnum || self.entnum == spectatee_status) -#else - if(self.entnum == player_localentnum) -#endif - self.renderflags |= RF_EXTERNALMODEL; - else - self.renderflags &~= RF_EXTERNALMODEL; - - // draw it - self.drawmask = MASK_NORMAL; - self.predraw = CSQCModel_Draw; -} - -entity CSQCModel_server2csqc(float pl) -{ - return findfloat(world, entnum, pl); // FIXME optimize this using an array -} diff --git a/qcsrc/csqcmodel/cl_model.qh b/qcsrc/csqcmodel/cl_model.qh deleted file mode 100644 index d38656533..000000000 --- a/qcsrc/csqcmodel/cl_model.qh +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -void CSQCModel_Read(); - -#define CSQCMODEL_IF(cond) -#define CSQCMODEL_ENDIF -#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ - .t f; -#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f) - ALLPROPERTIES -#undef CSQCMODEL_PROPERTY_SCALED -#undef CSQCMODEL_PROPERTY -#undef CSQCMODEL_ENDIF -#undef CSQCMODEL_IF - -entity CSQCModel_server2csqc(float pl); -.float csqcmodel_teleported; diff --git a/qcsrc/csqcmodel/cl_player.qc b/qcsrc/csqcmodel/cl_player.qc deleted file mode 100644 index 9c62bbc5f..000000000 --- a/qcsrc/csqcmodel/cl_player.qc +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -var float autocvar_cl_predictionerrorcompensation = 0; - -// engine stuff -.float pmove_flags; -float pmove_onground; // weird engine flag we shouldn't really use but have to for now -#define PMF_JUMP_HELD 1 -#define PMF_DUCKED 4 -#define PMF_ONGROUND 8 -#define REFDEFFLAG_TELEPORTED 1 -#define REFDEFFLAG_JUMPING 2 - -entity csqcplayer; -vector csqcplayer_origin, csqcplayer_velocity; -float csqcplayer_sequence, player_pmflags; -float csqcplayer_moveframe; -vector csqcplayer_predictionerror; -float csqcplayer_predictionerrortime; - -vector CSQCPlayer_GetPredictionError() -{ - if(!autocvar_cl_predictionerrorcompensation) - return '0 0 0'; - if(time < csqcplayer_predictionerrortime) - return csqcplayer_predictionerror * (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation; - return '0 0 0'; -} - -void CSQCPlayer_SetPredictionError(vector v) -{ - if(!autocvar_cl_predictionerrorcompensation) - return; - csqcplayer_predictionerror = (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation * csqcplayer_predictionerror + v; - csqcplayer_predictionerrortime = time + 1.0 / autocvar_cl_predictionerrorcompensation; -} - -void CSQCPlayer_Unpredict() -{ - if(csqcplayer_status == CSQCPLAYERSTATUS_UNPREDICTED) - return; - if(csqcplayer_status != CSQCPLAYERSTATUS_PREDICTED) - error("Cannot unpredict in current status"); - self.origin = csqcplayer_origin; - self.velocity = csqcplayer_velocity; - csqcplayer_moveframe = csqcplayer_sequence+1; //+1 because the recieved frame has the move already done (server side) - self.pmove_flags = player_pmflags; -} - -void CSQCPlayer_SetMinsMaxs() -{ - if(self.pmove_flags & PMF_DUCKED) - { - self.mins = PL_CROUCH_MIN; - self.maxs = PL_CROUCH_MAX; - self.view_ofs = PL_CROUCH_VIEW_OFS; - } - else - { - self.mins = PL_MIN; - self.maxs = PL_MAX; - self.view_ofs = PL_VIEW_OFS; - } -} - -void CSQCPlayer_SavePrediction() -{ - player_pmflags = self.pmove_flags; - csqcplayer_origin = self.origin; - csqcplayer_velocity = self.velocity; - csqcplayer_sequence = servercommandframe; - csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; -} - -void CSQCPlayer_PredictTo(float endframe) -{ - CSQCPlayer_Unpredict(); - CSQCPlayer_SetMinsMaxs(); - - csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; - - if (getstatf(STAT_HEALTH) <= 0) - { - csqcplayer_moveframe = clientcommandframe; - getinputstate(csqcplayer_moveframe-1); - return; - } - - while(csqcplayer_moveframe < endframe) - { - if (!getinputstate(csqcplayer_moveframe)) - { - break; - } - if(input_timelength <= 0.0005) // too short move - { - dprint("CSQC physics hack: too short frame skipped\n"); - // even if not running physics, handle releasing the jump key - if(!(input_buttons & 4)) - self.pmove_flags &~= PMF_JUMP_HELD; - } - else if(input_timelength > 0.05) // too long move - { - dprint("CSQC physics hack: too long frame split in two\n"); - input_timelength *= 0.5; - runstandardplayerphysics(self); - CSQCPlayer_SetMinsMaxs(); - runstandardplayerphysics(self); - CSQCPlayer_SetMinsMaxs(); - } - else - { - runstandardplayerphysics(self); - CSQCPlayer_SetMinsMaxs(); - } - csqcplayer_moveframe++; - } - - //add in anything that was applied after (for low packet rate protocols) - input_angles = view_angles; -} - -float CSQCPlayer_IsLocalPlayer() -{ - return (self == csqcplayer); -} - -void(entity e, float fl) V_CalcRefdef = #640; // DP_CSQC_V_CALCREFDEF - -void CSQCPlayer_SetCamera() -{ - if(csqcplayer) - { - entity oldself; - oldself = self; - self = csqcplayer; - -#ifdef COMPAT_XON050_ENGINE - if(servercommandframe == 0 || !(checkextension("DP_CSQC_V_CALCREFDEF") || checkextension("DP_CSQC_V_CALCREFDEF_WIP1"))) -#else - if(servercommandframe == 0) -#endif - { - InterpolateOrigin_Do(); - self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT); - - // get crouch state from the server - if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z) - self.pmove_flags &~= PMF_DUCKED; - else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z) - self.pmove_flags |= PMF_DUCKED; - - // get onground state from the server - if(pmove_onground) - self.pmove_flags |= PMF_ONGROUND; - else - self.pmove_flags &~= PMF_ONGROUND; - - CSQCPlayer_SetMinsMaxs(); - - // override it back just in case - self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT); - } - else - { - if(csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER) - { - vector o, v; - o = self.origin; - v = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity - csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; - CSQCPlayer_PredictTo(servercommandframe + 1); - CSQCPlayer_SetPredictionError(o - self.origin); - self.origin = o; - self.velocity = v; - - // get crouch state from the server - if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z) - self.pmove_flags &~= PMF_DUCKED; - else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z) - self.pmove_flags |= PMF_DUCKED; - - // get onground state from the server - if(pmove_onground) - self.pmove_flags |= PMF_ONGROUND; - else - self.pmove_flags &~= PMF_ONGROUND; - - CSQCPlayer_SavePrediction(); - } - CSQCPlayer_PredictTo(clientcommandframe + 1); - - CSQCPlayer_SetMinsMaxs(); - - self.angles_y = input_angles_y; - } - - // relink - setorigin(self, self.origin); - - self = oldself; - } - - entity view; -#ifdef COMPAT_XON050_ENGINE - view = CSQCModel_server2csqc((spectatee_status > 0) ? spectatee_status : player_localentnum); -#else - view = CSQCModel_server2csqc(player_localentnum); -#endif - -#ifdef COMPAT_XON050_ENGINE - if(view && !(checkextension("DP_CSQC_V_CALCREFDEF") || checkextension("DP_CSQC_V_CALCREFDEF_WIP1"))) - { - // legacy code, not totally correct, but good enough for not having V_CalcRefdef - setproperty(VF_ORIGIN, view.origin + '0 0 1' * getstati(STAT_VIEWHEIGHT)); - setproperty(VF_ANGLES, view_angles); - } - else -#endif - if(view) - { - var float refdefflags = 0; - - if(view.csqcmodel_teleported) - refdefflags |= REFDEFFLAG_TELEPORTED; - - if(input_buttons & 4) - refdefflags |= REFDEFFLAG_JUMPING; - - V_CalcRefdef(view, refdefflags); - } - else - { - setproperty(VF_ORIGIN, pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT)); - setproperty(VF_ANGLES, view_angles); - } - - { CSQCPLAYER_HOOK_POSTCAMERASETUP } -} - -void CSQCPlayer_Remove() -{ - if(self.entnum != player_localnum + 1) - return; - csqcplayer = world; - cvar_clientsettemp("cl_movement_replay", "1"); -} - -float CSQCPlayer_PreUpdate() -{ - if(self.entnum != player_localnum + 1) - return 0; - cvar_clientsettemp("cl_movement_replay", "0"); - if(csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER) - CSQCPlayer_Unpredict(); - return 1; -} - -float CSQCPlayer_PostUpdate() -{ - if(self.entnum != player_localentnum) - return 0; - csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER; - csqcplayer = self; - self.entremove = CSQCPlayer_Remove; - return 1; -} diff --git a/qcsrc/csqcmodel/cl_player.qh b/qcsrc/csqcmodel/cl_player.qh deleted file mode 100644 index 0eecabed8..000000000 --- a/qcsrc/csqcmodel/cl_player.qh +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -float csqcplayer_status; -#define CSQCPLAYERSTATUS_UNPREDICTED 0 -#define CSQCPLAYERSTATUS_FROMSERVER 1 -#define CSQCPLAYERSTATUS_PREDICTED 2 - -void CSQCPlayer_SetCamera(); -float CSQCPlayer_PreUpdate(); -float CSQCPlayer_PostUpdate(); -float CSQCPlayer_IsLocalPlayer(); diff --git a/qcsrc/csqcmodel/common.qh b/qcsrc/csqcmodel/common.qh deleted file mode 100644 index 587645cd4..000000000 --- a/qcsrc/csqcmodel/common.qh +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -noref string csqcmodel_license = "\ -Copyright (c) 2011 Rudolf Polzer\ -\ -Permission is hereby granted, free of charge, to any person obtaining a copy\ -of this software and associated documentation files (the \"Software\"), to\ -deal in the Software without restriction, including without limitation the\ -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\ -sell copies of the Software, and to permit persons to whom the Software is\ -furnished to do so, subject to the following conditions:\ -\ -The above copyright notice and this permission notice shall be included in\ -all copies or substantial portions of the Software.\ -\ -THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\ -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\ -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\ -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\ -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\ -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\ -IN THE SOFTWARE.\ -"; - -.vector glowmod; -.vector view_ofs; -.float frame; -.float frame1time; -.float frame2; -.float frame2time; -.float lerpfrac; - -#define CSQCMODEL_PROPERTY_FRAME 32768 -#define CSQCMODEL_PROPERTY_FRAME2 16384 -#define CSQCMODEL_PROPERTY_LERPFRAC 8192 -#define CSQCMODEL_PROPERTY_TELEPORTED 4096 // the "teleport bit" cancelling interpolation -#define CSQCMODEL_PROPERTY_MODELINDEX 2048 -#define CSQCMODEL_PROPERTY_ORIGIN 1024 -#define CSQCMODEL_PROPERTY_YAW 512 -#define CSQCMODEL_PROPERTY_PITCHROLL 256 - -#define ALLPROPERTIES_COMMON \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_FRAME, float, ReadByte, WriteByte, frame) \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_MODELINDEX, float, ReadShort, WriteShort, modelindex) \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_x) \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_y) \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_z) \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_PITCHROLL, float, ReadAngle, WriteAngle, angles_x) \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_YAW, float, ReadAngle, WriteAngle, angles_y) \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_PITCHROLL, float, ReadAngle, WriteAngle, angles_z) \ - CSQCMODEL_EXTRAPROPERTIES - -#ifdef CSQCMODEL_HAVE_TWO_FRAMES -.float frame3; -.float frame3time; -.float lerpfrac3; -.float frame4; -.float frame4time; -.float lerpfrac4; -#define ALLPROPERTIES ALLPROPERTIES_COMMON \ - CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_FRAME2, float, ReadByte, WriteByte, frame2) \ - CSQCMODEL_PROPERTY_SCALED(CSQCMODEL_PROPERTY_LERPFRAC, float, ReadByte, WriteByte, lerpfrac, 255, 0, 255) -#else -#define ALLPROPERTIES ALLPROPERTIES_COMMON -#endif diff --git a/qcsrc/csqcmodel/interpolate.qc b/qcsrc/csqcmodel/interpolate.qc deleted file mode 100644 index ac0ba6e7d..000000000 --- a/qcsrc/csqcmodel/interpolate.qc +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -.vector iorigin1, iorigin2; -.vector ivelocity1, ivelocity2; -.vector iforward1, iforward2; -.vector iup1, iup2; -.float itime1, itime2; -void InterpolateOrigin_Reset() -{ - self.iflags &~= IFLAG_INTERNALMASK; - self.itime1 = self.itime2 = 0; -} -void InterpolateOrigin_Note() -{ - float dt; - float f0; - - dt = time - self.itime2; - - f0 = self.iflags; - if(self.iflags & IFLAG_PREVALID) - self.iflags |= IFLAG_VALID; - else - self.iflags |= IFLAG_PREVALID; - - self.iorigin1 = self.iorigin2; - self.iorigin2 = self.origin; - - if(self.iflags & IFLAG_AUTOANGLES) - if(self.iorigin2 != self.iorigin1) - self.angles = vectoangles(self.iorigin2 - self.iorigin1); - - if(self.iflags & IFLAG_ANGLES) - { - fixedmakevectors(self.angles); - if(f0 & IFLAG_VALID) - { - self.iforward1 = self.iforward2; - self.iup1 = self.iup2; - } - else - { - self.iforward1 = v_forward; - self.iup1 = v_up; - } - self.iforward2 = v_forward; - self.iup2 = v_up; - } - - if(self.iflags & IFLAG_VELOCITY) - { - self.ivelocity1 = self.ivelocity2; - self.ivelocity2 = self.velocity; - } - - if(self.iflags & IFLAG_TELEPORTED) - { - self.iflags &~= IFLAG_TELEPORTED; - self.itime1 = self.itime2 = time; // don't lerp - } - else if(vlen(self.iorigin2 - self.iorigin1) > 1000) - { - self.itime1 = self.itime2 = time; // don't lerp - } - else if((self.iflags & IFLAG_VELOCITY) && (vlen(self.ivelocity2 - self.ivelocity1) > 1000)) - { - self.itime1 = self.itime2 = time; // don't lerp - } - else if(dt >= 0.2) - { - self.itime1 = self.itime2 = time; - } - else - { - self.itime1 = serverprevtime; - self.itime2 = time; - } -} -void InterpolateOrigin_Do() -{ - vector forward, up; - if(self.itime1 && self.itime2 && self.itime1 != self.itime2) - { - float f; - f = bound(0, (time - self.itime1) / (self.itime2 - self.itime1), 1 + autocvar_cl_lerpexcess); - self.origin = (1 - f) * self.iorigin1 + f * self.iorigin2; - if(self.iflags & IFLAG_ANGLES) - { - forward = (1 - f) * self.iforward1 + f * self.iforward2; - up = (1 - f) * self.iup1 + f * self.iup2; - self.angles = fixedvectoangles2(forward, up); - } - if(self.iflags & IFLAG_VELOCITY) - self.velocity = (1 - f) * self.ivelocity1 + f * self.ivelocity2; - } -} -void InterpolateOrigin_Undo() -{ - self.origin = self.iorigin2; - if(self.iflags & IFLAG_ANGLES) - self.angles = fixedvectoangles2(self.iforward2, self.iup2); - if(self.iflags & IFLAG_VELOCITY) - self.velocity = self.ivelocity2; -} - diff --git a/qcsrc/csqcmodel/interpolate.qh b/qcsrc/csqcmodel/interpolate.qh deleted file mode 100644 index 8254fae8c..000000000 --- a/qcsrc/csqcmodel/interpolate.qh +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -.float iflags; -#define IFLAG_VELOCITY 1 -#define IFLAG_ANGLES 2 -#define IFLAG_AUTOANGLES 4 -#define IFLAG_VALID 8 -#define IFLAG_PREVALID 16 -#define IFLAG_TELEPORTED 32 -#define IFLAG_INTERNALMASK (IFLAG_VALID | IFLAG_PREVALID) - -// call this BEFORE reading an entity update -void InterpolateOrigin_Undo(); - -// call this AFTER receiving an entity update -void InterpolateOrigin_Note(); - -// call this when the entity got teleported, before InterpolateOrigin_Note -void InterpolateOrigin_Reset(); - -// call this BEFORE drawing -void InterpolateOrigin_Do(); diff --git a/qcsrc/csqcmodel/settings.qh b/qcsrc/csqcmodel/settings.qh deleted file mode 100644 index 257676db7..000000000 --- a/qcsrc/csqcmodel/settings.qh +++ /dev/null @@ -1,84 +0,0 @@ -// define this if svqc code wants to use .frame2 and .lerpfrac -#define CSQCMODEL_HAVE_TWO_FRAMES - -// don't define this ever -//#define CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW - -// a hack for Xonotic -#ifdef CSQC -# define TAG_ENTITY_NAME tag_networkentity -# define TAG_ENTITY_TYPE float -.float tag_networkentity; -#else -# define TAG_ENTITY_NAME tag_entity -# define TAG_ENTITY_TYPE entity -#endif - -// add properties you want networked to CSQC here -#define CSQCMODEL_EXTRAPROPERTIES \ - CSQCMODEL_PROPERTY(1, float, ReadShort, WriteShort, colormap) \ - CSQCMODEL_PROPERTY(2, float, ReadInt24_t, WriteInt24_t, effects) \ - CSQCMODEL_PROPERTY(4, float, ReadByte, WriteByte, modelflags) \ - CSQCMODEL_PROPERTY_SCALED(8, float, ReadByte, WriteByte, alpha, 255, 0, 255) \ - CSQCMODEL_PROPERTY(16, float, ReadByte, WriteByte, skin) \ - CSQCMODEL_IF(isplayer) \ - CSQCMODEL_ENDIF \ - CSQCMODEL_IF(!isplayer) \ - CSQCMODEL_PROPERTY(32, TAG_ENTITY_TYPE, ReadShort, WriteEntity, TAG_ENTITY_NAME) \ - CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_x, 255, 0, 255) \ - CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_y, 255, 0, 255) \ - CSQCMODEL_PROPERTY_SCALED(64, float, ReadByte, WriteByte, glowmod_z, 255, 0, 255) \ - CSQCMODEL_ENDIF -// TODO get rid of colormod/glowmod here, find good solution for nex charge glowmod hack; also get rid of some useless properties on non-players that only exist for CopyBody - -// add hook function calls here -#define CSQCMODEL_HOOK_PREUPDATE \ - CSQCModel_Hook_PreUpdate(isplayer, islocalplayer); -#define CSQCMODEL_HOOK_POSTUPDATE \ - CSQCModel_Hook_PostUpdate(isplayer, islocalplayer); -#define CSQCMODEL_HOOK_PREDRAW \ - CSQCModel_Hook_PreDraw(isplayer, islocalplayer); -#define CSQCPLAYER_HOOK_POSTCAMERASETUP - -#define CSQCPLAYER_FORCE_UPDATES 0.25 - -// mod must define: -//vector PL_MIN = ...; -//vector PL_MAX = ...; -//vector PL_VIEW_OFS = ...; -//vector PL_CROUCH_MIN = ...; -//vector PL_CROUCH_MAX = ...; -//vector PL_CROUCH_VIEW_OFS = ...; - -#ifdef SVQC -# ifdef NO_LEGACY_NETWORKING -# define CSQCMODEL_AUTOINIT() CSQCModel_LinkEntity() -# define CSQCMODEL_AUTOUPDATE() CSQCModel_CheckUpdate() -# else -.float iscsqcmodel; -float autocvar_sv_use_csqc_players; -# define CSQCMODEL_AUTOINIT() \ - if(autocvar_sv_use_csqc_players) \ - { \ - CSQCModel_LinkEntity(); \ - self.iscsqcmodel = 1; \ - } \ - else \ - self.iscsqcmodel = 0 -# define CSQCMODEL_AUTOUPDATE() \ - if(autocvar_sv_use_csqc_players && !self.iscsqcmodel) \ - { \ - CSQCModel_LinkEntity(); \ - self.iscsqcmodel = 1; \ - } \ - if(!autocvar_sv_use_csqc_players && self.iscsqcmodel) \ - { \ - CSQCModel_UnlinkEntity(); \ - self.iscsqcmodel = 0; \ - } \ - if(self.iscsqcmodel) \ - CSQCModel_CheckUpdate() -# endif -#endif - -#define CSQCMODEL_EF_INVISIBLE EF_SELECTABLE diff --git a/qcsrc/csqcmodel/sv_model.qc b/qcsrc/csqcmodel/sv_model.qc deleted file mode 100644 index 1c214e0ab..000000000 --- a/qcsrc/csqcmodel/sv_model.qc +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -// generic CSQC model code - -float CSQCModel_Send(entity to, float sf) -{ - // some nice flags for CSQCMODEL_IF - float isplayer = (self.flags & FL_CLIENT); - float islocalplayer = (self == to); - float isnolocalplayer = (isplayer && (self != to)); - - WriteByte(MSG_ENTITY, ENT_CLIENT_MODEL); - WriteShort(MSG_ENTITY, sf); - -#define CSQCMODEL_IF(cond) if(cond) { -#define CSQCMODEL_ENDIF } -#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ - if(sf & flag) \ - { \ - w(MSG_ENTITY, self.csqcmodel_##f); \ - } -#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f) - ALLPROPERTIES -#undef CSQCMODEL_PROPERTY_SCALED -#undef CSQCMODEL_PROPERTY -#undef CSQCMODEL_ENDIF -#undef CSQCMODEL_IF - - return TRUE; -} - -#ifdef CSQCPLAYER_FORCE_UPDATES -.float csqcmodel_nextforcedupdate; -#endif -void CSQCModel_CheckUpdate() -{ - // some nice flags for CSQCMODEL_IF - float isplayer = (self.flags & FL_CLIENT); - float islocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags - float isnolocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags - -#ifdef CSQCPLAYER_FORCE_UPDATES - if(isplayer && time > self.csqcmodel_nextforcedupdate) - { - self.SendFlags |= CSQCMODEL_PROPERTY_ORIGIN; - self.csqcmodel_nextforcedupdate = time + CSQCPLAYER_FORCE_UPDATES * (0.5 + random()); // ensure about 4 origin sends per sec - } -#endif - - if(self.effects & EF_RESTARTANIM_BIT) - { - self.SendFlags |= CSQCMODEL_PROPERTY_FRAME | CSQCMODEL_PROPERTY_FRAME2; // full anim resend please - self.effects &~= EF_RESTARTANIM_BIT; - } - - if(self.effects & EF_TELEPORT_BIT) - { - self.SendFlags |= CSQCMODEL_PROPERTY_TELEPORTED; // no interpolation please - self.effects &~= EF_TELEPORT_BIT; - } - -#define CSQCMODEL_IF(cond) if(cond) { -#define CSQCMODEL_ENDIF } -#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ - { \ - t tmp = self.f; \ - if(tmp != self.csqcmodel_##f) \ - { \ - self.csqcmodel_##f = tmp; \ - self.SendFlags |= flag; \ - } \ - } -#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \ - { \ - t tmp = bound(mi, s * self.f, ma); \ - if(tmp != self.csqcmodel_##f) \ - { \ - self.csqcmodel_##f = tmp; \ - self.SendFlags |= flag; \ - } \ - } - ALLPROPERTIES -#undef CSQCMODEL_PROPERTY_SCALED -#undef CSQCMODEL_PROPERTY -#undef CSQCMODEL_ENDIF -#undef CSQCMODEL_IF -} - -void CSQCModel_LinkEntity() -{ - self.SendEntity = CSQCModel_Send; - self.SendFlags = 0xFFFFFF; -} - -void CSQCModel_UnlinkEntity() -{ - self.SendEntity = func_null; -} diff --git a/qcsrc/csqcmodel/sv_model.qh b/qcsrc/csqcmodel/sv_model.qh deleted file mode 100644 index 3c4ce2b78..000000000 --- a/qcsrc/csqcmodel/sv_model.qh +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2011 Rudolf Polzer - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -// generic CSQC model code - -void CSQCModel_CheckUpdate(); -void CSQCModel_LinkEntity(); -void CSQCModel_UnlinkEntity(); - -#define CSQCMODEL_IF(cond) -#define CSQCMODEL_ENDIF -#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ - .t f; \ - .t csqcmodel_##f; -#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f) - ALLPROPERTIES -#undef CSQCMODEL_PROPERTY_SCALED -#undef CSQCMODEL_PROPERTY -#undef CSQCMODEL_ENDIF -#undef CSQCMODEL_IF diff --git a/qcsrc/csqcmodellib/cl_model.qc b/qcsrc/csqcmodellib/cl_model.qc new file mode 100644 index 000000000..03226613b --- /dev/null +++ b/qcsrc/csqcmodellib/cl_model.qc @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +var float autocvar_cl_lerpanim_maxdelta_framegroups = 0.1; +var float autocvar_cl_nolerp = 0; + +.float csqcmodel_lerpfrac; +.float csqcmodel_lerpfrac2; +.float csqcmodel_lerpfractime; +.float csqcmodel_lerpfrac2time; + +void CSQCModel_InterpolateAnimation_PreNote(float sf) +{ +#ifdef CSQCMODEL_HAVE_TWO_FRAMES + if(sf & CSQCMODEL_PROPERTY_FRAME) + { + self.frame3 = self.frame; + self.frame3time = self.frame1time; + } + if(sf & CSQCMODEL_PROPERTY_FRAME2) + { + self.frame4 = self.frame2; + self.frame4time = self.frame2time; + } + if(sf & CSQCMODEL_PROPERTY_LERPFRAC) + { + self.csqcmodel_lerpfrac2 = self.csqcmodel_lerpfrac; + self.csqcmodel_lerpfrac2time = self.csqcmodel_lerpfractime; + self.lerpfrac = self.csqcmodel_lerpfrac; + } +#else + if(sf & CSQCMODEL_PROPERTY_FRAME) + { + self.frame2 = self.frame; + self.frame2time = self.frame1time; + } +#endif +} + +void CSQCModel_InterpolateAnimation_Note(float sf) +{ +#ifdef CSQCMODEL_HAVE_TWO_FRAMES + if(sf & CSQCMODEL_PROPERTY_FRAME) + { + self.frame1time = time; + } + if(sf & CSQCMODEL_PROPERTY_FRAME2) + { + self.frame2time = time; + } + if(sf & CSQCMODEL_PROPERTY_LERPFRAC) + { + self.csqcmodel_lerpfrac = self.lerpfrac; + self.csqcmodel_lerpfractime = time; + } +#else + if(sf & CSQCMODEL_PROPERTY_FRAME) + { + self.frame1time = time; + } +#endif +} + +void CSQCModel_InterpolateAnimation_Do() +{ +#ifdef CSQCMODEL_HAVE_TWO_FRAMES + if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0)) + { + self.lerpfrac = self.csqcmodel_lerpfrac; + self.lerpfrac3 = 0; + self.lerpfrac4 = 0; + } + else + { + float l13, l24, llf; + float l24_13; + + if(self.frame3time == 0) // if frame1/3 were not previously displayed, only frame1 can make sense + l13 = 1; + else + l13 = bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); + + if(self.frame4time == 0) // if frame2/4 were not previously displayed, only frame2 can make sense + l24 = 1; + else + l24 = bound(0, (time - self.frame2time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); + + if(self.csqcmodel_lerpfrac2time == 0) // if there is no old lerpfrac (newly displayed model), only lerpfrac makes sense + llf = 1; + else + llf = bound(0, (time - self.csqcmodel_lerpfractime) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); + + l24_13 = self.csqcmodel_lerpfrac * llf + self.csqcmodel_lerpfrac2 * (1 - llf); + + self.lerpfrac = l24 * l24_13; + self.lerpfrac4 = (1 - l24) * l24_13; + self.lerpfrac3 = (1 - l13) * (1 - l24_13); + + if(l24_13 == 0) // if frames 2/4 are not displayed, clear their frametime + { + self.frame2time = 0; + self.frame4time = 0; + } + + if(l24_13 == 1) // if frames 1/3 are not displayed, clear their frametime + { + self.frame1time = 0; + self.frame3time = 0; + } + } +#else + if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0)) + { + self.lerpfrac = 0; + } + else + { + self.lerpfrac = 1 - bound(0, (time - self.frame1time) / autocvar_cl_lerpanim_maxdelta_framegroups, 1); + } +#endif +} + +void CSQCModel_Draw() +{ + // some nice flags for CSQCMODEL_IF and the hooks + float isplayer = (self.entnum >= 1 && self.entnum <= maxclients); + float islocalplayer = (self.entnum == player_localnum + 1); + float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1)); + + // we don't do this for the local player as that one is already handled + // by CSQCPlayer_SetCamera() + if(!CSQCPlayer_IsLocalPlayer()) + InterpolateOrigin_Do(); + + // TODO csqcplayers: run prediction here too + CSQCModel_InterpolateAnimation_Do(); + + { CSQCMODEL_HOOK_PREDRAW } + + // inherit draw flags easily + entity root = self; + while(root.tag_entity) + root = root.tag_entity; + if(self != root) + { + self.renderflags &~= RF_EXTERNALMODEL | RF_VIEWMODEL; + self.renderflags |= (root.renderflags & (RF_EXTERNALMODEL | RF_VIEWMODEL)); + } + + // we're drawn, now teleporting is over + self.csqcmodel_teleported = 0; +} + +void CSQCModel_Read() +{ + float sf; + sf = ReadShort(); + + // some nice flags for CSQCMODEL_IF and the hooks + float isplayer = (self.entnum >= 1 && self.entnum <= maxclients); + float islocalplayer = (self.entnum == player_localnum + 1); + float isnolocalplayer = (isplayer && (self.entnum != player_localnum + 1)); + + self.iflags |= IFLAG_ANGLES; // interpolate angles too + + { CSQCMODEL_HOOK_PREUPDATE } + + CSQCPlayer_PreUpdate(); + InterpolateOrigin_Undo(); + CSQCModel_InterpolateAnimation_PreNote(sf); + +#define CSQCMODEL_IF(cond) if(cond) { +#define CSQCMODEL_ENDIF } +#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ + if(sf & flag) \ + self.f = r(); +#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \ + if(sf & flag) \ + self.f = r() / s; + ALLPROPERTIES +#undef CSQCMODEL_PROPERTY_SCALED +#undef CSQCMODEL_PROPERTY +#undef CSQCMODEL_ENDIF +#undef CSQCMODEL_IF + + if(sf & CSQCMODEL_PROPERTY_MODELINDEX) + setmodelindex(self, self.modelindex); // this retrieves the .model key and sets mins/maxs/absmin/absmax + + if(sf & CSQCMODEL_PROPERTY_TELEPORTED) + { + self.iflags |= IFLAG_TELEPORTED; + self.csqcmodel_teleported = 1; + } + + CSQCModel_InterpolateAnimation_Note(sf); + InterpolateOrigin_Note(); + CSQCPlayer_PostUpdate(); + + { CSQCMODEL_HOOK_POSTUPDATE } + +#ifdef CSQCMODEL_SUPPORT_GETTAGINFO_BEFORE_DRAW + InterpolateOrigin_Do(); + CSQCModel_InterpolateAnimation_Do(); +#endif + + // relink + setorigin(self, self.origin); + + // set obvious render flags +#ifdef COMPAT_XON050_ENGINE + if(self.entnum == player_localentnum || self.entnum == spectatee_status) +#else + if(self.entnum == player_localentnum) +#endif + self.renderflags |= RF_EXTERNALMODEL; + else + self.renderflags &~= RF_EXTERNALMODEL; + + // draw it + self.drawmask = MASK_NORMAL; + self.predraw = CSQCModel_Draw; +} + +entity CSQCModel_server2csqc(float pl) +{ + return findfloat(world, entnum, pl); // FIXME optimize this using an array +} diff --git a/qcsrc/csqcmodellib/cl_model.qh b/qcsrc/csqcmodellib/cl_model.qh new file mode 100644 index 000000000..d38656533 --- /dev/null +++ b/qcsrc/csqcmodellib/cl_model.qh @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +void CSQCModel_Read(); + +#define CSQCMODEL_IF(cond) +#define CSQCMODEL_ENDIF +#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ + .t f; +#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f) + ALLPROPERTIES +#undef CSQCMODEL_PROPERTY_SCALED +#undef CSQCMODEL_PROPERTY +#undef CSQCMODEL_ENDIF +#undef CSQCMODEL_IF + +entity CSQCModel_server2csqc(float pl); +.float csqcmodel_teleported; diff --git a/qcsrc/csqcmodellib/cl_player.qc b/qcsrc/csqcmodellib/cl_player.qc new file mode 100644 index 000000000..9c62bbc5f --- /dev/null +++ b/qcsrc/csqcmodellib/cl_player.qc @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +var float autocvar_cl_predictionerrorcompensation = 0; + +// engine stuff +.float pmove_flags; +float pmove_onground; // weird engine flag we shouldn't really use but have to for now +#define PMF_JUMP_HELD 1 +#define PMF_DUCKED 4 +#define PMF_ONGROUND 8 +#define REFDEFFLAG_TELEPORTED 1 +#define REFDEFFLAG_JUMPING 2 + +entity csqcplayer; +vector csqcplayer_origin, csqcplayer_velocity; +float csqcplayer_sequence, player_pmflags; +float csqcplayer_moveframe; +vector csqcplayer_predictionerror; +float csqcplayer_predictionerrortime; + +vector CSQCPlayer_GetPredictionError() +{ + if(!autocvar_cl_predictionerrorcompensation) + return '0 0 0'; + if(time < csqcplayer_predictionerrortime) + return csqcplayer_predictionerror * (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation; + return '0 0 0'; +} + +void CSQCPlayer_SetPredictionError(vector v) +{ + if(!autocvar_cl_predictionerrorcompensation) + return; + csqcplayer_predictionerror = (csqcplayer_predictionerrortime - time) * autocvar_cl_predictionerrorcompensation * csqcplayer_predictionerror + v; + csqcplayer_predictionerrortime = time + 1.0 / autocvar_cl_predictionerrorcompensation; +} + +void CSQCPlayer_Unpredict() +{ + if(csqcplayer_status == CSQCPLAYERSTATUS_UNPREDICTED) + return; + if(csqcplayer_status != CSQCPLAYERSTATUS_PREDICTED) + error("Cannot unpredict in current status"); + self.origin = csqcplayer_origin; + self.velocity = csqcplayer_velocity; + csqcplayer_moveframe = csqcplayer_sequence+1; //+1 because the recieved frame has the move already done (server side) + self.pmove_flags = player_pmflags; +} + +void CSQCPlayer_SetMinsMaxs() +{ + if(self.pmove_flags & PMF_DUCKED) + { + self.mins = PL_CROUCH_MIN; + self.maxs = PL_CROUCH_MAX; + self.view_ofs = PL_CROUCH_VIEW_OFS; + } + else + { + self.mins = PL_MIN; + self.maxs = PL_MAX; + self.view_ofs = PL_VIEW_OFS; + } +} + +void CSQCPlayer_SavePrediction() +{ + player_pmflags = self.pmove_flags; + csqcplayer_origin = self.origin; + csqcplayer_velocity = self.velocity; + csqcplayer_sequence = servercommandframe; + csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; +} + +void CSQCPlayer_PredictTo(float endframe) +{ + CSQCPlayer_Unpredict(); + CSQCPlayer_SetMinsMaxs(); + + csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; + + if (getstatf(STAT_HEALTH) <= 0) + { + csqcplayer_moveframe = clientcommandframe; + getinputstate(csqcplayer_moveframe-1); + return; + } + + while(csqcplayer_moveframe < endframe) + { + if (!getinputstate(csqcplayer_moveframe)) + { + break; + } + if(input_timelength <= 0.0005) // too short move + { + dprint("CSQC physics hack: too short frame skipped\n"); + // even if not running physics, handle releasing the jump key + if(!(input_buttons & 4)) + self.pmove_flags &~= PMF_JUMP_HELD; + } + else if(input_timelength > 0.05) // too long move + { + dprint("CSQC physics hack: too long frame split in two\n"); + input_timelength *= 0.5; + runstandardplayerphysics(self); + CSQCPlayer_SetMinsMaxs(); + runstandardplayerphysics(self); + CSQCPlayer_SetMinsMaxs(); + } + else + { + runstandardplayerphysics(self); + CSQCPlayer_SetMinsMaxs(); + } + csqcplayer_moveframe++; + } + + //add in anything that was applied after (for low packet rate protocols) + input_angles = view_angles; +} + +float CSQCPlayer_IsLocalPlayer() +{ + return (self == csqcplayer); +} + +void(entity e, float fl) V_CalcRefdef = #640; // DP_CSQC_V_CALCREFDEF + +void CSQCPlayer_SetCamera() +{ + if(csqcplayer) + { + entity oldself; + oldself = self; + self = csqcplayer; + +#ifdef COMPAT_XON050_ENGINE + if(servercommandframe == 0 || !(checkextension("DP_CSQC_V_CALCREFDEF") || checkextension("DP_CSQC_V_CALCREFDEF_WIP1"))) +#else + if(servercommandframe == 0) +#endif + { + InterpolateOrigin_Do(); + self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT); + + // get crouch state from the server + if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z) + self.pmove_flags &~= PMF_DUCKED; + else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z) + self.pmove_flags |= PMF_DUCKED; + + // get onground state from the server + if(pmove_onground) + self.pmove_flags |= PMF_ONGROUND; + else + self.pmove_flags &~= PMF_ONGROUND; + + CSQCPlayer_SetMinsMaxs(); + + // override it back just in case + self.view_ofs = '0 0 1' * getstati(STAT_VIEWHEIGHT); + } + else + { + if(csqcplayer_status == CSQCPLAYERSTATUS_FROMSERVER) + { + vector o, v; + o = self.origin; + v = pmove_vel; // TRICK: pmove_vel is set by the engine when we get here. No need to network velocity + csqcplayer_status = CSQCPLAYERSTATUS_PREDICTED; + CSQCPlayer_PredictTo(servercommandframe + 1); + CSQCPlayer_SetPredictionError(o - self.origin); + self.origin = o; + self.velocity = v; + + // get crouch state from the server + if(getstati(STAT_VIEWHEIGHT) == PL_VIEW_OFS_z) + self.pmove_flags &~= PMF_DUCKED; + else if(getstati(STAT_VIEWHEIGHT) == PL_CROUCH_VIEW_OFS_z) + self.pmove_flags |= PMF_DUCKED; + + // get onground state from the server + if(pmove_onground) + self.pmove_flags |= PMF_ONGROUND; + else + self.pmove_flags &~= PMF_ONGROUND; + + CSQCPlayer_SavePrediction(); + } + CSQCPlayer_PredictTo(clientcommandframe + 1); + + CSQCPlayer_SetMinsMaxs(); + + self.angles_y = input_angles_y; + } + + // relink + setorigin(self, self.origin); + + self = oldself; + } + + entity view; +#ifdef COMPAT_XON050_ENGINE + view = CSQCModel_server2csqc((spectatee_status > 0) ? spectatee_status : player_localentnum); +#else + view = CSQCModel_server2csqc(player_localentnum); +#endif + +#ifdef COMPAT_XON050_ENGINE + if(view && !(checkextension("DP_CSQC_V_CALCREFDEF") || checkextension("DP_CSQC_V_CALCREFDEF_WIP1"))) + { + // legacy code, not totally correct, but good enough for not having V_CalcRefdef + setproperty(VF_ORIGIN, view.origin + '0 0 1' * getstati(STAT_VIEWHEIGHT)); + setproperty(VF_ANGLES, view_angles); + } + else +#endif + if(view) + { + var float refdefflags = 0; + + if(view.csqcmodel_teleported) + refdefflags |= REFDEFFLAG_TELEPORTED; + + if(input_buttons & 4) + refdefflags |= REFDEFFLAG_JUMPING; + + V_CalcRefdef(view, refdefflags); + } + else + { + setproperty(VF_ORIGIN, pmove_org + '0 0 1' * getstati(STAT_VIEWHEIGHT)); + setproperty(VF_ANGLES, view_angles); + } + + { CSQCPLAYER_HOOK_POSTCAMERASETUP } +} + +void CSQCPlayer_Remove() +{ + if(self.entnum != player_localnum + 1) + return; + csqcplayer = world; + cvar_clientsettemp("cl_movement_replay", "1"); +} + +float CSQCPlayer_PreUpdate() +{ + if(self.entnum != player_localnum + 1) + return 0; + cvar_clientsettemp("cl_movement_replay", "0"); + if(csqcplayer_status != CSQCPLAYERSTATUS_FROMSERVER) + CSQCPlayer_Unpredict(); + return 1; +} + +float CSQCPlayer_PostUpdate() +{ + if(self.entnum != player_localentnum) + return 0; + csqcplayer_status = CSQCPLAYERSTATUS_FROMSERVER; + csqcplayer = self; + self.entremove = CSQCPlayer_Remove; + return 1; +} diff --git a/qcsrc/csqcmodellib/cl_player.qh b/qcsrc/csqcmodellib/cl_player.qh new file mode 100644 index 000000000..0eecabed8 --- /dev/null +++ b/qcsrc/csqcmodellib/cl_player.qh @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +float csqcplayer_status; +#define CSQCPLAYERSTATUS_UNPREDICTED 0 +#define CSQCPLAYERSTATUS_FROMSERVER 1 +#define CSQCPLAYERSTATUS_PREDICTED 2 + +void CSQCPlayer_SetCamera(); +float CSQCPlayer_PreUpdate(); +float CSQCPlayer_PostUpdate(); +float CSQCPlayer_IsLocalPlayer(); diff --git a/qcsrc/csqcmodellib/common.qh b/qcsrc/csqcmodellib/common.qh new file mode 100644 index 000000000..587645cd4 --- /dev/null +++ b/qcsrc/csqcmodellib/common.qh @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +noref string csqcmodel_license = "\ +Copyright (c) 2011 Rudolf Polzer\ +\ +Permission is hereby granted, free of charge, to any person obtaining a copy\ +of this software and associated documentation files (the \"Software\"), to\ +deal in the Software without restriction, including without limitation the\ +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\ +sell copies of the Software, and to permit persons to whom the Software is\ +furnished to do so, subject to the following conditions:\ +\ +The above copyright notice and this permission notice shall be included in\ +all copies or substantial portions of the Software.\ +\ +THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\ +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\ +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\ +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\ +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\ +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\ +IN THE SOFTWARE.\ +"; + +.vector glowmod; +.vector view_ofs; +.float frame; +.float frame1time; +.float frame2; +.float frame2time; +.float lerpfrac; + +#define CSQCMODEL_PROPERTY_FRAME 32768 +#define CSQCMODEL_PROPERTY_FRAME2 16384 +#define CSQCMODEL_PROPERTY_LERPFRAC 8192 +#define CSQCMODEL_PROPERTY_TELEPORTED 4096 // the "teleport bit" cancelling interpolation +#define CSQCMODEL_PROPERTY_MODELINDEX 2048 +#define CSQCMODEL_PROPERTY_ORIGIN 1024 +#define CSQCMODEL_PROPERTY_YAW 512 +#define CSQCMODEL_PROPERTY_PITCHROLL 256 + +#define ALLPROPERTIES_COMMON \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_FRAME, float, ReadByte, WriteByte, frame) \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_MODELINDEX, float, ReadShort, WriteShort, modelindex) \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_x) \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_y) \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_ORIGIN, float, ReadCoord, WriteCoord, origin_z) \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_PITCHROLL, float, ReadAngle, WriteAngle, angles_x) \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_YAW, float, ReadAngle, WriteAngle, angles_y) \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_PITCHROLL, float, ReadAngle, WriteAngle, angles_z) \ + CSQCMODEL_EXTRAPROPERTIES + +#ifdef CSQCMODEL_HAVE_TWO_FRAMES +.float frame3; +.float frame3time; +.float lerpfrac3; +.float frame4; +.float frame4time; +.float lerpfrac4; +#define ALLPROPERTIES ALLPROPERTIES_COMMON \ + CSQCMODEL_PROPERTY(CSQCMODEL_PROPERTY_FRAME2, float, ReadByte, WriteByte, frame2) \ + CSQCMODEL_PROPERTY_SCALED(CSQCMODEL_PROPERTY_LERPFRAC, float, ReadByte, WriteByte, lerpfrac, 255, 0, 255) +#else +#define ALLPROPERTIES ALLPROPERTIES_COMMON +#endif diff --git a/qcsrc/csqcmodellib/interpolate.qc b/qcsrc/csqcmodellib/interpolate.qc new file mode 100644 index 000000000..ac0ba6e7d --- /dev/null +++ b/qcsrc/csqcmodellib/interpolate.qc @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +.vector iorigin1, iorigin2; +.vector ivelocity1, ivelocity2; +.vector iforward1, iforward2; +.vector iup1, iup2; +.float itime1, itime2; +void InterpolateOrigin_Reset() +{ + self.iflags &~= IFLAG_INTERNALMASK; + self.itime1 = self.itime2 = 0; +} +void InterpolateOrigin_Note() +{ + float dt; + float f0; + + dt = time - self.itime2; + + f0 = self.iflags; + if(self.iflags & IFLAG_PREVALID) + self.iflags |= IFLAG_VALID; + else + self.iflags |= IFLAG_PREVALID; + + self.iorigin1 = self.iorigin2; + self.iorigin2 = self.origin; + + if(self.iflags & IFLAG_AUTOANGLES) + if(self.iorigin2 != self.iorigin1) + self.angles = vectoangles(self.iorigin2 - self.iorigin1); + + if(self.iflags & IFLAG_ANGLES) + { + fixedmakevectors(self.angles); + if(f0 & IFLAG_VALID) + { + self.iforward1 = self.iforward2; + self.iup1 = self.iup2; + } + else + { + self.iforward1 = v_forward; + self.iup1 = v_up; + } + self.iforward2 = v_forward; + self.iup2 = v_up; + } + + if(self.iflags & IFLAG_VELOCITY) + { + self.ivelocity1 = self.ivelocity2; + self.ivelocity2 = self.velocity; + } + + if(self.iflags & IFLAG_TELEPORTED) + { + self.iflags &~= IFLAG_TELEPORTED; + self.itime1 = self.itime2 = time; // don't lerp + } + else if(vlen(self.iorigin2 - self.iorigin1) > 1000) + { + self.itime1 = self.itime2 = time; // don't lerp + } + else if((self.iflags & IFLAG_VELOCITY) && (vlen(self.ivelocity2 - self.ivelocity1) > 1000)) + { + self.itime1 = self.itime2 = time; // don't lerp + } + else if(dt >= 0.2) + { + self.itime1 = self.itime2 = time; + } + else + { + self.itime1 = serverprevtime; + self.itime2 = time; + } +} +void InterpolateOrigin_Do() +{ + vector forward, up; + if(self.itime1 && self.itime2 && self.itime1 != self.itime2) + { + float f; + f = bound(0, (time - self.itime1) / (self.itime2 - self.itime1), 1 + autocvar_cl_lerpexcess); + self.origin = (1 - f) * self.iorigin1 + f * self.iorigin2; + if(self.iflags & IFLAG_ANGLES) + { + forward = (1 - f) * self.iforward1 + f * self.iforward2; + up = (1 - f) * self.iup1 + f * self.iup2; + self.angles = fixedvectoangles2(forward, up); + } + if(self.iflags & IFLAG_VELOCITY) + self.velocity = (1 - f) * self.ivelocity1 + f * self.ivelocity2; + } +} +void InterpolateOrigin_Undo() +{ + self.origin = self.iorigin2; + if(self.iflags & IFLAG_ANGLES) + self.angles = fixedvectoangles2(self.iforward2, self.iup2); + if(self.iflags & IFLAG_VELOCITY) + self.velocity = self.ivelocity2; +} + diff --git a/qcsrc/csqcmodellib/interpolate.qh b/qcsrc/csqcmodellib/interpolate.qh new file mode 100644 index 000000000..8254fae8c --- /dev/null +++ b/qcsrc/csqcmodellib/interpolate.qh @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +.float iflags; +#define IFLAG_VELOCITY 1 +#define IFLAG_ANGLES 2 +#define IFLAG_AUTOANGLES 4 +#define IFLAG_VALID 8 +#define IFLAG_PREVALID 16 +#define IFLAG_TELEPORTED 32 +#define IFLAG_INTERNALMASK (IFLAG_VALID | IFLAG_PREVALID) + +// call this BEFORE reading an entity update +void InterpolateOrigin_Undo(); + +// call this AFTER receiving an entity update +void InterpolateOrigin_Note(); + +// call this when the entity got teleported, before InterpolateOrigin_Note +void InterpolateOrigin_Reset(); + +// call this BEFORE drawing +void InterpolateOrigin_Do(); diff --git a/qcsrc/csqcmodellib/sv_model.qc b/qcsrc/csqcmodellib/sv_model.qc new file mode 100644 index 000000000..1c214e0ab --- /dev/null +++ b/qcsrc/csqcmodellib/sv_model.qc @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +// generic CSQC model code + +float CSQCModel_Send(entity to, float sf) +{ + // some nice flags for CSQCMODEL_IF + float isplayer = (self.flags & FL_CLIENT); + float islocalplayer = (self == to); + float isnolocalplayer = (isplayer && (self != to)); + + WriteByte(MSG_ENTITY, ENT_CLIENT_MODEL); + WriteShort(MSG_ENTITY, sf); + +#define CSQCMODEL_IF(cond) if(cond) { +#define CSQCMODEL_ENDIF } +#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ + if(sf & flag) \ + { \ + w(MSG_ENTITY, self.csqcmodel_##f); \ + } +#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f) + ALLPROPERTIES +#undef CSQCMODEL_PROPERTY_SCALED +#undef CSQCMODEL_PROPERTY +#undef CSQCMODEL_ENDIF +#undef CSQCMODEL_IF + + return TRUE; +} + +#ifdef CSQCPLAYER_FORCE_UPDATES +.float csqcmodel_nextforcedupdate; +#endif +void CSQCModel_CheckUpdate() +{ + // some nice flags for CSQCMODEL_IF + float isplayer = (self.flags & FL_CLIENT); + float islocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags + float isnolocalplayer = isplayer; // we set BOTH to 1 here as we need the sendflags + +#ifdef CSQCPLAYER_FORCE_UPDATES + if(isplayer && time > self.csqcmodel_nextforcedupdate) + { + self.SendFlags |= CSQCMODEL_PROPERTY_ORIGIN; + self.csqcmodel_nextforcedupdate = time + CSQCPLAYER_FORCE_UPDATES * (0.5 + random()); // ensure about 4 origin sends per sec + } +#endif + + if(self.effects & EF_RESTARTANIM_BIT) + { + self.SendFlags |= CSQCMODEL_PROPERTY_FRAME | CSQCMODEL_PROPERTY_FRAME2; // full anim resend please + self.effects &~= EF_RESTARTANIM_BIT; + } + + if(self.effects & EF_TELEPORT_BIT) + { + self.SendFlags |= CSQCMODEL_PROPERTY_TELEPORTED; // no interpolation please + self.effects &~= EF_TELEPORT_BIT; + } + +#define CSQCMODEL_IF(cond) if(cond) { +#define CSQCMODEL_ENDIF } +#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ + { \ + t tmp = self.f; \ + if(tmp != self.csqcmodel_##f) \ + { \ + self.csqcmodel_##f = tmp; \ + self.SendFlags |= flag; \ + } \ + } +#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \ + { \ + t tmp = bound(mi, s * self.f, ma); \ + if(tmp != self.csqcmodel_##f) \ + { \ + self.csqcmodel_##f = tmp; \ + self.SendFlags |= flag; \ + } \ + } + ALLPROPERTIES +#undef CSQCMODEL_PROPERTY_SCALED +#undef CSQCMODEL_PROPERTY +#undef CSQCMODEL_ENDIF +#undef CSQCMODEL_IF +} + +void CSQCModel_LinkEntity() +{ + self.SendEntity = CSQCModel_Send; + self.SendFlags = 0xFFFFFF; +} + +void CSQCModel_UnlinkEntity() +{ + self.SendEntity = func_null; +} diff --git a/qcsrc/csqcmodellib/sv_model.qh b/qcsrc/csqcmodellib/sv_model.qh new file mode 100644 index 000000000..3c4ce2b78 --- /dev/null +++ b/qcsrc/csqcmodellib/sv_model.qh @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2011 Rudolf Polzer + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +// generic CSQC model code + +void CSQCModel_CheckUpdate(); +void CSQCModel_LinkEntity(); +void CSQCModel_UnlinkEntity(); + +#define CSQCMODEL_IF(cond) +#define CSQCMODEL_ENDIF +#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \ + .t f; \ + .t csqcmodel_##f; +#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) CSQCMODEL_PROPERTY(flag,t,r,w,f) + ALLPROPERTIES +#undef CSQCMODEL_PROPERTY_SCALED +#undef CSQCMODEL_PROPERTY +#undef CSQCMODEL_ENDIF +#undef CSQCMODEL_IF diff --git a/qcsrc/server/progs.src b/qcsrc/server/progs.src index 45d83116f..083feb4e2 100644 --- a/qcsrc/server/progs.src +++ b/qcsrc/server/progs.src @@ -38,9 +38,9 @@ campaign.qh accuracy.qh csqcprojectile.qh -../csqcmodel/settings.qh -../csqcmodel/common.qh -../csqcmodel/sv_model.qh +../common/csqcmodel_settings.qh +../csqcmodellib/common.qh +../csqcmodellib/sv_model.qh csqceffects.qc anticheat.qh @@ -179,7 +179,7 @@ target_music.qc accuracy.qc -../csqcmodel/sv_model.qc +../csqcmodellib/sv_model.qc csqcprojectile.qc playerdemo.qc