]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Viewmodel: animate clientside
authorTimePath <andrew.hardaker1995@gmail.com>
Mon, 2 Nov 2015 06:15:30 +0000 (17:15 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Mon, 2 Nov 2015 06:15:30 +0000 (17:15 +1100)
qcsrc/client/view.qc
qcsrc/common/stats.qh
qcsrc/common/weapons/all.qc
qcsrc/common/weapons/weapon.qh
qcsrc/server/defs.qh
qcsrc/server/g_world.qc
qcsrc/server/weapons/weaponsystem.qc

index 95167a1c4c752c4189d6a6e5568f02b6d0c2d5fa..dcd9d7ecc7cf688755df462f149b3a892cf4d46b 100644 (file)
@@ -49,6 +49,45 @@ void viewmodel_draw(entity this)
                e.csqcmodel_effects = fx;
                WITH(entity, self, e, CSQCModel_Effects_Apply());
        }
+       {
+               static string name_last;
+               string name = get_weaponinfo(activeweapon).mdl;
+               if (name != name_last)
+               {
+                       name_last = name;
+                       CL_WeaponEntity_SetModel(this, name);
+                       updateanim(this);
+                       if (!this.animstate_override)
+                               setanim(this, this.anim_idle, true, false, false);
+               }
+       }
+       float eta = (getstatf(STAT_WEAPON_NEXTTHINK) - time); // TODO: / W_WeaponRateFactor();
+       float f = 0; // 0..1; 0: fully active
+       switch (this.state)
+       {
+               case WS_RAISE:
+               {
+                       // entity newwep = Weapons_from(activeweapon);
+                       float delay = 0.2; // TODO: newwep.switchdelay_raise;
+                       f = eta / max(eta, delay);
+                       this.angles_x = -90 * f * f;
+                       break;
+               }
+               case WS_DROP:
+               {
+                       // entity oldwep = Weapons_from(activeweapon);
+                       float delay = 0.2; // TODO: newwep.switchdelay_drop;
+                       f = 1 - eta / max(eta, delay);
+                       this.angles_x = -90 * f * f;
+                       break;
+               }
+               case WS_CLEAR:
+               {
+                       f = 1;
+                       break;
+               }
+       }
+       this.angles_x = -90 * f * f;
 }
 
 entity viewmodel;
@@ -1262,18 +1301,6 @@ void CSQC_UpdateView(float w, float h)
 
        WarpZone_FixView();
        //WarpZone_FixPMove();
-       {
-               static string name_last;
-               string name = get_weaponinfo(switchingweapon).mdl;
-               if (name != name_last)
-               {
-                   name_last = name;
-                       CL_WeaponEntity_SetModel(viewmodel, name);
-                       updateanim(viewmodel);
-                       if (!viewmodel.animstate_override)
-                               setanim(viewmodel, viewmodel.anim_idle, true, false, false);
-               }
-       }
 
        vector ov_org = '0 0 0';
        vector ov_mid = '0 0 0';
index 9bdcb5773a5e4bcff57fe8079b53542babfa2bef..68bfbe8332ee4b5b881b79a7f04da839fe8f6093 100644 (file)
@@ -109,7 +109,7 @@ const int STAT_OK_AMMO_CHARGE         = 85;
 const int STAT_OK_AMMO_CHARGEPOOL     = 86;
 const int STAT_FROZEN                 = 87;
 const int STAT_REVIVE_PROGRESS        = 88;
-// 89 empty?
+const int STAT_WEAPON_NEXTTHINK       = 89;
 // 90 empty?
 // 91 empty?
 // 92 empty?
index cb397e8e5e99fde095e2a20eca5ae3e16e4fb424..11f0414e63d9b13b1957273ef51cebbfdd16ba21 100644 (file)
@@ -591,11 +591,12 @@ REGISTER_NET_TEMP(wframe, bool isNew)
     a.z = ReadCoord();
        bool restartanim = ReadByte();
        setanim(viewmodel, a, restartanim == false, restartanim, restartanim);
+       viewmodel.state = ReadByte();
 }
 #endif
 
 #ifdef SVQC
-void wframe_send(entity actor, vector a, bool restartanim)
+void wframe_send(entity actor, .entity weaponentity, vector a, bool restartanim)
 {
        if (!IS_REAL_CLIENT(actor)) return;
        int channel = MSG_ONE;
@@ -605,6 +606,7 @@ void wframe_send(entity actor, vector a, bool restartanim)
        WriteCoord(channel, a.y);
        WriteCoord(channel, a.z);
        WriteByte(channel, restartanim);
+       WriteByte(channel, actor.(weaponentity).state);
 }
 #endif
 
