return false;
}
- traceline(this.origin + this.view_ofs, targ.origin, MOVE_NOMONSTERS, this);
+ vector targ_origin = ((targ.absmin + targ.absmax) * 0.5);
+ traceline(this.origin + this.view_ofs, targ_origin, MOVE_NOMONSTERS, this);
- if(trace_fraction < 1)
+ if(trace_fraction < 1 && trace_ent != targ)
return false; // solid
if(autocvar_g_monsters_target_infront || (this.spawnflags & MONSTERFLAG_INFRONT))
return true;
}
-void Monster_Attack_Check(entity this, entity targ)
+void Monster_Attack_Check(entity this, entity targ, .entity weaponentity)
{
+ int slot = weaponslot(weaponentity);
+
if((!this || !targ)
|| (!this.monster_attackfunc)
- || (time < this.attack_finished_single[0])
+ || (time < this.attack_finished_single[slot])
) { return; }
if(vdist(targ.origin - this.origin, <=, this.attack_range))
{
- int attack_success = this.monster_attackfunc(MONSTER_ATTACK_MELEE, this, targ);
+ int attack_success = this.monster_attackfunc(MONSTER_ATTACK_MELEE, this, targ, weaponentity);
if(attack_success == 1)
Monster_Sound(this, monstersound_melee, 0, false, CH_VOICE);
else if(attack_success > 0)
if(vdist(targ.origin - this.origin, >, this.attack_range))
{
- int attack_success = this.monster_attackfunc(MONSTER_ATTACK_RANGED, this, targ);
+ int attack_success = this.monster_attackfunc(MONSTER_ATTACK_RANGED, this, targ, weaponentity);
if(attack_success == 1)
Monster_Sound(this, monstersound_melee, 0, false, CH_VOICE);
else if(attack_success > 0)
void Monster_Move(entity this, float runspeed, float walkspeed, float stpspeed)
{
// update goal entity if lost
- if(this.target2 && this.goalentity.targetname != this.target2) { this.goalentity = find(NULL, targetname, this.target2); }
+ if(this.target2 && this.target2 != "" && this.goalentity.targetname != this.target2)
+ this.goalentity = find(NULL, targetname, this.target2);
if(STAT(FROZEN, this) == 2)
{
entity targ = this.goalentity;
if (MUTATOR_CALLHOOK(MonsterMove, this, runspeed, walkspeed, targ)
- || gameover
+ || game_stopped
|| this.draggedby != NULL
|| (round_handler_IsActive() && !round_handler_IsRoundStarted())
|| time < game_starttime
else
{
entity e = this.goalentity; //find(NULL, targetname, this.target2);
- if(e.target2)
+ if(e.target2 && e.target2 != "")
this.target2 = e.target2;
- else if(e.target) // compatibility
+ else if(e.target && e.target != "") // compatibility
this.target2 = e.target;
movelib_brake_simple(this, stpspeed);
this.angles_y += turny;
}
- Monster_Attack_Check(this, this.enemy);
+ .entity weaponentity = weaponentities[0]; // TODO?
+ Monster_Attack_Check(this, this.enemy, weaponentity);
}
void Monster_Remove(entity this)
mon.mr_death(mon, this);
if(this.candrop && this.weapon)
- W_ThrowNewWeapon(this, this.weapon, 0, this.origin, randomvec() * 150 + '0 0 325');
+ {
+ .entity weaponentity = weaponentities[0]; // TODO: unhardcode
+ W_ThrowNewWeapon(this, this.weapon, 0, this.origin, randomvec() * 150 + '0 0 325', weaponentity);
+ }
}
void Monster_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
this.dmg_time = time;
- if(sound_allowed(MSG_BROADCAST, attacker) && deathtype != DEATH_DROWN.m_id)
+ if(deathtype != DEATH_DROWN.m_id && deathtype != DEATH_FIRE.m_id && sound_allowed(MSG_BROADCAST, attacker))
spamsound (this, CH_PAIN, SND(BODYIMPACT1), VOL_BASE, ATTEN_NORM); // FIXME: PLACEHOLDER
this.velocity += force * this.damageforcescale;
// don't check for enemies, just keep walking in a straight line
void Monster_Move_2D(entity this, float mspeed, bool allow_jumpoff)
{
- if(gameover || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || this.draggedby != NULL || time < game_starttime || (autocvar_g_campaign && !campaign_bots_may_start) || time < this.spawn_time)
+ if(game_stopped || (round_handler_IsActive() && !round_handler_IsRoundStarted()) || this.draggedby != NULL || time < game_starttime || (autocvar_g_campaign && !campaign_bots_may_start) || time < this.spawn_time)
{
mspeed = 0;
if(time >= this.spawn_time)