Anim: cleanup
authorTimePath <andrew.hardaker1995@gmail.com>
Fri, 6 Nov 2015 08:40:11 +0000 (19:40 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Fri, 6 Nov 2015 08:40:11 +0000 (19:40 +1100)
14 files changed:
qcsrc/Makefile
qcsrc/client/weapons/projectile.qc
qcsrc/common/anim.qc
qcsrc/common/anim.qh
qcsrc/common/triggers/subs.qh
qcsrc/common/weapons/all.qh
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/lib/_all.inc
qcsrc/lib/enumclass.qh [new file with mode: 0644]
qcsrc/server/cl_player.qc
qcsrc/server/defs.qh
qcsrc/server/g_subs.qh
qcsrc/server/weapons/weaponsystem.qc
qcsrc/server/weapons/weaponsystem.qh

index 452dfc9..b5b77e0 100644 (file)
@@ -22,6 +22,7 @@ QCCFLAGS ?= \
        -fftepp -flno -futf8 -fno-bail-on-werror -fftepp-predefs \
        -frelaxed-switch -freturn-assignments \
        $(QCCFLAGS_WATERMARK) \
+       -DNDEBUG=1 \
        $(QCCFLAGS_FEATURES) \
        $(QCCFLAGS_EXTRA)
 
index 9969a89..d220ccb 100644 (file)
@@ -282,47 +282,47 @@ void Ent_Projectile()
                self.traileffect = 0;
                switch (self.cnt)
                {
-                       #define CASE(id) case PROJECTILE_##id: setmodel(self, MDL_PROJECTILE_##id);
-                       CASE(ELECTRO)            self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-                       CASE(ROCKET)             self.traileffect = EFFECT_TR_ROCKET.m_id; self.scale = 2; break;
-                       CASE(CRYLINK)            self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
-                       CASE(CRYLINK_BOUNCING)   self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
-                       CASE(ELECTRO_BEAM)       self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-                       CASE(GRENADE)            self.traileffect = EFFECT_TR_GRENADE.m_id; break;
-                       CASE(GRENADE_BOUNCING)   self.traileffect = EFFECT_TR_GRENADE.m_id; break;
-                       CASE(MINE)               self.traileffect = EFFECT_TR_GRENADE.m_id; break;
-                       CASE(BLASTER)            self.traileffect = EFFECT_Null.m_id; break;
-                       CASE(HLAC)               self.traileffect = EFFECT_Null.m_id; break;
-                       CASE(PORTO_RED)          self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
-                       CASE(PORTO_BLUE)         self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
-                       CASE(HOOKBOMB)           self.traileffect = EFFECT_TR_KNIGHTSPIKE.m_id; break;
-                       CASE(HAGAR)              self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
-                       CASE(HAGAR_BOUNCING)     self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
-                       CASE(NAPALM_FOUNTAIN)                                                                         // fallthrough // sself.modelindex = 0; self.traileffect = _particleeffectnum("torch_small"); break;
-                       CASE(FIREBALL)           self.modelindex = 0; self.traileffect = EFFECT_FIREBALL.m_id; break; // particle effect is good enough
-                       CASE(FIREMINE)           self.modelindex = 0; self.traileffect = EFFECT_FIREMINE.m_id; break; // particle effect is good enough
-                       CASE(TAG)                self.traileffect = EFFECT_TR_ROCKET.m_id; break;
-                       CASE(FLAC)               self.scale = 0.4; self.traileffect = EFFECT_FLAC_TRAIL.m_id; break;
-                       CASE(SEEKER)             self.traileffect = EFFECT_SEEKER_TRAIL.m_id; break;
-
-                       CASE(MAGE_SPIKE)         self.traileffect = EFFECT_TR_VORESPIKE.m_id; break;
-                       CASE(SHAMBLER_LIGHTNING) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-
-                       CASE(RAPTORBOMB)         self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
-                       CASE(RAPTORBOMBLET)      self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
-                       CASE(RAPTORCANNON)       self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
-
-                       CASE(SPIDERROCKET)       self.traileffect = EFFECT_SPIDERBOT_ROCKET_TRAIL.m_id; break;
-                       CASE(WAKIROCKET)         self.traileffect = EFFECT_RACER_ROCKET_TRAIL.m_id; break;
-                       CASE(WAKICANNON)         self.traileffect = EFFECT_Null.m_id; break;
-
-                       CASE(BUMBLE_GUN)         self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-                       CASE(BUMBLE_BEAM)        self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-
-                       CASE(RPC)                self.traileffect = EFFECT_TR_ROCKET.m_id; break;
-
-                       CASE(ROCKETMINSTA_LASER) self.traileffect = EFFECT_ROCKETMINSTA_LASER(self.team).m_id; break;
-#undef CASE
+                       #define HANDLE(id) case PROJECTILE_##id: setmodel(self, MDL_PROJECTILE_##id);
+                       HANDLE(ELECTRO)            self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+                       HANDLE(ROCKET)             self.traileffect = EFFECT_TR_ROCKET.m_id; self.scale = 2; break;
+                       HANDLE(CRYLINK)            self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+                       HANDLE(CRYLINK_BOUNCING)   self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+                       HANDLE(ELECTRO_BEAM)       self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+                       HANDLE(GRENADE)            self.traileffect = EFFECT_TR_GRENADE.m_id; break;
+                       HANDLE(GRENADE_BOUNCING)   self.traileffect = EFFECT_TR_GRENADE.m_id; break;
+                       HANDLE(MINE)               self.traileffect = EFFECT_TR_GRENADE.m_id; break;
+                       HANDLE(BLASTER)            self.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(HLAC)               self.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(PORTO_RED)          self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
+                       HANDLE(PORTO_BLUE)         self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
+                       HANDLE(HOOKBOMB)           self.traileffect = EFFECT_TR_KNIGHTSPIKE.m_id; break;
+                       HANDLE(HAGAR)              self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
+                       HANDLE(HAGAR_BOUNCING)     self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
+                       HANDLE(NAPALM_FOUNTAIN)                                                                         // fallthrough // sself.modelindex = 0; self.traileffect = _particleeffectnum("torch_small"); break;
+                       HANDLE(FIREBALL)           self.modelindex = 0; self.traileffect = EFFECT_FIREBALL.m_id; break; // particle effect is good enough
+                       HANDLE(FIREMINE)           self.modelindex = 0; self.traileffect = EFFECT_FIREMINE.m_id; break; // particle effect is good enough
+                       HANDLE(TAG)                self.traileffect = EFFECT_TR_ROCKET.m_id; break;
+                       HANDLE(FLAC)               self.scale = 0.4; self.traileffect = EFFECT_FLAC_TRAIL.m_id; break;
+                       HANDLE(SEEKER)             self.traileffect = EFFECT_SEEKER_TRAIL.m_id; break;
+
+                       HANDLE(MAGE_SPIKE)         self.traileffect = EFFECT_TR_VORESPIKE.m_id; break;
+                       HANDLE(SHAMBLER_LIGHTNING) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+
+                       HANDLE(RAPTORBOMB)         self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(RAPTORBOMBLET)      self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
+                       HANDLE(RAPTORCANNON)       self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+
+                       HANDLE(SPIDERROCKET)       self.traileffect = EFFECT_SPIDERBOT_ROCKET_TRAIL.m_id; break;
+                       HANDLE(WAKIROCKET)         self.traileffect = EFFECT_RACER_ROCKET_TRAIL.m_id; break;
+                       HANDLE(WAKICANNON)         self.traileffect = EFFECT_Null.m_id; break;
+
+                       HANDLE(BUMBLE_GUN)         self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+                       HANDLE(BUMBLE_BEAM)        self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+
+                       HANDLE(RPC)                self.traileffect = EFFECT_TR_ROCKET.m_id; break;
+
+                       HANDLE(ROCKETMINSTA_LASER) self.traileffect = EFFECT_ROCKETMINSTA_LASER(self.team).m_id; break;
+#undef HANDLE
                        default:
                                if (MUTATOR_CALLHOOK(Ent_Projectile, self))
                                        break;
index c2781c6..6a4dbe5 100644 (file)
@@ -1,4 +1,9 @@
-void setanim(entity e, vector anim, bool looping, bool override, int restart)
+#include "anim.qh"
+
+/**
+ * @param anim x = startframe, y = numframes, z = framerate
+ */
+void anim_set(entity e, vector anim, bool looping, bool override, bool restart)
 {
        if (!anim) return;  // no animation was given to us! We can't use this.
 
@@ -9,7 +14,7 @@ void setanim(entity e, vector anim, bool looping, bool override, int restart)
                        if (anim.z == e.animstate_framerate)
                        {
                                if (!restart) return;
-                               if (restart > 0 && anim.y == 1)  // ZYM animation
+                               if (anim.y == 1)  // ZYM animation
                                        BITXOR_ASSIGN(e.effects, EF_RESTARTANIM_BIT);
                        }
                }
@@ -17,15 +22,18 @@ void setanim(entity e, vector anim, bool looping, bool override, int restart)
        e.animstate_startframe = anim.x;
        e.animstate_numframes = anim.y;
        e.animstate_framerate = anim.z;
-       e.animstate_starttime = servertime - 0.1 * frametime;  // shift it a little bit into the past to prevent float inaccuracy hiccups
+       e.animstate_starttime = time - 0.1 * frametime;  // shift it a little bit into the past to prevent float inaccuracy hiccups
        e.animstate_endtime = e.animstate_starttime + e.animstate_numframes / e.animstate_framerate;
        e.animstate_looping = looping;
        e.animstate_override = override;
        e.frame = e.animstate_startframe;
-       e.frame1time = servertime;
+       e.frame1time = time;
 }
 
-void updateanim(entity e)
+/**
+ * Update e.frame based on its animstate relative to time
+ */
+void anim_update(entity e)
 {
        if (time >= e.animstate_endtime)
        {
@@ -36,7 +44,6 @@ void updateanim(entity e)
                }
                e.animstate_override = false;
        }
-       e.frame = e.animstate_startframe + bound(0, (time - e.animstate_starttime) * e.animstate_framerate,
-               e.animstate_numframes - 1);
-       // print(ftos(time), " -> ", ftos(e.frame), "\n");
+       float frameofs = bound(0, (time - e.animstate_starttime) * e.animstate_framerate, e.animstate_numframes - 1);
+       e.frame = e.animstate_startframe + frameofs;
 }