index 3a878a461d1f933a93160409ae4f873e5aae5ff7..2a92f955b50fc1cd16beb89dbe64f50de2ec3c2f 100644 (file)
@@ -17,6 +17,18 @@ int weaponslot(.entity weaponentity)
        return 0;
 }
 
+// weapon states (actor.(weaponentity).state)
+/** no weapon selected */
+const int WS_CLEAR  = 0;
+/** raise frame */
+const int WS_RAISE  = 1;
+/** deselecting frame */
+const int WS_DROP   = 2;
+/** fire state */
+const int WS_INUSE  = 3;
+/** idle frame */
+const int WS_READY  = 4;
+
 .int ammo_shells;
 .int ammo_nails;
 .int ammo_rockets;
index c419346a58f24ed7e9eb3b8a12d90b83a33c68b1..f85a94b3a40d247b0577f893a85f97659da1f8c3 100644 (file)
@@ -154,13 +154,6 @@ void w_ready(Weapon thiswep, entity actor, .entity weaponentity, int fire);
 .void(Weapon thiswep, entity actor, .entity weaponentity, int fire) weapon_think;
 
 
-// weapon states (self.weaponentity.state)
-const int WS_CLEAR                     = 0; // no weapon selected
-const int WS_RAISE                     = 1; // raise frame
-const int WS_DROP                              = 2; // deselecting frame
-const int WS_INUSE                     = 3; // fire state
-const int WS_READY                     = 4; // idle frame
-
 // there is 2 weapon tics that can run in one server frame
 const int W_TICSPERFRAME = 2;
 
index 7af45b38140870db94de916a4a713806ff29549a..79afb490df58c1bad588548f5866e566cd125511 100644 (file)
@@ -772,6 +772,7 @@ spawnfunc(worldspawn)
        WepSet_AddStat_InMap();
        addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon);
        addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon);
+       addstat(STAT_WEAPON_NEXTTHINK, AS_FLOAT, weapon_nextthink);
        addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime);
        addstat(STAT_ROUNDSTARTTIME, AS_FLOAT, stat_round_starttime);
        addstat(STAT_ALLOW_OLDVORTEXBEAM, AS_INT, stat_allow_oldvortexbeam);
index 98ebdf641fca3ff69697a73f1fae4072cafde822..395834ef0617f74f844c3ea53d41b61985b92aed 100644 (file)
@@ -119,27 +119,6 @@ void CL_Weaponentity_Think()
                this.weaponchild.colormap = this.colormap;
                this.weaponchild.glowmod = this.glowmod;
        }
-
-       this.angles = '0 0 0';
-
-       float f = this.owner.weapon_nextthink - time;
-       if (this.state == WS_RAISE && !intermission_running)
-       {
-               entity newwep = Weapons_from(this.owner.switchweapon);
-               f = f * g_weaponratefactor / max(f, newwep.switchdelay_raise);
-               this.angles_x = -90 * f * f;
-       }
-       else if (this.state == WS_DROP && !intermission_running)
-       {
-               entity oldwep = Weapons_from(this.owner.weapon);
-               f = 1 - f * g_weaponratefactor / max(f, oldwep.switchdelay_drop);
-               this.angles_x = -90 * f * f;
-       }
-       else if (this.state == WS_CLEAR)
-       {
-               f = 1;
-               this.angles_x = -90 * f * f;
-       }
 }
 
 void CL_ExteriorWeaponentity_Think()
@@ -344,7 +323,7 @@ bool weapon_prepareattack(Weapon thiswep, entity actor, .entity weaponentity, bo
        return false;
 }
 
-void wframe_send(entity actor, vector a, bool restartanim);
+void wframe_send(entity actor, .entity weaponentity, vector a, bool restartanim);
 
 void weapon_thinkf(entity actor, .entity weaponentity, float fr, float t, void(Weapon thiswep, entity actor,
        .entity weaponentity, int fire) func)
@@ -378,7 +357,7 @@ void weapon_thinkf(entity actor, .entity weaponentity, float fr, float t, void(W
                else  // if (fr == WFRAME_RELOAD)
                        a = actor.(weaponentity).anim_reload;
                a.z *= g_weaponratefactor;
-               wframe_send(actor, a, restartanim);
+               wframe_send(actor, weaponentity, a, restartanim);
        }
 
        v_forward = of;
@@ -402,7 +381,7 @@ void weapon_thinkf(entity actor, .entity weaponentity, float fr, float t, void(W
                actor.weapon_nextthink = time;
                // dprint("reset weapon animation timer at ", ftos(time), "\n");
        }
-       actor.weapon_nextthink = actor.weapon_nextthink + t;
+       actor.weapon_nextthink += t;
        actor.weapon_think = func;
        // dprint("next ", ftos(actor.weapon_nextthink), "\n");