]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/csqcmodel/cl_model.qc
Merge branch 'master' into divVerent/csqcmodel
[xonotic/xonotic-data.pk3dir.git] / qcsrc / csqcmodel / cl_model.qc
index e5bf9c54a4223a523d5f5ece6f9d60997dce1f32..c6d2923d4514c9cc8da2ad41caaf91ae57e326f7 100644 (file)
@@ -20,8 +20,6 @@
  * IN THE SOFTWARE.
  */
 
-// generic CSQC model code
-
 var float autocvar_cl_lerpanim_maxdelta_framegroups = 0.1;
 var float autocvar_cl_nolerp = 0;
 
@@ -29,28 +27,29 @@ var float autocvar_cl_nolerp = 0;
 .float csqcmodel_lerpfrac2;
 .float csqcmodel_lerpfractime;
 .float csqcmodel_lerpfrac2time;
+.float csqcmodel_teleported;
 
 void CSQCModel_InterpolateAnimation_PreNote(float sf)
 {
-#ifdef CSQCMODELS_HAVE_TWO_FRAMES
-       if(sf & PROPERTY_FRAME)
+#ifdef CSQCMODEL_HAVE_TWO_FRAMES
+       if(sf & CSQCMODEL_PROPERTY_FRAME)
        {
                self.frame3 = self.frame;
                self.frame3time = self.frame1time;
        }
-       if(sf & PROPERTY_FRAME2)
+       if(sf & CSQCMODEL_PROPERTY_FRAME2)
        {
                self.frame4 = self.frame2;
                self.frame4time = self.frame2time;
        }
-       if(sf & PROPERTY_LERPFRAC)
+       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 & PROPERTY_FRAME)
+       if(sf & CSQCMODEL_PROPERTY_FRAME)
        {
                self.frame2 = self.frame;
                self.frame2time = self.frame1time;
@@ -60,22 +59,22 @@ void CSQCModel_InterpolateAnimation_PreNote(float sf)
 
 void CSQCModel_InterpolateAnimation_Note(float sf)
 {
-#ifdef CSQCMODELS_HAVE_TWO_FRAMES
-       if(sf & PROPERTY_FRAME)
+#ifdef CSQCMODEL_HAVE_TWO_FRAMES
+       if(sf & CSQCMODEL_PROPERTY_FRAME)
        {
                self.frame1time = time;
        }
-       if(sf & PROPERTY_FRAME2)
+       if(sf & CSQCMODEL_PROPERTY_FRAME2)
        {
                self.frame2time = time;
        }
-       if(sf & PROPERTY_LERPFRAC)
+       if(sf & CSQCMODEL_PROPERTY_LERPFRAC)
        {
                self.csqcmodel_lerpfrac = self.lerpfrac;
                self.csqcmodel_lerpfractime = time;
        }
 #else
-       if(sf & PROPERTY_FRAME)
+       if(sf & CSQCMODEL_PROPERTY_FRAME)
        {
                self.frame1time = time;
        }
@@ -84,7 +83,7 @@ void CSQCModel_InterpolateAnimation_Note(float sf)
 
 void CSQCModel_InterpolateAnimation_Do()
 {
-#ifdef CSQCMODELS_HAVE_TWO_FRAMES
+#ifdef CSQCMODEL_HAVE_TWO_FRAMES
        if(autocvar_cl_nolerp || (autocvar_cl_lerpanim_maxdelta_framegroups == 0))
        {
                self.lerpfrac = self.csqcmodel_lerpfrac;
@@ -143,6 +142,11 @@ void CSQCModel_InterpolateAnimation_Do()
 
 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())
@@ -151,7 +155,17 @@ void CSQCModel_Draw()
        // TODO csqcplayers: run prediction here too
        CSQCModel_InterpolateAnimation_Do();
 
-       { CSQCMODELS_HOOK_PREDRAW }
+       { 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));
+       }
 }
 
 void CSQCModel_Read()
@@ -159,38 +173,66 @@ 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
 
-       { CSQCMODELS_HOOK_PREUPDATE }
+       { CSQCMODEL_HOOK_PREUPDATE }
 
        CSQCPlayer_PreUpdate();
        InterpolateOrigin_Undo();
        CSQCModel_InterpolateAnimation_PreNote(sf);
 
-#define PROPERTY(flag,r,w,f) \
+#define CSQCMODEL_IF(cond) if(cond) {
+#define CSQCMODEL_ENDIF }
+#define CSQCMODEL_PROPERTY(flag,t,r,w,f) \
        if(sf & flag) \
                self.f = r();
-#define PROPERTY_SCALED(flag,r,w,f,s,mi,ma) \
+#define CSQCMODEL_PROPERTY_SCALED(flag,t,r,w,f,s,mi,ma) \
        if(sf & flag) \
                self.f = r() / s;
        ALLPROPERTIES
-#undef PROPERTY_SCALED
-#undef PROPERTY
+#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 & PROPERTY_TELEPORTED)
+       if(sf & CSQCMODEL_PROPERTY_TELEPORTED)
+       {
                self.iflags |= IFLAG_TELEPORTED;
+               self.csqcmodel_teleported = 1;
+       }
        
        CSQCModel_InterpolateAnimation_Note(sf);
        InterpolateOrigin_Note();
        CSQCPlayer_PostUpdate();
 
-       { CSQCMODELS_HOOK_POSTUPDATE }
+       { CSQCMODEL_HOOK_POSTUPDATE }
 
-#ifdef CSQCMODELS_SUPPORT_GETTAGINFO_BEFORE_DRAW
+#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;