From eb81cc1498c2142011ea97308ad40aa48bcb64f2 Mon Sep 17 00:00:00 2001 From: TimePath Date: Mon, 2 Nov 2015 17:15:30 +1100 Subject: [PATCH] Viewmodel: animate clientside --- qcsrc/client/view.qc | 51 +++++++++++++++++++++------- qcsrc/common/stats.qh | 2 +- qcsrc/common/weapons/all.qc | 4 ++- qcsrc/common/weapons/weapon.qh | 12 +++++++ qcsrc/server/defs.qh | 7 ---- qcsrc/server/g_world.qc | 1 + qcsrc/server/weapons/weaponsystem.qc | 27 ++------------- 7 files changed, 59 insertions(+), 45 deletions(-) diff --git a/qcsrc/client/view.qc b/qcsrc/client/view.qc index 95167a1c4..dcd9d7ecc 100644 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@ -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'; diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh index 9bdcb5773..68bfbe833 100644 --- a/qcsrc/common/stats.qh +++ b/qcsrc/common/stats.qh @@ -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? diff --git a/qcsrc/common/weapons/all.qc b/qcsrc/common/weapons/all.qc index cb397e8e5..11f0414e6 100644 --- a/qcsrc/common/weapons/all.qc +++ b/qcsrc/common/weapons/all.qc @@ -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 diff --git a/qcsrc/common/weapons/weapon.qh b/qcsrc/common/weapons/weapon.qh index 3a878a461..2a92f955b 100644 --- a/qcsrc/common/weapons/weapon.qh +++ b/qcsrc/common/weapons/weapon.qh @@ -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; diff --git a/qcsrc/server/defs.qh b/qcsrc/server/defs.qh index c419346a5..f85a94b3a 100644 --- a/qcsrc/server/defs.qh +++ b/qcsrc/server/defs.qh @@ -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; diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index 7af45b381..79afb490d 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -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); diff --git a/qcsrc/server/weapons/weaponsystem.qc b/qcsrc/server/weapons/weaponsystem.qc index 98ebdf641..395834ef0 100644 --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@ -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"); -- 2.39.2