void CSQCModel_Fade_Apply()
{
+ if(!self.fade_end) { return; }
vector org;
float alph;
org = getpropertyvec(VF_ORIGIN);
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;
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;
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);
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
{
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;
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);
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
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)
{
//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
{
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;
}
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:
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;
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;
const float demon_anim_pain = 4;
const float demon_anim_death = 5;
const float demon_anim_attack = 6;
+*/
void M_Demon_Attack_Leap_Touch()
{
{
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));
}
}
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:
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;
}
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;
const float enforcer_anim_pain2 = 7;
const float enforcer_anim_pain3 = 8;
const float enforcer_anim_pain4 = 9;
+*/
void M_Enforcer_Attack_Plasma_Explode()
{
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;
}
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:
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;
{
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:
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;
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;
}
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);
}
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;
}
}
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);
}
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:
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;
}
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;
const float ogre_anim_death1 = 11;
const float ogre_anim_death2 = 12;
const float ogre_anim_pull = 13;
+*/
void M_Ogre_Attack_MachineGun()
{
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;
}
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;
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;
}
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;
}
}
}
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:
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;
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)
{
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:
{
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:
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;
}
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;
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)
{
{
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:
{
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:
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;
}
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()
{
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();
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);
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;
}
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;
const float shambler_anim_magic = 6;
const float shambler_anim_pain = 7;
const float shambler_anim_death = 8;
+*/
.float shambler_lastattack; // delay attacks separately
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);
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;
}
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;
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:
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;
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()
{
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;
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);
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;
}
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;
{
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();
}
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);
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;
}
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;
{
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);
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:
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;
}
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()
{
}
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);
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;
}
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;
const float zombie_anim_runforwardleft = 28;
const float zombie_anim_runforwardright = 29;
const float zombie_anim_spawn = 30;
+*/
void M_Zombie_Attack_Leap_Touch()
{
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);
{
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));
}
}
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:
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:
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);
// 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);
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;
}
// 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;
precache_model(trymodel);
setmodel(self, trymodel);
setsize(self, oldmin, oldmax);
+ Monster_UpdateModel();
CSQCMODEL_AUTOUPDATE(); // do a quick update
}
{
if(other == world) { return; }
+ if(other.monster_attack)
if(self.enemy != other)
if(!IS_MONSTER(other))
if(Monster_ValidTarget(self, other))
//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); }
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;
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;
{
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;
}
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
{
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);
}
// 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;
}
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()
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();
}
self.ticrate = bound(sys_frametime, ((!self.ticrate) ? autocvar_g_monsters_think_delay : self.ticrate), 60);
+ Monster_UpdateModel();
+
if(!Monster_Spawn_Setup())
{
Monster_Remove(self);
.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
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);
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)
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
}
}
{
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);
}
}
}
// 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