index c1dee15..acf6735 100644 (file)
@@ -1,7 +1,50 @@
 #ifndef ANIM_H
 #define ANIM_H
 
-void setanim(entity e, vector anim, float looping, float override, float restart);
-void updateanim(entity e);
+// begin engine fields
+
+/** primary framegroup animation (strength = 1 - lerpfrac - lerpfrac3 - lerpfrac4) */
+.float frame;
+/** secondary framegroup animation (strength = lerpfrac) */
+.float frame2;
+/** tertiary framegroup animation (strength = lerpfrac3) */
+.float frame3;
+/** quaternary framegroup animation (strength = lerpfrac4) */
+.float frame4;
+
+/** strength of framegroup blend */
+.float lerpfrac;
+/** strength of framegroup blend */
+.float lerpfrac3;
+/** strength of framegroup blend */
+.float lerpfrac4;
+
+/** start time of framegroup animation */
+.float frame1time;
+/** start time of framegroup animation */
+.float frame2time;
+/** start time of framegroup animation */
+.float frame3time;
+/** start time of framegroup animation */
+.float frame4time;
+
+// end engine fields
+
+// player animation state
+
+.int animstate_startframe;
+.int animstate_numframes;
+.float animstate_framerate;
+.float animstate_starttime;
+.float animstate_endtime;
+/** whether to repeat */
+.bool animstate_looping;
+/** true for one cycle, then changed to false */
+.bool animstate_override;
+
+void anim_set(entity e, vector anim, bool looping, bool override, bool restart);
+#define setanim(...) anim_set(__VA_ARGS__)
+void anim_update(entity e);
+#define updateanim(...) anim_update(__VA_ARGS__)
 
 #endif
