void Monster::doAttacking(uint32_t interval)
{
if(!attackedCreature || (isSummon() && attackedCreature == this))
return;
bool updateLook = true, outOfRange = true;
resetTicks = interval;
attackTicks += interval;
const Position& myPos = getPosition();
for(SpellList::iterator it = mType->spellAttackList.begin(); it != mType->spellAttackList.end(); ++it)
{
if(!attackedCreature || attackedCreature->isRemoved())
break;
const Position& targetPos = attackedCreature->getPosition();
if(it->isMelee && isFleeing())
continue;
bool inRange = false;
if(canUseSpell(myPos, targetPos, *it, interval, inRange))
{
if(it->chance >= (uint32_t)random_range(1, 100))
{
if(updateLook)
{
updateLookDirection();
updateLook = false;
}
double multiplier;
if(maxCombatValue > 0) //defense
multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_DEFENSE);
else //attack
multiplier = g_config.getDouble(ConfigManager::RATE_MONSTER_ATTACK);
minCombatValue = (int32_t)(it->minCombatValue * multiplier);
maxCombatValue = (int32_t)(it->maxCombatValue * multiplier);
it->spell->castSpell(this, attackedCreature);
if(it->isMelee)
extraMeleeAttack = false;
#ifdef __DEBUG__
static uint64_t prevTicks = OTSYS_TIME();
std::clog << "doAttacking ticks: " << OTSYS_TIME() - prevTicks << std::endl;
prevTicks = OTSYS_TIME();
#endif
}
}
if(inRange)
outOfRange = false;
else if(it->isMelee) //melee swing out of reach
extraMeleeAttack = true;
}
if(updateLook)
updateLookDirection();
if(resetTicks)
attackTicks = 0;
}