set g_monsters_healthbars 1
set g_monsters_target_range 2000
set g_monsters_target_infront 0
+set g_monsters_attack_range 120
set g_monsters_respawn 1
set g_monsters_respawn_delay 20
set g_monsters_score_kill 1
{
monsters_setframe(animus_anim_attack);
self.attack_finished_single = time + 1;
- monster_melee(self.enemy, MON_CVAR(animus, attack_melee_damage), 0.3, DEATH_MONSTER_ANIMUS, TRUE);
+ monster_melee(self.enemy, MON_CVAR(animus, attack_melee_damage), self.attack_range, DEATH_MONSTER_ANIMUS, TRUE);
return TRUE;
}
monsters_setframe((len < 50) ? bruiser_anim_attack : bruiser_anim_runattack);
self.attack_finished_single = time + 1.25;
- monster_melee(self.enemy, MON_CVAR(bruiser, attack_melee_damage), 0.3, DEATH_MONSTER_BRUISER, FALSE);
+ monster_melee(self.enemy, MON_CVAR(bruiser, attack_melee_damage), self.attack_range, DEATH_MONSTER_BRUISER, FALSE);
return TRUE;
}
self.brute_cycles += 1;
self.angles_y = self.angles_y + random()* 25;
- monster_melee(self.enemy, MON_CVAR(brute, attack_chainsaw_damage), 0.3, DEATH_MONSTER_BRUTE_BLADE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(brute, attack_chainsaw_damage), self.attack_range, DEATH_MONSTER_BRUTE_BLADE, TRUE);
if(self.brute_cycles <= 4)
defer(0.2, brute_blade);
{
monsters_setframe(cerberus_anim_attack);
self.attack_finished_single = time + 0.7;
- monster_melee(self.enemy, MON_CVAR(cerberus, attack_bite_damage), 0.2, DEATH_MONSTER_CERBERUS_BITE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(cerberus, attack_bite_damage), self.attack_range, DEATH_MONSTER_CERBERUS_BITE, TRUE);
return TRUE;
}
monsters_setframe(anim);
self.attack_finished_single = time + 0.7;
- monster_melee(self.enemy, MON_CVAR(knight, attack_melee_damage), 0.3, DEATH_MONSTER_KNIGHT_MELEE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(knight, attack_melee_damage), self.attack_range, DEATH_MONSTER_KNIGHT_MELEE, TRUE);
return TRUE;
}
void mageattack_melee()
{
- monster_melee(self.enemy, MON_CVAR(mage, attack_melee_damage), 0.3, DEATH_MONSTER_MAGE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(mage, attack_melee_damage), self.attack_range, DEATH_MONSTER_MAGE, TRUE);
}
void mage_grenade_explode()
void shambler_smash()
{
- monster_melee(self.enemy, MON_CVAR(shambler, attack_smash_damage), 0.3, DEATH_MONSTER_SHAMBLER_SMASH, TRUE);
+ monster_melee(self.enemy, MON_CVAR(shambler, attack_smash_damage), self.attack_range, DEATH_MONSTER_SHAMBLER_SMASH, TRUE);
}
void shambler_delayedsmash()
{
float r = (random() < 0.5);
monsters_setframe((r) ? shambler_anim_swingr : shambler_anim_swingl);
- monster_melee(self.enemy, MON_CVAR(shambler, attack_claw_damage), 0.3, DEATH_MONSTER_SHAMBLER_CLAW, TRUE);
+ monster_melee(self.enemy, MON_CVAR(shambler, attack_claw_damage), self.attack_range, DEATH_MONSTER_SHAMBLER_CLAW, TRUE);
self.attack_finished_single = time + 0.8;
if(r)
defer(0.5, shambler_swing);
case MR_SETUP:
{
if not(self.health) self.health = MON_CVAR(shambler, health);
+ if not(self.attack_range) self.attack_range = 150;
self.monster_loot = spawnfunc_item_health_mega;
self.monster_attackfunc = shambler_attack;
{
case MONSTER_ATTACK_MELEE:
{
- monster_melee(self.enemy, MON_CVAR(spider, attack_bite_damage), 0.3, DEATH_MONSTER_SPIDER, TRUE);
+ monster_melee(self.enemy, MON_CVAR(spider, attack_bite_damage), self.attack_range, DEATH_MONSTER_SPIDER, TRUE);
monsters_setframe((random() > 0.5) ? spider_anim_attack : spider_anim_attack2);
self.attack_finished_single = time + MON_CVAR(spider, attack_bite_delay);
{
monsters_setframe(stingray_anim_attack);
self.attack_finished_single = time + MON_CVAR(stingray, attack_bite_delay);
- monster_melee(self.enemy, MON_CVAR(stingray, attack_bite_damage), 0.1, DEATH_MONSTER_STINGRAY, FALSE);
+ monster_melee(self.enemy, MON_CVAR(stingray, attack_bite_damage), self.attack_range, DEATH_MONSTER_STINGRAY, FALSE);
return TRUE;
}
self.attack_finished_single = time + MON_CVAR(zombie, attack_melee_delay);
- monster_melee(self.enemy, MON_CVAR(zombie, attack_melee_damage), 0.3, DEATH_MONSTER_ZOMBIE_MELEE, TRUE);
+ monster_melee(self.enemy, MON_CVAR(zombie, attack_melee_damage), self.attack_range, DEATH_MONSTER_ZOMBIE_MELEE, TRUE);
return TRUE;
}
if(self.msound_sight == "") self.msound_sight = strzone(strcat("monsters/", mon, "_sight.wav"));
}
-float monster_melee (entity targ, float damg, float er, float deathtype, float dostop)
+float monster_melee(entity targ, float damg, float er, float deathtype, float dostop)
{
- float dot, rdmg = damg * random();
+ float rdmg = damg * random();
if (self.health <= 0)
return FALSE;
}
makevectors (self.angles);
- dot = normalize (targ.origin - self.origin) * v_forward;
- if(dot > er)
+ traceline(self.origin + self.view_ofs, self.origin + v_forward * er, 0, self);
+
+ if(trace_ent.takedamage)
Damage(targ, self, self, rdmg * monster_skill, deathtype, targ.origin, normalize(targ.origin - self.origin));
return TRUE;
return;
}
+ if(vlen(targ.origin - e.origin) > e.attack_range)
if(e.monster_attackfunc(MONSTER_ATTACK_RANGED))
{
monster_sound(e.msound_attack_ranged, 0, FALSE);
if not(self.monster_respawned)
if not(self.skin)
self.skin = rint(random() * 4);
+
+ if not(self.attack_range)
+ self.attack_range = autocvar_g_monsters_attack_range;
self.pos1 = self.origin;
if(mon.spawnflags & MONSTER_SIZE_BROKEN)
self.scale = 1.3;
- if not(self.attack_range)
- self.attack_range = 120;
-
if not(self.ticrate)
self.ticrate = autocvar_g_monsters_think_delay;
float autocvar_g_monsters_max_perplayer;
float autocvar_g_monsters_target_range;
float autocvar_g_monsters_target_infront;
+float autocvar_g_monsters_attack_range;
float autocvar_g_monsters_typefrag;
float autocvar_g_monsters_owners;
float autocvar_g_monsters_miniboss_chance;