index 95cc599..5e3f543 100644 (file)
@@ -48,15 +48,6 @@ void SUB_VanishOrRemove (entity ent);
 .vector destvec;
 .vector destvec2;
 
-// player animation state
-.float animstate_startframe;
-.float animstate_numframes;
-.float animstate_framerate;
-.float animstate_starttime;
-.float animstate_endtime;
-.float animstate_override;
-.float animstate_looping;
-
 .float delay;
 .float wait;
 .float lip;
index 7379878..9959b64 100644 (file)
@@ -186,13 +186,16 @@ STATIC_INIT(register_weapons_done)
 .vector anim_reload;
 
 // static frame globals
-.int wframe;
 
-const float WFRAME_DONTCHANGE = -1;
-const float WFRAME_FIRE1 = 0;
-const float WFRAME_FIRE2 = 1;
-const float WFRAME_IDLE = 2;
-const float WFRAME_RELOAD = 3;
+ENUMCLASS(WFRAME)
+CASE(WFRAME, DONTCHANGE)
+CASE(WFRAME, FIRE1)
+CASE(WFRAME, FIRE2)
+CASE(WFRAME, IDLE)
+CASE(WFRAME, RELOAD)
+ENUMCLASS_END(WFRAME)
+
+.WFRAME wframe;
 
 vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn);
 void CL_WeaponEntity_SetModel(entity this, string name);
