Exemple #1
0
int16 CBattleEntity::GetRangedWeaponDelay(bool tp)
{
    CItemWeapon* PRange = (CItemWeapon*)m_Weapons[SLOT_RANGED];
    CItemWeapon* PAmmo = (CItemWeapon*)m_Weapons[SLOT_AMMO];

    // base delay
    int delay = 240;

    if (PRange != nullptr && PRange->getDamage() != 0) {
        delay += ((PRange->getDelay() * 60) / 1000);
    }

    if (PAmmo != nullptr && PAmmo->isThrowing())
    {
        // this is a throwing weapon
        delay += ((PAmmo->getDelay() * 60) / 1000);
    }

    delay = (((delay - getMod(MOD_RANGED_DELAY)) * 1000) / 110);

    //apply haste and delay reductions that don't affect tp
    if (!tp)
    {
        delay = delay * ((float)(100 + getMod(MOD_RANGED_DELAYP)) / 100);
    }
    else {

        if (PAmmo != nullptr && PAmmo->getDamage() != 0 && !PAmmo->isThrowing()) {
            delay += ((PAmmo->getDelay() * 60) / 1000);
        }
    }
    return delay;
}
Exemple #2
0
bool CRangeState::CanUseRangedAttack(CBattleEntity* PTarget)
{
    if (!PTarget)
    {
        m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, m_PEntity, 0, 0, MSGBASIC_CANNOT_ATTACK_TARGET);
        return false;
    }
    CItemWeapon* PRanged = (CItemWeapon*)m_PEntity->getEquip(SLOT_RANGED);
    CItemWeapon* PAmmo = (CItemWeapon*)m_PEntity->getEquip(SLOT_AMMO);

    if (!(PRanged && PRanged->isType(ITEM_WEAPON) ||
        PAmmo && PAmmo->isThrowing()))
    {
        m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, m_PEntity, 0, 0, MSGBASIC_NO_RANGED_WEAPON);
        return false;
    }

    auto SkillType = PRanged ? PRanged->getSkillType() : PAmmo->getSkillType();

    switch (SkillType)
    {
        case SKILL_THR:
        {
            // remove barrage, doesn't work here
            m_PEntity->StatusEffectContainer->DelStatusEffect(EFFECT_BARRAGE);
            break;
        }
        case SKILL_ARC:
        case SKILL_MRK:
        {
            PRanged = (CItemWeapon*)m_PEntity->getEquip(SLOT_AMMO);
            if (PRanged != nullptr && PRanged->isType(ITEM_WEAPON))
            {
                break;
            }
        }
        default:
        {
            m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, m_PEntity, 0, 0, MSGBASIC_NO_RANGED_WEAPON);
            return false;
        }
    }

    if (!isFaceing(m_PEntity->loc.p, PTarget->loc.p, 40))
    {
        m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, PTarget, 0, 0, MSGBASIC_CANNOT_SEE);
        return false;
    }
    if (distance(m_PEntity->loc.p, PTarget->loc.p) > 25)
    {
        m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, PTarget, 0, 0, MSGBASIC_TOO_FAR_AWAY);
        return false;
    }
    if (!m_PEntity->PAI->TargetFind->canSee(&PTarget->loc.p))
    {
        m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, PTarget, 0, 0, MSGBASIC_CANNOT_PERFORM_ACTION);
        return false;
    }

    return true;
}