}
else
{
- Send_Effect("healing_fx", head.origin, '0 0 0', 1);
+ Send_Effect(EFFECT_HEALING, head.origin, '0 0 0', 1);
head.health = bound(0, head.health + (autocvar_g_monster_mage_heal_allies), head.max_health);
- if(!(head.spawnflags & MONSTERFLAG_INVINCIBLE))
+ if(!(head.spawnflags & MONSTERFLAG_INVINCIBLE) && head.sprite)
WaypointSprite_UpdateHealth(head.sprite, head.health);
}
}
{
sound(self, CH_SHOTS, W_Sound("tagexp1"), 1, ATTEN_NORM);
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);
- Send_Effect("TE_EXPLOSION", self.origin, '0 0 0', 1);
+ Send_Effect(EFFECT_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);
}
.float shambler_lastattack; // delay attacks separately
-void shambler_smash()
+void M_Shambler_Attack_Smash()
{
makevectors(self.angles);
- Send_Effect("explosion_medium", (self.origin + (v_forward * 150)) - ('0 0 1' * self.maxs.z), '0 0 0', 1);
+ Send_Effect(EFFECT_EXPLOSION_MEDIUM, (self.origin + (v_forward * 150)) - ('0 0 1' * self.maxs.z), '0 0 0', 1);
sound(self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
- tracebox(self.origin + v_forward * 50, self.mins * 0.5, self.maxs * 0.5, self.origin + v_forward * 500, MOVE_NORMAL, self);
+ // RadiusDamage does NOT support custom starting location, which means we must use this hack...
+
+ tracebox(self.origin + v_forward * 50, self.mins * 0.5, self.maxs * 0.5, self.origin + v_forward * autocvar_g_monster_shambler_attack_smash_range, MOVE_NORMAL, self);
if(trace_ent.takedamage)
- Damage(trace_ent, self, self, (autocvar_g_monster_shambler_attack_smash_damage) * Monster_SkillModifier(), DEATH_MONSTER_SHAMBLER_SMASH, trace_ent.origin, normalize(trace_ent.origin - self.origin));
+ Damage(trace_ent, self, self, (autocvar_g_monster_shambler_attack_smash_damage) * MONSTER_SKILLMOD(self), DEATH_MONSTER_SHAMBLER_SMASH, trace_ent.origin, normalize(trace_ent.origin - self.origin));
}
-void shambler_swing()
+void M_Shambler_Attack_Swing()
{
float r = (random() < 0.5);
- monster_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);
- if(r)
+ if(r && 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))
{
- defer(0.5, shambler_swing);
+ Monster_Delay(1, 0, 0.5, M_Shambler_Attack_Swing);
self.attack_finished_single += 0.5;
+ self.anim_finished = self.attack_finished_single;
}
}
self.angles_y += turny;
}
- monster_checkattack(self, self.enemy);
+ Monster_Attack_Check(self, self.enemy);
}
-void monster_remove(entity mon)
+void Monster_Remove(entity mon)
{
- if(!mon)
- return; // nothing to remove
-
- Send_Effect(EFFECT_ITEM_PICKUP, mon.origin, '0 0 0', 1);
+ if(!mon) { return; }
- if(mon.weaponentity)
- remove(mon.weaponentity);
-
- if(mon.iceblock)
- remove(mon.iceblock);
+ if(!MUTATOR_CALLHOOK(MonsterRemove, mon))
- Send_Effect("item_pickup", mon.origin, '0 0 0', 1);
++ Send_Effect(EFFECT_ITEM_PICKUP, mon.origin, '0 0 0', 1);
+ if(mon.weaponentity) { remove(mon.weaponentity); }
+ if(mon.iceblock) { remove(mon.iceblock); }
WaypointSprite_Kill(mon.sprite);
-
remove(mon);
}