]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Possibly unstable, but worth it (move monster animation handling to setanim, rather...
authorMario <zacjardine@y7mail.com>
Sun, 26 Apr 2015 11:24:15 +0000 (21:24 +1000)
committerMario <zacjardine@y7mail.com>
Sun, 26 Apr 2015 11:24:15 +0000 (21:24 +1000)
22 files changed:
qcsrc/client/csqcmodel_hooks.qc
qcsrc/common/monsters/monster/afrit.qc
qcsrc/common/monsters/monster/creeper.qc
qcsrc/common/monsters/monster/demon.qc
qcsrc/common/monsters/monster/enforcer.qc
qcsrc/common/monsters/monster/goomba.qc
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/monster/ogre.qc
qcsrc/common/monsters/monster/rotfish.qc
qcsrc/common/monsters/monster/rottweiler.qc
qcsrc/common/monsters/monster/scrag.qc
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/monster/spawn.qc
qcsrc/common/monsters/monster/spider.qc
qcsrc/common/monsters/monster/vore.qc
qcsrc/common/monsters/monster/wyvern.qc
qcsrc/common/monsters/monster/zombie.qc
qcsrc/common/monsters/monsters.qh
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/monsters/sv_monsters.qh
qcsrc/server/cl_client.qc
qcsrc/server/mutators/base.qh

index c574f4f8fe154491404f97402586423403366d55..e63c7d68b725d72f9634255aee2457cf538d21d0 100644 (file)
@@ -628,6 +628,7 @@ void CSQCModel_Effects_Apply(void)
 
 void CSQCModel_Fade_Apply()
 {
+       if(!self.fade_end) { return; }
        vector org;
        float alph;
        org = getpropertyvec(VF_ORIGIN);
index 3a5458d3f422d182e9efe8f0771bca0d57ec3c45..48bce9e2efb77c70891ad5913f15d0a56398a512 100644 (file)
@@ -25,6 +25,7 @@ float autocvar_g_monster_afrit_speed_stop;
 float autocvar_g_monster_afrit_speed_run;
 float autocvar_g_monster_afrit_speed_walk;
 
+/*
 const float afrit_anim_sleep   = 0;
 const float afrit_anim_getup   = 1;
 const float afrit_anim_fly             = 2;
@@ -32,6 +33,7 @@ const float afrit_anim_pain           = 3;
 const float afrit_anim_attack  = 4;
 const float afrit_anim_die1            = 5;
 const float afrit_anim_die2            = 6;
+*/
 
 .float afrit_targetrange_backup;
 .float afrit_targetcheck_delay;
@@ -91,8 +93,8 @@ float M_Afrit_Attack(float attack_type)
                case MONSTER_ATTACK_RANGED:
                {
                        self.attack_finished_single = time + 2;
-                       self.anim_finished = time + 1.3;
-                       self.frame = afrit_anim_attack;
+                       setanim(self, self.anim_shoot, false, true, true);
+                       self.anim_finished = self.animstate_endtime;
 
                        Monster_Delay(2, 0.3, 0.7, M_Afrit_Attack_Fireball);
 
@@ -118,8 +120,8 @@ float M_Afrit(float req)
                                        self.target_range = self.afrit_targetrange_backup;
                                        if(Monster_FindTarget(self) != world)
                                        {
-                                               self.frame = afrit_anim_getup;
-                                               self.anim_finished = time + 2.3;
+                                               setanim(self, self.anim_draw, false, true, true);
+                                               self.anim_finished = self.animstate_endtime;
                                        }
                                        else
                                        {
@@ -131,11 +133,11 @@ float M_Afrit(float req)
                        self.fire_endtime = 0; // never burns
 
                        if(self.flags & FL_ONGROUND)
-                               self.m_anim_idle = afrit_anim_sleep;
+                               self.anim_idle = animfixfps(self, '0 1 0.5', '0 0 0');
                        else
-                               self.m_anim_idle = afrit_anim_fly;
+                               self.anim_idle = animfixfps(self, '2 1 0.5', '0 0 0');
 
-                       if(self.frame == afrit_anim_sleep)
+                       if(self.flags & FL_ONGROUND)
                                self.armorvalue = 0.95; // almost invincible
                        else
                                self.armorvalue = autocvar_g_monsters_armor_blockpercent;
@@ -147,17 +149,30 @@ float M_Afrit(float req)
                                frag_damage = 0; // afrit doesn't burn
                        else
                        {
-                               self.pain_finished = time + 0.6;
-                               self.frame = afrit_anim_pain;
+                               setanim(self, self.anim_pain1, true, true, true);
                        }
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = (random() >= 0.5) ? afrit_anim_die1 : afrit_anim_die2;
+                       setanim(self, ((random() >= 0.5) ? self.anim_die1 : self.anim_die2), false, true, true);
                        self.superweapons_finished = time + 20;
                        return true;
                }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '5 1 0.5', none); // 2 seconds
+                       self.anim_die2 = animfixfps(self, '6 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '2 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 0.5', none);
+                       self.anim_pain1 = animfixfps(self, '3 1 2', none); // 0.5 seconds
+                       self.anim_shoot = animfixfps(self, '4 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '2 1 1', none);
+                       self.anim_draw = animfixfps(self, '1 1 1', none);
+
+                       return true;
+               }
                case MR_SETUP:
                {
                        if(!self.health) self.health = (autocvar_g_monster_afrit_health);
@@ -166,10 +181,6 @@ float M_Afrit(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_afrit_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_afrit_damageforcescale); }
 
-                       self.m_anim_walk = afrit_anim_fly;
-                       self.m_anim_run = afrit_anim_fly;
-                       self.m_anim_idle = afrit_anim_fly;
-
                        if(!self.target_range) { self.afrit_targetrange_backup = autocvar_g_monsters_target_range; }
                        else { self.afrit_targetrange_backup = self.target_range; }
                        self.target_range = -1; // special handler
index 21f4f5ad1834538e3e1a86ce2c11f7f38db0ae1d..a2cb40ac5e278ef5217f47530c526462fc129cd1 100644 (file)
@@ -22,13 +22,15 @@ float autocvar_g_monster_creeper_speed_stop;
 float autocvar_g_monster_creeper_speed_walk;
 float autocvar_g_monster_creeper_speed_run;
 
-const float creeper_anim_idle = 0;
-const float creeper_anim_walk = 1;
-const float creeper_anim_die = 2;
+/*
+const int creeper_anim_idle = 0;
+const int creeper_anim_walk = 1;
+const int creeper_anim_die = 2;
+*/
 
-.float creeper_primed;
+.bool creeper_primed;
 
-float M_Creeper_Attack(float attack_type)
+bool M_Creeper_Attack(int attack_type)
 {
        switch(attack_type)
        {
@@ -44,7 +46,7 @@ float M_Creeper_Attack(float attack_type)
                                //Monster_Sound(monstersound_attack, 0, false, CH_SHOTS);
                                Damage (self, world, world, self.health + self.max_health + 200, DEATH_KILL, self.origin, '0 0 0'); // killing monster should be reliable enough
                                self.event_damage = func_null;
-                               self.frame = creeper_anim_idle;
+                               setanim(self, self.anim_idle, true, false, false);
                        }
                        else
                        {
@@ -52,7 +54,7 @@ float M_Creeper_Attack(float attack_type)
                                self.creeper_primed = true;
 
                                self.colormod = '1 0 0';
-                               self.frame = creeper_anim_idle;
+                               setanim(self, self.anim_idle, true, false, false);
                                self.velocity_x = 0;
                                self.velocity_y = 0;
                                self.state = MONSTER_ATTACK_MELEE;
@@ -90,7 +92,17 @@ float M_Creeper(float req)
                }
                case MR_DEATH:
                {
-                       self.frame = creeper_anim_die;
+                       setanim(self, self.anim_die1, false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '2 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '1 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_run = animfixfps(self, '1 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -103,11 +115,7 @@ float M_Creeper(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_creeper_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_creeper_damageforcescale); }
 
-                       self.m_anim_walk = creeper_anim_walk;
-                       self.m_anim_run = creeper_anim_walk;
-                       self.m_anim_idle = creeper_anim_idle;
                        self.monster_loot = spawnfunc_ammo_rockets;
-                       self.frame = creeper_anim_idle;
                        self.colormod = '1 1 1';
 
                        return true;
index 718246f8bf63a5360ff60d8c2069865279d29523..105bfa4fb1f7a8c106ef91f4d7a7c3e5017d4604 100644 (file)
@@ -24,6 +24,7 @@ float autocvar_g_monster_demon_speed_stop;
 float autocvar_g_monster_demon_speed_run;
 float autocvar_g_monster_demon_speed_walk;
 
+/*
 const float demon_anim_stand   = 0;
 const float demon_anim_walk            = 1;
 const float demon_anim_run             = 2;
@@ -31,6 +32,7 @@ const float demon_anim_leap           = 3;
 const float demon_anim_pain            = 4;
 const float demon_anim_death   = 5;
 const float demon_anim_attack  = 6;
+*/
 
 void M_Demon_Attack_Leap_Touch()
 {
@@ -61,13 +63,13 @@ float M_Demon_Attack(float attack_type)
        {
                case MONSTER_ATTACK_MELEE:
                {
-                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_demon_attack_melee_damage), demon_anim_attack, self.attack_range, (autocvar_g_monster_demon_attack_melee_delay), DEATH_MONSTER_DEMON_MELEE, true);
+                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_demon_attack_melee_damage), self.anim_melee, self.attack_range, (autocvar_g_monster_demon_attack_melee_delay), DEATH_MONSTER_DEMON_MELEE, true);
                }
                case MONSTER_ATTACK_RANGED:
                {
                        if(vlen(self.enemy.origin - self.origin) <= autocvar_g_monster_demon_attack_leap_mindist) { return false; }
                        makevectors(self.angles);
-                       return Monster_Attack_Leap(demon_anim_leap, M_Demon_Attack_Leap_Touch, v_forward * (autocvar_g_monster_demon_attack_leap_speed) + '0 0 200', (autocvar_g_monster_demon_attack_leap_delay));
+                       return Monster_Attack_Leap(self.anim_shoot, M_Demon_Attack_Leap_Touch, v_forward * (autocvar_g_monster_demon_attack_leap_speed) + '0 0 200', (autocvar_g_monster_demon_attack_leap_delay));
                }
        }
 
@@ -89,12 +91,25 @@ float M_Demon(float req)
                case MR_PAIN:
                {
                        self.pain_finished = time + 0.5;
-                       self.frame = demon_anim_pain;
+                       setanim(self, self.anim_pain1, true, true, false);
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = demon_anim_death;
+                       setanim(self, self.anim_die1, false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '5 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '1 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '4 1 2', none); // 0.5 seconds
+                       self.anim_melee = animfixfps(self, '6 1 5', none); // analyze models and set framerate
+                       self.anim_shoot = animfixfps(self, '3 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '2 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -105,12 +120,7 @@ float M_Demon(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_demon_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_demon_damageforcescale); }
 
-                       self.m_anim_walk = demon_anim_walk;
-                       self.m_anim_run = demon_anim_run;
-                       self.m_anim_idle = demon_anim_stand;
-
                        self.monster_loot = spawnfunc_item_health_large;
-                       self.frame = demon_anim_stand;
 
                        return true;
                }
index a48a0af15ff58b67eecc659667642a373dd386c0..3560f9366d884325faf1b3b0606fd5d37d769077 100644 (file)
@@ -26,6 +26,7 @@ float autocvar_g_monster_enforcer_speed_stop;
 float autocvar_g_monster_enforcer_speed_run;
 float autocvar_g_monster_enforcer_speed_walk;
 
+/*
 const float enforcer_anim_stand                        = 0;
 const float enforcer_anim_walk                 = 1;
 const float enforcer_anim_run                  = 2;
@@ -36,6 +37,7 @@ const float enforcer_anim_pain1                       = 6;
 const float enforcer_anim_pain2                        = 7;
 const float enforcer_anim_pain3                        = 8;
 const float enforcer_anim_pain4                        = 9;
+*/
 
 void M_Enforcer_Attack_Plasma_Explode()
 {
@@ -107,7 +109,7 @@ float M_Enforcer_Attack(float attack_type)
                case MONSTER_ATTACK_MELEE:
                case MONSTER_ATTACK_RANGED:
                {
-                       self.frame = enforcer_anim_attack;
+                       setanim(self, self.anim_shoot, true, true, true);
                        self.attack_finished_single = time + 0.7;
                        self.anim_finished = time + 0.7 * autocvar_g_monster_enforcer_attack_plasma_shots;
                        self.state = MONSTER_ATTACK_RANGED;
@@ -131,19 +133,37 @@ float M_Enforcer(float req)
                }
                case MR_PAIN:
                {
+                       vector anim;
                        switch(floor(random() * 5))
                        {
                                default:
-                               case 1: self.frame = enforcer_anim_pain1; self.pain_finished = time + 0.3; break;
-                               case 2: self.frame = enforcer_anim_pain2; self.pain_finished = time + 0.4; break;
-                               case 3: self.frame = enforcer_anim_pain3; self.pain_finished = time + 0.7; break;
-                               case 4: self.frame = enforcer_anim_pain4; self.pain_finished = time + 1; break;
+                               case 1: anim = self.anim_pain1; self.pain_finished = time + 0.3; break;
+                               case 2: anim = self.anim_pain2; self.pain_finished = time + 0.4; break;
+                               case 3: anim = self.anim_pain3; self.pain_finished = time + 0.7; break;
+                               case 4: anim = self.anim_pain4; self.pain_finished = time + 1; break;
                        }
+                       setanim(self, anim, true, true, false);
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = ((random() > 0.5) ? enforcer_anim_death1 : enforcer_anim_death2);
+                       setanim(self, ((random() > 0.5) ? self.anim_die1 : self.anim_die2), false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '4 1 0.5', none); // 2 seconds
+                       self.anim_die2 = animfixfps(self, '5 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '1 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '6 1 2', none); // 0.5 seconds
+                       self.anim_pain2 = animfixfps(self, '7 1 2', none); // 0.5 seconds
+                       self.anim_pain3 = animfixfps(self, '8 1 2', none); // 0.5 seconds
+                       self.anim_pain4 = animfixfps(self, '9 1 2', none); // 0.5 seconds
+                       self.anim_shoot = animfixfps(self, '3 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '2 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -154,10 +174,6 @@ float M_Enforcer(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_enforcer_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_enforcer_damageforcescale); }
 
-                       self.m_anim_walk = enforcer_anim_walk;
-                       self.m_anim_run = enforcer_anim_run;
-                       self.m_anim_idle = enforcer_anim_stand;
-
                        self.monster_loot = spawnfunc_item_cells;
                        self.weapon = WEP_CRYLINK;
 
index 56f63512114a3c397f52e62aab8f2a33a7d373a9..8844534674c9e3f5c37c87345fd49634b130471d 100644 (file)
@@ -61,7 +61,7 @@ bool M_Goomba(int req)
        {
                case MR_THINK:
                {
-                       Monster_Move_2D(self.speed, autocvar_g_monster_goomba_allow_jumpoff, 0, 0);
+                       Monster_Move_2D(self.speed, autocvar_g_monster_goomba_allow_jumpoff);
                        return false; // funny handler here, false means don't do regular moving
                }
                case MR_PAIN:
index 9535701ff78dd9500c0946aca278a58d42e819d1..b1ec4e6af7acd86afcdf00fe4a5b59474b5015ba 100644 (file)
@@ -42,12 +42,14 @@ float autocvar_g_monster_mage_speed_stop;
 float autocvar_g_monster_mage_speed_run;
 float autocvar_g_monster_mage_speed_walk;
 
+/*
 const float mage_anim_idle             = 0;
 const float mage_anim_walk             = 1;
 const float mage_anim_attack   = 2;
 const float mage_anim_pain             = 3;
 const float mage_anim_death            = 4;
 const float mage_anim_run              = 5;
+*/
 
 void() M_Mage_Defend_Heal;
 void() M_Mage_Defend_Shield;
@@ -243,7 +245,7 @@ void M_Mage_Defend_Heal()
 
        if(washealed)
        {
-               self.frame = mage_anim_attack;
+               setanim(self, self.anim_shoot, true, true, true);
                self.attack_finished_single = time + (autocvar_g_monster_mage_heal_delay);
                self.anim_finished = time + 1.5;
        }
@@ -255,7 +257,7 @@ void M_Mage_Attack_Push()
        RadiusDamage (self, self, (autocvar_g_monster_mage_attack_push_damage), (autocvar_g_monster_mage_attack_push_damage), (autocvar_g_monster_mage_attack_push_radius), world, world, (autocvar_g_monster_mage_attack_push_force), DEATH_MONSTER_MAGE, self.enemy);
        pointparticles(particleeffectnum("TE_EXPLOSION"), self.origin, '0 0 0', 1);
 
-       self.frame = mage_anim_attack;
+       setanim(self, self.anim_shoot, true, true, true);
        self.attack_finished_single = time + (autocvar_g_monster_mage_attack_push_delay);
 }
 
@@ -288,7 +290,7 @@ void M_Mage_Defend_Shield()
        self.mage_shield_delay = time + (autocvar_g_monster_mage_shield_delay);
        self.armorvalue = (autocvar_g_monster_mage_shield_blockpercent);
        self.mage_shield_time = time + (autocvar_g_monster_mage_shield_time);
-       self.frame = mage_anim_attack;
+       setanim(self, self.anim_shoot, true, true, true);
        self.attack_finished_single = time + 1;
        self.anim_finished = time + 1;
 }
@@ -318,7 +320,7 @@ float M_Mage_Attack(float attack_type)
                                }
                                else
                                {
-                                       self.frame = mage_anim_attack;
+                                       setanim(self, self.anim_shoot, true, true, true);
                                        self.attack_finished_single = time + (autocvar_g_monster_mage_attack_spike_delay);
                                        self.anim_finished = time + 1;
                                        Monster_Delay(1, 0, 0.2, M_Mage_Attack_Spike);
@@ -384,7 +386,19 @@ float M_Mage(float req)
                }
                case MR_DEATH:
                {
-                       self.frame = mage_anim_death;
+                       setanim(self, self.anim_die1, false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '4 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '1 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '3 1 2', none); // 0.5 seconds
+                       self.anim_shoot = animfixfps(self, '2 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '5 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -395,12 +409,7 @@ float M_Mage(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_mage_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_mage_damageforcescale); }
 
-                       self.m_anim_walk = mage_anim_walk;
-                       self.m_anim_run = mage_anim_run;
-                       self.m_anim_idle = mage_anim_idle;
-
                        self.monster_loot = spawnfunc_item_health_large;
-                       self.frame = mage_anim_walk;
 
                        return true;
                }
index ceb4d73fd9e0a862bb5ff9cfa7133b45363198aa..cbcd985249567141bb0928be8332617283dd508c 100644 (file)
@@ -44,6 +44,7 @@ float autocvar_g_monster_ogre_speed_stop;
 float autocvar_g_monster_ogre_speed_run;
 float autocvar_g_monster_ogre_speed_walk;
 
+/*
 const float ogre_anim_idle                     = 0;
 const float ogre_anim_walk                     = 1;
 const float ogre_anim_run                      = 2;
@@ -58,6 +59,7 @@ const float ogre_anim_pain5           = 10;
 const float ogre_anim_death1           = 11;
 const float ogre_anim_death2           = 12;
 const float ogre_anim_pull                     = 13;
+*/
 
 void M_Ogre_Attack_MachineGun()
 {
@@ -257,7 +259,7 @@ void M_Ogre_Attack_Chainsaw()
        if(time >= self.cnt + meleetime)
        {
                // melee is finished
-               self.realowner.frame = ogre_anim_idle;
+               setanim(self.realowner, self.realowner.anim_idle, true, false, false);
                remove(self);
                return;
        }
@@ -280,7 +282,7 @@ float M_Ogre_Attack(float attack_type)
                        if(vdir_z > 0.7)
                        {
                                self.attack_finished_single = time + 1.2;
-                               self.frame = ogre_anim_shoot;
+                               setanim(self, self.anim_pain1, true, true, false);
                                self.state = MONSTER_ATTACK_RANGED;
                                Monster_Delay(2, 0.1, 0.4, M_Ogre_Attack_MachineGun);
                                return 2;
@@ -293,7 +295,7 @@ float M_Ogre_Attack(float attack_type)
                        self.attack_finished_single = time + autocvar_g_monster_ogre_attack_melee_time + autocvar_g_monster_ogre_attack_melee_delay + 0.7;
                        self.anim_finished = self.attack_finished_single;
                        self.state = MONSTER_ATTACK_MELEE;
-                       self.frame = ogre_anim_swing;
+                       setanim(self, self.anim_melee1, true, true, false);
 
                        return true;
                }
@@ -303,7 +305,7 @@ float M_Ogre_Attack(float attack_type)
                        self.state = MONSTER_ATTACK_RANGED;
                        self.attack_finished_single = time + 1;
                        self.anim_finished = time + 0.5;
-                       self.frame = ogre_anim_shoot;
+                       setanim(self, self.anim_pain1, true, true, false);
                        return true;
                }
        }
@@ -323,20 +325,42 @@ float M_Ogre(float req)
                }
                case MR_PAIN:
                {
+                       vector anim;
                        switch(floor(random() * 6))
                        {
                                default:
-                               case 1: self.frame = ogre_anim_pain1; self.anim_finished = time + 0.4; break;
-                               case 2: self.frame = ogre_anim_pain2; self.anim_finished = time + 0.2; break;
-                               case 3: self.frame = ogre_anim_pain3; self.anim_finished = time + 0.5; break;
-                               case 4: self.frame = ogre_anim_pain4; self.anim_finished = time + 1.5; break;
-                               case 5: self.frame = ogre_anim_pain5; self.anim_finished = time + 1.4; break;
+                               case 1: anim = self.anim_pain1; self.anim_finished = time + 0.4; break;
+                               case 2: anim = self.anim_pain2; self.anim_finished = time + 0.2; break;
+                               case 3: anim = self.anim_pain3; self.anim_finished = time + 0.5; break;
+                               case 4: anim = self.anim_pain4; self.anim_finished = time + 1.5; break;
+                               case 5: anim = self.anim_pain5; self.anim_finished = time + 1.4; break;
                        }
+                       setanim(self, anim, true, true, true);
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = ((random() >= 0.5) ? ogre_anim_death1 : ogre_anim_death2);
+                       setanim(self, ((random() > 0.5) ? self.anim_die1 : self.anim_die2), false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '11 1 0.5', none); // 2 seconds
+                       self.anim_die2 = animfixfps(self, '12 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '1 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '6 1 2', none); // 0.5 seconds
+                       self.anim_pain2 = animfixfps(self, '7 1 2', none); // 0.5 seconds
+                       self.anim_pain3 = animfixfps(self, '8 1 2', none); // 0.5 seconds
+                       self.anim_pain4 = animfixfps(self, '9 1 2', none); // 0.5 seconds
+                       self.anim_pain5 = animfixfps(self, '10 1 2', none); // 0.5 seconds
+                       self.anim_melee1 = animfixfps(self, '3 1 5', none); // analyze models and set framerate
+                       self.anim_melee2 = animfixfps(self, '4 1 5', none); // analyze models and set framerate
+                       self.anim_shoot = animfixfps(self, '5 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '2 1 1', none);
+                       self.anim_draw = animfixfps(self, '13 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -347,14 +371,10 @@ float M_Ogre(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_ogre_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_ogre_damageforcescale); }
 
-                       self.m_anim_walk = ogre_anim_walk;
-                       self.m_anim_run = ogre_anim_run;
-                       self.m_anim_idle = ogre_anim_idle;
-
                        self.monster_loot = spawnfunc_item_rockets;
                        self.weapon = WEP_MACHINEGUN;
-                       self.frame = ogre_anim_pull;
-                       self.spawn_time = time + 1;
+                       setanim(self, self.anim_draw, false, true, true);
+                       self.spawn_time = self.animstate_endtime;
                        self.spawnshieldtime = self.spawn_time;
 
                        return true;
index 91351e589917cfda4843edb7679e80ab54574ddd..fc8d3022c85bdf735c9176935f4774e502e40fcd 100644 (file)
@@ -20,10 +20,12 @@ float autocvar_g_monster_rotfish_speed_stop;
 float autocvar_g_monster_rotfish_speed_run;
 float autocvar_g_monster_rotfish_speed_walk;
 
+/*
 const float rotfish_anim_attack = 0;
 const float rotfish_anim_death  = 1;
 const float rotfish_anim_swim   = 2;
 const float rotfish_anim_pain   = 3;
+*/
 
 
 float M_Rotfish_Attack(float attack_type)
@@ -32,7 +34,7 @@ float M_Rotfish_Attack(float attack_type)
        {
                case MONSTER_ATTACK_MELEE:
                {
-                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_rotfish_attack_melee_damage), rotfish_anim_attack, self.attack_range, (autocvar_g_monster_rotfish_attack_melee_delay), DEATH_MONSTER_ROTFISH_MELEE, true);
+                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_rotfish_attack_melee_damage), self.anim_melee, self.attack_range, (autocvar_g_monster_rotfish_attack_melee_delay), DEATH_MONSTER_ROTFISH_MELEE, true);
                }
                case MONSTER_ATTACK_RANGED:
                {
@@ -58,12 +60,24 @@ float M_Rotfish(float req)
                case MR_PAIN:
                {
                        self.pain_finished = 0.8;
-                       self.frame = rotfish_anim_pain;
+                       setanim(self, self.anim_pain1, true, true, false);
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = rotfish_anim_death;
+                       setanim(self, self.anim_die1, false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '1 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '2 1 1', none);
+                       self.anim_idle = animfixfps(self, '2 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '3 1 2', none); // 0.5 seconds
+                       self.anim_melee = animfixfps(self, '0 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '2 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -75,12 +89,7 @@ float M_Rotfish(float req)
                        if(!self.attack_range) { self.attack_range = autocvar_g_monster_rotfish_attack_range; }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_rotfish_damageforcescale); }
 
-                       self.m_anim_walk = rotfish_anim_swim;
-                       self.m_anim_run = rotfish_anim_swim;
-                       self.m_anim_idle = rotfish_anim_swim;
-
                        self.monster_loot = spawnfunc_item_armor_small;
-                       self.frame = rotfish_anim_swim;
 
                        return true;
                }
index c38cb06100706ceb130647aee7509d1632da74e5..4149357de0a34b73a2bd89b559c33244c0c4c3b9 100644 (file)
@@ -19,6 +19,7 @@ float autocvar_g_monster_rottweiler_speed_stop;
 float autocvar_g_monster_rottweiler_speed_run;
 float autocvar_g_monster_rottweiler_speed_walk;
 
+/*
 const float rottweiler_anim_attack1            = 0;
 const float rottweiler_anim_death1             = 1;
 const float rottweiler_anim_death2             = 2;
@@ -28,6 +29,7 @@ const float rottweiler_anim_run                       = 5;
 const float rottweiler_anim_leap               = 6;
 const float rottweiler_anim_idle               = 7;
 const float rottweiler_anim_walk               = 8;
+*/
 
 float M_Rottweiler_Attack(float attack_type)
 {
@@ -35,7 +37,7 @@ float M_Rottweiler_Attack(float attack_type)
        {
                case MONSTER_ATTACK_MELEE:
                {
-                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_rottweiler_attack_melee_damage), ((random() >= 0.5) ? rottweiler_anim_attack1 : rottweiler_anim_attack2), self.attack_range, (autocvar_g_monster_rottweiler_attack_melee_delay), DEATH_MONSTER_ROTTWEILER, true);
+                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_rottweiler_attack_melee_damage), ((random() >= 0.5) ? self.anim_melee1 : self.anim_melee2), self.attack_range, (autocvar_g_monster_rottweiler_attack_melee_delay), DEATH_MONSTER_ROTTWEILER, true);
                }
                case MONSTER_ATTACK_RANGED:
                {
@@ -62,13 +64,28 @@ float M_Rottweiler(float req)
                        if(random() <= 0.3)
                        {
                                self.pain_finished = time + 1.5;
-                               self.frame = rottweiler_anim_pain;
+                               setanim(self, self.anim_pain1, true, true, false);
                        }
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = (random() >= 0.5) ? rottweiler_anim_death1 : rottweiler_anim_death2;
+                       setanim(self, ((random() > 0.5) ? self.anim_die1 : self.anim_die2), false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '5 1 0.5', none); // 2 seconds
+                       self.anim_die2 = animfixfps(self, '1 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '2 1 1', none);
+                       self.anim_idle = animfixfps(self, '7 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '4 1 2', none); // 0.5 seconds
+                       self.anim_melee1 = animfixfps(self, '0 1 5', none); // analyze models and set framerate
+                       self.anim_melee2 = animfixfps(self, '3 1 5', none); // analyze models and set framerate
+                       self.anim_shoot = animfixfps(self, '6 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '5 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -79,12 +96,7 @@ float M_Rottweiler(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_rottweiler_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_rottweiler_damageforcescale); }
 
-                       self.m_anim_walk = rottweiler_anim_walk;
-                       self.m_anim_run = rottweiler_anim_run;
-                       self.m_anim_idle = rottweiler_anim_idle;
-
                        self.monster_loot = spawnfunc_item_health_small;
-                       self.frame = rottweiler_anim_idle;
 
                        return true;
                }
index 7a722097128d845372054b431232e9dd3a2a5896..cc6c6dde2764fc98e1b5891280930728f2d4c023 100644 (file)
@@ -22,11 +22,13 @@ float autocvar_g_monster_scrag_speed_stop;
 float autocvar_g_monster_scrag_speed_run;
 float autocvar_g_monster_scrag_speed_walk;
 
+/*
 const float scrag_anim_hover   = 0;
 const float scrag_anim_fly             = 1;
 const float scrag_anim_magic   = 2;
 const float scrag_anim_pain            = 3;
 const float scrag_anim_death   = 4;
+*/
 
 void M_Scrag_Attack_Spike_Explode()
 {
@@ -83,7 +85,7 @@ float M_Scrag_Attack(float attack_type)
                        self.attack_finished_single = time + ((random() >= 0.8) ? 1.3 : 0.15);
                        self.anim_finished = self.attack_finished_single;
 
-                       self.frame = scrag_anim_magic;
+                       setanim(self, self.anim_shoot, true, true, false);
 
                        M_Scrag_Attack_Spike();
 
@@ -120,17 +122,29 @@ float M_Scrag(float req)
                case MR_PAIN:
                {
                        self.pain_finished = time + 0.3;
-                       self.frame = scrag_anim_pain;
+                       setanim(self, self.anim_pain1, true, true, false);
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = scrag_anim_death;
+                       setanim(self, self.anim_die1, false, true, true);
                        self.velocity_x = -200 + 400 * random();
                        self.velocity_y = -200 + 400 * random();
                        self.velocity_z = 100 + 100 * random();
                        return true;
                }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '5 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '0 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '3 1 2', none); // 0.5 seconds
+                       self.anim_shoot = animfixfps(self, '2 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '1 1 1', none);
+
+                       return true;
+               }
                case MR_SETUP:
                {
                        if(!self.health) self.health = (autocvar_g_monster_scrag_health);
@@ -139,12 +153,7 @@ float M_Scrag(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_scrag_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_scrag_damageforcescale); }
 
-                       self.m_anim_walk = scrag_anim_hover;
-                       self.m_anim_run = scrag_anim_fly;
-                       self.m_anim_idle = scrag_anim_hover;
-
                        self.monster_loot = spawnfunc_item_shells;
-                       self.frame = scrag_anim_hover;
 
                        return true;
                }
index c614a7801a8ccab543aa373ffe17ba10adbcd2fc..8557c705d75c3547848ce5d4d1f374d067f95fcf 100644 (file)
@@ -28,6 +28,7 @@ float autocvar_g_monster_shambler_speed_stop;
 float autocvar_g_monster_shambler_speed_run;
 float autocvar_g_monster_shambler_speed_walk;
 
+/*
 const float shambler_anim_stand                = 0;
 const float shambler_anim_walk         = 1;
 const float shambler_anim_run          = 2;
@@ -37,6 +38,7 @@ const float shambler_anim_swingl      = 5;
 const float shambler_anim_magic                = 6;
 const float shambler_anim_pain         = 7;
 const float shambler_anim_death                = 8;
+*/
 
 .float shambler_lastattack; // delay attacks separately
 
@@ -57,7 +59,7 @@ void M_Shambler_Attack_Smash()
 void M_Shambler_Attack_Swing()
 {
        float r = (random() < 0.5);
-       Monster_Attack_Melee(self.enemy, (autocvar_g_monster_shambler_attack_claw_damage), ((r) ? shambler_anim_swingr : shambler_anim_swingl), self.attack_range, 0.8, DEATH_MONSTER_SHAMBLER_CLAW, true);
+       Monster_Attack_Melee(self.enemy, (autocvar_g_monster_shambler_attack_claw_damage), ((r) ? self.anim_melee2 : self.anim_melee3), self.attack_range, 0.8, DEATH_MONSTER_SHAMBLER_CLAW, true);
        if(r)
        {
                Monster_Delay(1, 0, 0.5, M_Shambler_Attack_Swing);
@@ -180,7 +182,7 @@ float M_Shambler_Attack(float attack_type)
                        if(self.flags & FL_ONGROUND)
                        if(randomness <= 0.5 && enemy_len <= autocvar_g_monster_shambler_attack_smash_range)
                        {
-                               self.frame = shambler_anim_smash;
+                               setanim(self, self.anim_melee2, true, true, false);
                                Monster_Delay(1, 0, 0.7, M_Shambler_Attack_Smash);
                                self.attack_finished_single = time + 1.1;
                                self.anim_finished = time + 1.1;
@@ -190,7 +192,7 @@ float M_Shambler_Attack(float attack_type)
                        }
                        else if(randomness <= 0.1 && enemy_len >= autocvar_g_monster_shambler_attack_smash_range * 1.5) // small chance, don't want this spammed
                        {
-                               self.frame = shambler_anim_magic;
+                               setanim(self, self.anim_shoot, true, true, false);
                                self.state = MONSTER_ATTACK_MELEE; // maybe we should rename this to something more general
                                self.attack_finished_single = time + 1.1;
                                self.anim_finished = 1.1;
@@ -219,12 +221,27 @@ float M_Shambler(float req)
                case MR_PAIN:
                {
                        self.pain_finished = time + 0.5;
-                       self.frame = shambler_anim_pain;
+                       setanim(self, self.anim_pain1, true, true, false);
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = shambler_anim_death;
+                       setanim(self, self.anim_die1, false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '8 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '1 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '7 1 2', none); // 0.5 seconds
+                       self.anim_melee1 = animfixfps(self, '3 1 5', none); // analyze models and set framerate
+                       self.anim_melee2 = animfixfps(self, '4 1 5', none); // analyze models and set framerate
+                       self.anim_melee3 = animfixfps(self, '5 1 5', none); // analyze models and set framerate
+                       self.anim_shoot = animfixfps(self, '6 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '2 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -236,16 +253,11 @@ float M_Shambler(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_shambler_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_shambler_damageforcescale); }
 
-                       self.m_anim_walk = shambler_anim_walk;
-                       self.m_anim_run = shambler_anim_run;
-                       self.m_anim_idle = shambler_anim_stand;
-
                        self.monster_loot = spawnfunc_item_health_mega;
-                       self.frame = shambler_anim_stand;
                        self.weapon = WEP_ELECTRO; // matches attacks better than WEP_VORTEX
 
-                       self.frame = shambler_anim_magic;
-                       self.spawn_time = time + 1.1;
+                       setanim(self, self.anim_shoot, false, true, true);
+                       self.spawn_time = self.animstate_endtime;
                        self.spawnshieldtime = self.spawn_time;
 
                        return true;
index 6e6339eb859dbe0dffd0d4de81e362c408d34fd0..2ef2c2e0897fe4d6164c54ca5268a21c03e1a554 100644 (file)
@@ -25,11 +25,13 @@ float autocvar_g_monster_spawn_speed_stop;
 float autocvar_g_monster_spawn_speed_run;
 float autocvar_g_monster_spawn_speed_walk;
 
+/*
 const float spawn_anim_walk    = 0;
 const float spawn_anim_run     = 1;
 const float spawn_anim_jump    = 2;
 const float spawn_anim_fly     = 3;
 const float spawn_anim_explode         = 4;
+*/
 
 void M_Spawn_Attack_Explode()
 {
@@ -68,7 +70,7 @@ float M_Spawn_Attack(float attack_type)
                case MONSTER_ATTACK_RANGED:
                {
                        makevectors(self.angles);
-                       float leap_success = Monster_Attack_Leap(spawn_anim_jump, M_Spawn_Attack_Leap_Touch, v_forward * (autocvar_g_monster_spawn_attack_leap_speed) + '0 0 200', (autocvar_g_monster_spawn_attack_leap_delay));
+                       float leap_success = Monster_Attack_Leap(self.anim_melee, M_Spawn_Attack_Leap_Touch, v_forward * (autocvar_g_monster_spawn_attack_leap_speed) + '0 0 200', (autocvar_g_monster_spawn_attack_leap_delay));
                        if(leap_success)
                        {
                                self.movetype = MOVETYPE_BOUNCE;
@@ -107,6 +109,17 @@ float M_Spawn(float req)
                        defer(0.05, M_Spawn_Attack_Explode); // simply defer to prevent recursion
                        return true;
                }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '4 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '0 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_melee = animfixfps(self, '2 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '1 1 1', none);
+
+                       return true;
+               }
                case MR_SETUP:
                {
                        if(!self.health) self.health = (autocvar_g_monster_spawn_health);
@@ -116,12 +129,7 @@ float M_Spawn(float req)
                        if(!self.attack_range) { self.attack_range = autocvar_g_monsters_target_range * 0.8; } // bounce from almost any distance
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_spawn_damageforcescale); }
 
-                       self.m_anim_walk = spawn_anim_walk;
-                       self.m_anim_run = spawn_anim_run;
-                       self.m_anim_idle = spawn_anim_walk;
-
                        self.monster_loot = spawnfunc_item_rockets;
-                       self.frame = spawn_anim_walk;
 
                        return true;
                }
index 7e75fd541ce5234f73644c1ec402c59598e31800..3f8e5b62b3021fe4033534947cc3bd983d6f9cad 100644 (file)
@@ -25,10 +25,12 @@ float autocvar_g_monster_spider_speed_stop;
 float autocvar_g_monster_spider_speed_run;
 float autocvar_g_monster_spider_speed_walk;
 
+/*
 const float spider_anim_idle           = 0;
 const float spider_anim_walk           = 1;
 const float spider_anim_attack         = 2;
 const float spider_anim_attack2                = 3;
+*/
 
 .float spider_web_delay;
 
@@ -98,13 +100,13 @@ float M_Spider_Attack(float attack_type)
        {
                case MONSTER_ATTACK_MELEE:
                {
-                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_spider_attack_bite_damage), ((random() > 0.5) ? spider_anim_attack : spider_anim_attack2), self.attack_range, (autocvar_g_monster_spider_attack_bite_delay), DEATH_MONSTER_SPIDER, true);
+                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_spider_attack_bite_damage), ((random() > 0.5) ? self.anim_melee : self.anim_shoot), self.attack_range, (autocvar_g_monster_spider_attack_bite_delay), DEATH_MONSTER_SPIDER, true);
                }
                case MONSTER_ATTACK_RANGED:
                {
                        if(time >= self.spider_web_delay)
                        {
-                               self.frame = spider_anim_attack2;
+                               setanim(self, self.anim_shoot, true, true, true);
                                self.attack_finished_single = time + (autocvar_g_monster_spider_attack_web_delay);
                                self.anim_finished = time + 1;
                                M_Spider_Attack_Web();
@@ -135,10 +137,21 @@ float M_Spider(float req)
                }
                case MR_DEATH:
                {
-                       self.frame = spider_anim_attack;
+                       setanim(self, self.anim_melee, false, true, true);
                        self.angles_x = 180;
                        return true;
                }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_walk = animfixfps(self, '1 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_melee = animfixfps(self, '2 1 5', none); // analyze models and set framerate
+                       self.anim_shoot = animfixfps(self, '3 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '1 1 1', none);
+
+                       return true;
+               }
                case MR_SETUP:
                {
                        if(!self.health) self.health = (autocvar_g_monster_spider_health);
@@ -147,12 +160,7 @@ float M_Spider(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_spider_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_spider_damageforcescale); }
 
-                       self.m_anim_walk = spider_anim_walk;
-                       self.m_anim_run = spider_anim_walk;
-                       self.m_anim_idle = spider_anim_idle;
-
                        self.monster_loot = spawnfunc_item_health_medium;
-                       self.frame = spider_anim_idle;
 
                        return true;
                }
index ebd5c56c347262e47b634d8aacf261abf56e07dc..0c6b478edf32bc5fccc417bd70d80a868a7adf70 100644 (file)
@@ -32,10 +32,12 @@ float autocvar_g_monster_vore_speed_stop;
 float autocvar_g_monster_vore_speed_run;
 float autocvar_g_monster_vore_speed_walk;
 
+/*
 const float vore_anim_attack   = 0;
 const float vore_anim_pain             = 1;
 const float vore_anim_death            = 2;
 const float vore_anim_walk             = 3;
+*/
 
 .entity vore_spike;
 
@@ -157,13 +159,13 @@ float M_Vore_Attack(float attack_type)
        {
                case MONSTER_ATTACK_MELEE:
                {
-                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_vore_attack_melee_damage), vore_anim_attack, self.attack_range, (autocvar_g_monster_vore_attack_melee_delay), DEATH_MONSTER_VORE_MELEE, true);
+                       return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_vore_attack_melee_damage), self.anim_shoot, self.attack_range, (autocvar_g_monster_vore_attack_melee_delay), DEATH_MONSTER_VORE_MELEE, true);
                }
                case MONSTER_ATTACK_RANGED:
                {
                        if(!self.vore_spike)
                        {
-                               self.frame = vore_anim_attack;
+                               setanim(self, self.anim_shoot, true, true, true);
                                self.attack_finished_single = time + (autocvar_g_monster_vore_attack_spike_delay);
                                self.anim_finished = time + 1;
                                Monster_Delay(1, 0, 0.2, M_Vore_Attack_Spike);
@@ -193,12 +195,24 @@ float M_Vore(float req)
                case MR_PAIN:
                {
                        self.pain_finished = time + 0.4;
-                       self.frame = vore_anim_pain;
+                       setanim(self, self.anim_pain1, true, true, false);
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = vore_anim_death;
+                       setanim(self, self.anim_die1, false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '2 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '3 1 1', none);
+                       self.anim_idle = animfixfps(self, '3 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '1 1 2', none); // 0.5 seconds
+                       self.anim_shoot = animfixfps(self, '3 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '0 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -209,13 +223,8 @@ float M_Vore(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_vore_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_vore_damageforcescale); }
 
-                       self.m_anim_walk = vore_anim_walk;
-                       self.m_anim_run = vore_anim_walk;
-                       self.m_anim_idle = vore_anim_walk;
-
                        self.monster_loot = spawnfunc_ammo_cells;
                        self.weapon = WEP_MACHINEGUN;
-                       self.frame = vore_anim_walk;
 
                        return true;
                }
index cef6ed66eb7c9e27f8b7f3a64b0c36999152c387..d931a5b2e07b59832d0432ce77f22c5ec6693e24 100644 (file)
@@ -25,11 +25,13 @@ float autocvar_g_monster_wyvern_speed_stop;
 float autocvar_g_monster_wyvern_speed_run;
 float autocvar_g_monster_wyvern_speed_walk;
 
+/*
 const float wyvern_anim_hover  = 0;
 const float wyvern_anim_fly            = 1;
 const float wyvern_anim_magic  = 2;
 const float wyvern_anim_pain   = 3;
 const float wyvern_anim_death  = 4;
+*/
 
 void M_Wyvern_Attack_Fireball_Explode()
 {
@@ -113,16 +115,30 @@ float M_Wyvern(float req)
                }
                case MR_PAIN:
                {
+                       self.pain_finished = time + 0.5;
+                       setanim(self, self.anim_pain1, true, true, false);
                        return true;
                }
                case MR_DEATH:
                {
-                       self.frame = wyvern_anim_death;
+                       setanim(self, self.anim_die1, false, true, true);
                        self.velocity_x = -200 + 400 * random();
                        self.velocity_y = -200 + 400 * random();
                        self.velocity_z = 100 + 100 * random();
                        return true;
                }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '4 1 0.5', none); // 2 seconds
+                       self.anim_walk = animfixfps(self, '1 1 1', none);
+                       self.anim_idle = animfixfps(self, '0 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '3 1 2', none); // 0.5 seconds
+                       self.anim_shoot = animfixfps(self, '2 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '1 1 1', none);
+
+                       return true;
+               }
                case MR_SETUP:
                {
                        if(!self.health) self.health = (autocvar_g_monster_wyvern_health);
@@ -131,12 +147,7 @@ float M_Wyvern(float req)
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_wyvern_speed_stop); }
                        if(!self.damageforcescale) { self.damageforcescale = (autocvar_g_monster_wyvern_damageforcescale); }
 
-                       self.m_anim_walk = wyvern_anim_hover;
-                       self.m_anim_run = wyvern_anim_fly;
-                       self.m_anim_idle = wyvern_anim_hover;
-
                        self.monster_loot = spawnfunc_item_cells;
-                       self.frame = wyvern_anim_hover;
 
                        return true;
                }
index e754ef408a9b3750a34e1facc60debae5461db91..966dc99a5df5e8be3e26dc0ab1cad4a3cec0b8f5 100644 (file)
@@ -23,6 +23,7 @@ float autocvar_g_monster_zombie_speed_stop;
 float autocvar_g_monster_zombie_speed_run;
 float autocvar_g_monster_zombie_speed_walk;
 
+/*
 const float zombie_anim_attackleap                     = 0;
 const float zombie_anim_attackrun1                     = 1;
 const float zombie_anim_attackrun2                     = 2;
@@ -54,6 +55,7 @@ const float zombie_anim_runforward                    = 27;
 const float zombie_anim_runforwardleft         = 28;
 const float zombie_anim_runforwardright                = 29;
 const float zombie_anim_spawn                          = 30;
+*/
 
 void M_Zombie_Attack_Leap_Touch()
 {
@@ -83,17 +85,17 @@ void M_Zombie_Defend_Block_End()
        if(self.health <= 0)
                return;
 
-       self.frame = zombie_anim_blockend;
+       setanim(self, self.anim_blockend, false, true, true);
        self.armorvalue = autocvar_g_monsters_armor_blockpercent;
 }
 
 float M_Zombie_Defend_Block()
 {
-       self.frame = zombie_anim_blockstart;
        self.armorvalue = 0.9;
        self.state = MONSTER_ATTACK_MELEE; // freeze monster
        self.attack_finished_single = time + 2.1;
        self.anim_finished = self.attack_finished_single;
+       setanim(self, self.anim_blockstart, false, true, true);
 
        Monster_Delay(1, 0, 2, M_Zombie_Defend_Block_End);
 
@@ -106,24 +108,25 @@ float M_Zombie_Attack(float attack_type)
        {
                case MONSTER_ATTACK_MELEE:
                {
-                       float rand = random(), chosen_anim;
+                       if(random() < 0.3 && self.health < 75 && self.enemy.health > 10)
+                               return M_Zombie_Defend_Block();
+
+                       float rand = random();
+                       vector chosen_anim;
 
                        if(rand < 0.33)
-                               chosen_anim = zombie_anim_attackstanding1;
+                               chosen_anim = self.anim_melee1;
                        else if(rand < 0.66)
-                               chosen_anim = zombie_anim_attackstanding2;
+                               chosen_anim = self.anim_melee2;
                        else
-                               chosen_anim = zombie_anim_attackstanding3;
-
-                       if(random() < 0.3 && self.health < 75 && self.enemy.health > 10)
-                               return M_Zombie_Defend_Block();
+                               chosen_anim = self.anim_melee3;
 
                        return Monster_Attack_Melee(self.enemy, (autocvar_g_monster_zombie_attack_melee_damage), chosen_anim, self.attack_range, (autocvar_g_monster_zombie_attack_melee_delay), DEATH_MONSTER_ZOMBIE_MELEE, true);
                }
                case MONSTER_ATTACK_RANGED:
                {
                        makevectors(self.angles);
-                       return Monster_Attack_Leap(zombie_anim_attackleap, M_Zombie_Attack_Leap_Touch, v_forward * (autocvar_g_monster_zombie_attack_leap_speed) + '0 0 200', (autocvar_g_monster_zombie_attack_leap_delay));
+                       return Monster_Attack_Leap(self.anim_shoot, M_Zombie_Attack_Leap_Touch, v_forward * (autocvar_g_monster_zombie_attack_leap_speed) + '0 0 200', (autocvar_g_monster_zombie_attack_leap_delay));
                }
        }
 
@@ -145,13 +148,34 @@ float M_Zombie(float req)
                case MR_PAIN:
                {
                        self.pain_finished = time + 0.34;
-                       self.frame = (random() >= 0.5) ? zombie_anim_painfront1 : zombie_anim_painfront2;
+                       setanim(self, ((random() > 0.5) ? self.anim_pain1 : self.anim_pain2), true, true, false);
                        return true;
                }
                case MR_DEATH:
                {
                        self.armorvalue = autocvar_g_monsters_armor_blockpercent;
-                       self.frame = ((random() > 0.5) ? zombie_anim_deathback1 : zombie_anim_deathfront1);
+
+                       setanim(self, ((random() > 0.5) ? self.anim_die1 : self.anim_die2), false, true, true);
+                       return true;
+               }
+               case MR_ANIM:
+               {
+                       vector none = '0 0 0';
+                       self.anim_die1 = animfixfps(self, '9 1 0.5', none); // 2 seconds
+                       self.anim_die2 = animfixfps(self, '12 1 0.5', none); // 2 seconds
+                       self.anim_spawn = animfixfps(self, '30 1 3', none);
+                       self.anim_walk = animfixfps(self, '27 1 1', none);
+                       self.anim_idle = animfixfps(self, '19 1 1', none);
+                       self.anim_pain1 = animfixfps(self, '20 1 2', none); // 0.5 seconds
+                       self.anim_pain2 = animfixfps(self, '22 1 2', none); // 0.5 seconds
+                       self.anim_melee1 = animfixfps(self, '4 1 5', none); // analyze models and set framerate
+                       self.anim_melee2 = animfixfps(self, '4 1 5', none); // analyze models and set framerate
+                       self.anim_melee3 = animfixfps(self, '4 1 5', none); // analyze models and set framerate
+                       self.anim_shoot = animfixfps(self, '0 1 5', none); // analyze models and set framerate
+                       self.anim_run = animfixfps(self, '27 1 1', none);
+                       self.anim_blockstart = animfixfps(self, '8 1 1', none);
+                       self.anim_blockend = animfixfps(self, '7 1 1', none);
+
                        return true;
                }
                case MR_SETUP:
@@ -161,22 +185,19 @@ float M_Zombie(float req)
                        if(!self.speed2) { self.speed2 = (autocvar_g_monster_zombie_speed_run); }
                        if(!self.stopspeed) { self.stopspeed = (autocvar_g_monster_zombie_speed_stop); }
 
-                       self.m_anim_walk = zombie_anim_runforward;
-                       self.m_anim_run = zombie_anim_runforward;
-                       self.m_anim_idle = zombie_anim_idle;
-
                        if(self.spawnflags & MONSTERFLAG_NORESPAWN)
                                self.spawnflags &= ~MONSTERFLAG_NORESPAWN; // zombies always respawn
 
                        self.spawnflags |= MONSTER_RESPAWN_DEATHPOINT;
 
                        self.monster_loot = spawnfunc_item_health_medium;
-                       self.frame = zombie_anim_spawn;
-                       self.spawn_time = time + 2.1;
                        self.spawnshieldtime = self.spawn_time;
                        self.respawntime = 0.2;
                        self.damageforcescale = 0.0001; // no push while spawning
 
+                       setanim(self, self.anim_spawn, false, true, true);
+                       self.spawn_time = self.animstate_endtime;
+
                        return true;
                }
                case MR_PRECACHE:
index 1a2bdeea8f937aace52695c5f688cafc35b2742f..33068648ec88ad9581bf894f1f511bf4d6147048 100644 (file)
@@ -7,6 +7,7 @@ const int MR_THINK = 2; // (SERVER) logic to run every frame
 const int MR_DEATH = 3; // (SERVER) called when monster dies
 const int MR_PRECACHE = 4; // (BOTH) precaches models/sounds used by this monster
 const int MR_PAIN = 5; // (SERVER) called when monster is damaged
+const int MR_ANIM = 6; // (BOTH?) sets animations for monster
 
 // functions
 entity get_monsterinfo(float id);
index 848df83c8559d38126ef8d9ad8b020ad6d207a9e..7d21678b4b3d6e1c94d1012d97db86f8d822c3bb 100644 (file)
@@ -356,13 +356,16 @@ void Monster_Sound(.string samplefield, float sound_delay, float delaytoo, float
 // Monster attack handlers
 // =======================
 
-float Monster_Attack_Melee(entity targ, float damg, float anim, float er, float animtime, int deathtype, float dostop)
+float Monster_Attack_Melee(entity targ, float damg, vector anim, float er, float animtime, int deathtype, float dostop)
 {
        if(dostop) { self.state = MONSTER_ATTACK_MELEE; }
 
-       self.frame = anim;
+       setanim(self, anim, true, true, true);
 
-       if(animtime > 0) { self.attack_finished_single = self.anim_finished = time + animtime; }
+       if(self.animstate_endtime > time)
+               self.attack_finished_single = self.anim_finished = self.animstate_endtime;
+       else
+               self.attack_finished_single = self.anim_finished = time + animtime;
 
        monster_makevectors(targ);
 
@@ -396,21 +399,24 @@ float Monster_Attack_Leap_Check(vector vel)
        return true;
 }
 
-bool Monster_Attack_Leap(int anm, void() touchfunc, vector vel, float animtime)
+bool Monster_Attack_Leap(vector anm, void() touchfunc, vector vel, float animtime)
 {
        if(!Monster_Attack_Leap_Check(vel))
                return false;
 
-       self.frame = anm;
+       setanim(self, anm, true, true, true);
+
+       if(self.animstate_endtime > time)
+               self.attack_finished_single = self.anim_finished = self.animstate_endtime;
+       else
+               self.attack_finished_single = self.anim_finished = time + animtime;
+
        self.state = MONSTER_ATTACK_RANGED;
        self.touch = touchfunc;
        self.origin_z += 1;
        self.velocity = vel;
        self.flags &= ~FL_ONGROUND;
 
-       self.attack_finished_single = time + animtime;
-       self.anim_finished = self.attack_finished_single; // TODO: make these frame based
-
        return true;
 }
 
@@ -447,6 +453,24 @@ void Monster_Attack_Check(entity e, entity targ)
 // Main monster functions
 // ======================
 
+void Monster_UpdateModel()
+{
+       // assume some defaults
+       /*self.anim_idle   = animfixfps(self, '0 1 0.01', '0 0 0');
+       self.anim_walk   = animfixfps(self, '1 1 0.01', '0 0 0');
+       self.anim_run    = animfixfps(self, '2 1 0.01', '0 0 0');
+       self.anim_fire1  = animfixfps(self, '3 1 0.01', '0 0 0');
+       self.anim_fire2  = animfixfps(self, '4 1 0.01', '0 0 0');
+       self.anim_melee  = animfixfps(self, '5 1 0.01', '0 0 0');
+       self.anim_pain1  = animfixfps(self, '6 1 0.01', '0 0 0');
+       self.anim_pain2  = animfixfps(self, '7 1 0.01', '0 0 0');
+       self.anim_die1   = animfixfps(self, '8 1 0.01', '0 0 0');
+       self.anim_die2   = animfixfps(self, '9 1 0.01', '0 0 0');*/
+
+       // then get the real values
+       MON_ACTION(self.monsterid, MR_ANIM);
+}
+
 void Monster_Skin_Check()
 {
        vector oldmin = self.mins, oldmax = self.maxs;
@@ -458,6 +482,7 @@ void Monster_Skin_Check()
                precache_model(trymodel);
                setmodel(self, trymodel);
                setsize(self, oldmin, oldmax);
+               Monster_UpdateModel();
                CSQCMODEL_AUTOUPDATE(); // do a quick update
        }
 
@@ -468,6 +493,7 @@ void Monster_Touch()
 {
        if(other == world) { return; }
 
+       if(other.monster_attack)
        if(self.enemy != other)
        if(!IS_MONSTER(other))
        if(Monster_ValidTarget(self, other))
@@ -678,7 +704,7 @@ void Monster_CalculateVelocity(entity mon, vector to, vector from, float turnrat
        //mon.angles = vectoangles(mon.velocity);
 }
 
-void Monster_Move(float runspeed, float walkspeed, float stpspeed, float manim_run, float manim_walk, float manim_idle)
+void Monster_Move(float runspeed, float walkspeed, float stpspeed)
 {
        if(self.target2) { self.goalentity = find(world, targetname, self.target2); }
 
@@ -694,7 +720,7 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed, float manim_r
                        WaypointSprite_UpdateHealth(self.sprite, self.health);
 
                movelib_beak_simple(stpspeed);
-               self.frame = manim_idle;
+               setanim(self, self.anim_idle, true, false, false);
 
                self.enemy = world;
                self.nextthink = time + self.ticrate;
@@ -713,7 +739,7 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed, float manim_r
                        WaypointSprite_UpdateHealth(self.sprite, self.health);
 
                movelib_beak_simple(stpspeed);
-               self.frame = manim_idle;
+               setanim(self, self.anim_idle, true, false, false);
 
                self.enemy = world;
                self.nextthink = time + self.ticrate;
@@ -785,7 +811,7 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed, float manim_r
        {
                runspeed = walkspeed = 0;
                if(time >= self.spawn_time)
-                       self.frame = manim_idle;
+                       setanim(self, self.anim_idle, true, false, false);
                movelib_beak_simple(stpspeed);
                return;
        }
@@ -861,9 +887,9 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed, float manim_r
                if(!self.state)
                if(time > self.anim_finished)
                if(vlen(self.velocity) > 10)
-                       self.frame = ((do_run) ? manim_run : manim_walk);
+                       setanim(self, ((do_run) ? self.anim_run : self.anim_walk), true, false, false);
                else
-                       self.frame = manim_idle;
+                       setanim(self, self.anim_idle, true, false, false);
        }
        else
        {
@@ -878,7 +904,7 @@ void Monster_Move(float runspeed, float walkspeed, float stpspeed, float manim_r
                if(time > self.pain_finished)
                if(!self.state)
                if(vlen(self.velocity) <= 30)
-                       self.frame = manim_idle;
+                       setanim(self, self.anim_idle, true, false, false);
        }
 
        self.steerto = steerlib_attract2(((self.monster_face) ? self.monster_face : self.moveto), 0.5, 500, 0.95);
@@ -1114,13 +1140,13 @@ void Monster_Damage(entity inflictor, entity attacker, float damage, int deathty
 }
 
 // don't check for enemies, just keep walking in a straight line
-void Monster_Move_2D(float mspeed, float allow_jumpoff, float manim_walk, float manim_idle)
+void Monster_Move_2D(float mspeed, float allow_jumpoff)
 {
        if(gameover || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || self.draggedby != world || time < game_starttime || (autocvar_g_campaign && !campaign_bots_may_start) || time < self.spawn_time)
        {
                mspeed = 0;
                if(time >= self.spawn_time)
-                       self.frame = manim_idle;
+                       setanim(self, self.anim_idle, true, false, false);
                movelib_beak_simple(0.6);
                return;
        }
@@ -1164,9 +1190,9 @@ void Monster_Move_2D(float mspeed, float allow_jumpoff, float manim_walk, float
        if(time > self.pain_finished)
        if(time > self.attack_finished_single)
        if(vlen(self.velocity) > 10)
-               self.frame = manim_walk;
+               setanim(self, self.anim_walk, true, false, false);
        else
-               self.frame = manim_idle;
+               setanim(self, self.anim_idle, true, false, false);
 }
 
 void Monster_Think()
@@ -1184,7 +1210,7 @@ void Monster_Think()
        if(self.skin != self.oldskin) { Monster_Skin_Check(); }
 
        if(MON_ACTION(self.monsterid, MR_THINK))
-               Monster_Move(self.speed2, self.speed, self.stopspeed, self.m_anim_run, self.m_anim_walk, self.m_anim_idle);
+               Monster_Move(self.speed2, self.speed, self.stopspeed);
 
        CSQCMODEL_AUTOUPDATE();
 }
@@ -1336,6 +1362,8 @@ bool Monster_Spawn(int mon_id)
 
        self.ticrate = bound(sys_frametime, ((!self.ticrate) ? autocvar_g_monsters_think_delay : self.ticrate), 60);
 
+       Monster_UpdateModel();
+
        if(!Monster_Spawn_Setup())
        {
                Monster_Remove(self);
index 5a57fbbbd24b265afb5abe6db1d904e318f57bb2..d5f04b765871c0d324a01579d90c1e3d803a58b4 100644 (file)
@@ -26,12 +26,20 @@ int monsters_killed;
 .vector monster_face; // custom looking direction for monster (reset to '0 0 0' when you're done!)
 .float speed2; // run speed
 .float stopspeed;
-.int m_anim_run;
-.int m_anim_walk;
-.int m_anim_idle;
 .int oldskin;
 .string mdl_dead; // dead model for goombas
 
+.vector anim_blockend;
+.vector anim_blockstart;
+.vector anim_melee1;
+.vector anim_melee2;
+.vector anim_melee3;
+.vector anim_pain3;
+.vector anim_pain4;
+.vector anim_pain5;
+.vector anim_walk;
+.vector anim_spawn;
+
 #define MONSTER_SKILLMOD(mon) (0.5 + mon.monster_skill * ((1.2 - 0.3) / 10))
 
 // other properties
@@ -83,13 +91,13 @@ void monster_setupcolors(entity mon);
 
 void Monster_Touch();
 
-void Monster_Move_2D(float mspeed, float allow_jumpoff, float manim_walk, float manim_idle);
+void Monster_Move_2D(float mspeed, float allow_jumpoff);
 
 void Monster_Delay(float repeat_count, float repeat_defer, float defer_amnt, void() func);
 
-float Monster_Attack_Melee(entity targ, float damg, float anim, float er, float animtime, int deathtype, float dostop);
+float Monster_Attack_Melee(entity targ, float damg, vector anim, float er, float animtime, int deathtype, float dostop);
 
-bool Monster_Attack_Leap(int anm, void() touchfunc, vector vel, float animtime);
+bool Monster_Attack_Leap(vector anm, void() touchfunc, vector vel, float animtime);
 
 entity Monster_FindTarget(entity mon);
 
index 389f3036efdd7ddd009d73560cd14da757d39504..4b1c8c4ff4a08037fd73b7ecce1c296c560fb9d5 100644 (file)
@@ -439,6 +439,10 @@ void FixPlayermodel()
        if(!cvar("g_overkill") && self.cow && cow_allowed)
                defaultmodel = "models/player/cow.md3";
 
+       ret_string = defaultmodel;
+       MUTATOR_CALLHOOK(FixPlayermodel);
+       defaultmodel = ret_string;
+
        if(defaultmodel != "")
        {
                if (defaultmodel != self.model)
@@ -2729,8 +2733,8 @@ void PlayerPreThink (void)
                        if (!self.crouch)
                        {
                                self.crouch = true;
-                               self.view_ofs = PL_CROUCH_VIEW_OFS;
-                               setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX);
+                               self.view_ofs = self.stat_pl_crouch_view_ofs;
+                               setsize (self, self.stat_pl_crouch_min, self.stat_pl_crouch_max);
                                // setanim(self, self.anim_duck, false, true, true); // this anim is BROKEN anyway
                        }
                }
@@ -2738,12 +2742,12 @@ void PlayerPreThink (void)
                {
                        if (self.crouch)
                        {
-                               tracebox(self.origin, PL_MIN, PL_MAX, self.origin, false, self);
+                               tracebox(self.origin, self.stat_pl_min, self.stat_pl_max, self.origin, false, self);
                                if (!trace_startsolid || self.pbhost)
                                {
                                        self.crouch = false;
-                                       self.view_ofs = PL_VIEW_OFS;
-                                       setsize (self, PL_MIN, PL_MAX);
+                                       self.view_ofs = self.stat_pl_view_ofs;
+                                       setsize (self, self.stat_pl_min, self.stat_pl_max);
                                }
                        }
                }
index c3ea39badd7e584b7807f8f208b323d67dd9a51a..b1db8a63683c1c3de80b154b1e13cbe83a700d4a 100644 (file)
@@ -104,6 +104,11 @@ MUTATOR_HOOKABLE(SpectateCopy);
        // INPUT:
 //             entity other;
 
+MUTATOR_HOOKABLE(FixPlayermodel);
+       // allows modifying player's model
+       // INPUT, OUTPUT:
+       // string ret_string;
+
 MUTATOR_HOOKABLE(ForbidThrowCurrentWeapon);
        // returns 1 if throwing the current weapon shall not be allowed