index 5aed6a7..a487653 100644 (file)
@@ -87,7 +87,7 @@ void W_Rifle_Attack2(void)
 }
 
 .void(void) rifle_bullethail_attackfunc;
-.float rifle_bullethail_frame;
+.WFRAME rifle_bullethail_frame;
 .float rifle_bullethail_animtime;
 .float rifle_bullethail_refire;
 void W_Rifle_BulletHail_Continue(Weapon thiswep, entity actor, .entity weaponentity, int fire)
@@ -116,7 +116,7 @@ void W_Rifle_BulletHail_Continue(Weapon thiswep, entity actor, .entity weaponent
        }
 }
 
-void W_Rifle_BulletHail(.entity weaponentity, float mode, void(void) AttackFunc, float fr, float animtime, float refire)
+void W_Rifle_BulletHail(.entity weaponentity, float mode, void(void) AttackFunc, WFRAME fr, float animtime, float refire)
 {SELFPARAM();
        // if we get here, we have at least one bullet to fire
        AttackFunc();
index 5a6b739..8a31df6 100644 (file)
@@ -35,6 +35,7 @@
 #include "cvar.qh"
 #include "defer.qh"
 #include "draw.qh"
+#include "enumclass.qh"
 #include "file.qh"
 #include "functional.qh"
 #include "i18n.qh"
diff --git a/qcsrc/lib/enumclass.qh b/qcsrc/lib/enumclass.qh
new file mode 100644 (file)
index 0000000..2959565
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef ENUMCLASS_H
+#define ENUMCLASS_H
+
+#include "oo.qh"
+
+// purpose: prevent transposed parameter passing
+
+#if NDEBUG
+
+// zero overhead mode, use this for releases
+
+#define ENUMCLASS(id) typedef int id; enum {
+#define CASE(class, id) class##_##id,
+#define ENUMCLASS_END(id) };
+
+#else
+
+// edict overhead mode, use this for type checking
+
+#define ENUMCLASS(id) CLASS(id, Object)
+#define CASE(class, id) class class##_##id; STATIC_INIT(class##_##id) { class##_##id = NEW(class); }
+#define ENUMCLASS_END(id) ENDCLASS(id)
+
+#endif
+
+#endif
index b8b3618..cb99c02 100644 (file)
@@ -10,6 +10,7 @@
 #include "teamplay.qh"
 #include "weapons/throwing.qh"
 #include "command/common.qh"
+#include "../common/anim.qh"
 #include "../common/animdecide.qh"
 #include "../common/csqcmodel_settings.qh"
 #include "../common/deathtypes/all.qh"
index f85a94b..4e8188d 100644 (file)
@@ -93,7 +93,6 @@ float server_is_dedicated;
 .float fade_rate;
 
 void() player_setupanimsformodel;
-void setanim(entity e, vector anim, float looping, float override, float restart);
 
 .string mdl;
 
index 149324f..3b9447c 100644 (file)
@@ -10,10 +10,6 @@ void() SUB_Remove;
 
 spawnfunc(info_null);
 
-void setanim(entity e, vector anim, float looping, float override, float restart);
-
-void updateanim(entity e);
-
 /*
 ==================
 SUB_Remove
index d354924..9c09025 100644 (file)
@@ -39,9 +39,6 @@ float W_WeaponSpeedFactor()
 }
 
 
-void weapon_thinkf(entity actor, .entity weaponentity, float fr, float t, void(Weapon thiswep, entity actor,
-    .entity weaponentity, int fire) func);
-
 bool CL_Weaponentity_CustomizeEntityForClient()
 {
        SELFPARAM();
@@ -309,13 +306,14 @@ bool weapon_prepareattack(Weapon thiswep, entity actor, .entity weaponentity, bo
 
 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,
+void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor,
        .entity weaponentity, int fire) func)
 {
+       entity this = actor.(weaponentity);
        bool restartanim;
        if (fr == WFRAME_DONTCHANGE)
        {
-               fr = actor.(weaponentity).wframe;
+               fr = this.wframe;
                restartanim = false;
        }
        else if (fr == WFRAME_IDLE)
@@ -331,18 +329,18 @@ void weapon_thinkf(entity actor, .entity weaponentity, float fr, float t, void(W
        vector or = v_right;
        vector ou = v_up;
 
-       if (actor.(weaponentity))
+       if (this)
        {
-               actor.(weaponentity).wframe = fr;
+               this.wframe = fr;
                vector a = '0 0 0';
-               if (fr == WFRAME_IDLE) a = actor.(weaponentity).anim_idle;
-               else if (fr == WFRAME_FIRE1) a = actor.(weaponentity).anim_fire1;
-               else if (fr == WFRAME_FIRE2) a = actor.(weaponentity).anim_fire2;
+               if (fr == WFRAME_IDLE) a = this.anim_idle;
+               else if (fr == WFRAME_FIRE1) a = this.anim_fire1;
+               else if (fr == WFRAME_FIRE2) a = this.anim_fire2;
                else  // if (fr == WFRAME_RELOAD)
-                       a = actor.(weaponentity).anim_reload;
+                       a = this.anim_reload;
                a.z *= g_weaponratefactor;
                entity e; FOR_EACH_CLIENT(e) if (e == actor || (IS_SPEC(e) && e.enemy == actor)) {
-                       wframe_send(e, actor.(weaponentity), a, restartanim);
+                       wframe_send(e, this, a, restartanim);
                }
        }
 
@@ -350,7 +348,7 @@ void weapon_thinkf(entity actor, .entity weaponentity, float fr, float t, void(W
        v_right = or;
        v_up = ou;
 
-       if (actor.weapon_think == w_ready && func != w_ready && actor.(weaponentity).state == WS_RAISE) backtrace(
+       if (actor.weapon_think == w_ready && func != w_ready && this.state == WS_RAISE) backtrace(
                        "Tried to override initial weapon think function - should this really happen?");
 
        t *= W_WeaponRateFactor();
index dbede43..0000ac2 100644 (file)
@@ -32,6 +32,6 @@ bool weapon_prepareattack_check(Weapon thiswep, entity actor, .entity weaponenti
 
 void weapon_prepareattack_do(entity actor, .entity weaponentity, float secondary, float attacktime);
 
-void weapon_thinkf(entity actor, .entity weaponentity, float fr, float t, void(Weapon thiswep, entity actor, .entity weaponentity, int fire) func);
+void weapon_thinkf(entity actor, .entity weaponentity, WFRAME fr, float t, void(Weapon thiswep, entity actor, .entity weaponentity, int fire) func);
 
 #endif