Esempio n. 1
0
bool Character::recalculateBaseAttribute(unsigned int attr)
{
    /*
     * `attr' may or may not have changed. Recalculate the base value.
     */
    LOG_DEBUG("Received update attribute recalculation request at Character "
              "for " << attr << ".");
    if (!mAttributes.count(attr))
        return false;
    double newBase = getAttribute(attr);

    /*
     * Calculate new base.
     */
    switch (attr)
    {
    case ATTR_ACCURACY:
        newBase = getModifiedAttribute(ATTR_DEX); // Provisional
        break;
    case ATTR_DEFENSE:
        newBase = 0.3 * getModifiedAttribute(ATTR_VIT);
        break;
    case ATTR_DODGE:
        newBase = getModifiedAttribute(ATTR_AGI); // Provisional
        break;
    case ATTR_MAGIC_DODGE:
        newBase = 1.0;
        // TODO
        break;
    case ATTR_MAGIC_DEFENSE:
        newBase = 0.0;
        // TODO
        break;
    case ATTR_BONUS_ASPD:
        newBase = 0.0;
        // TODO
        break;
    default:
        return Being::recalculateBaseAttribute(attr);
    }

    if (newBase != getAttribute(attr))
    {
        setAttribute(attr, newBase);
        updateDerivedAttributes(attr);
        return true;
    }
    LOG_DEBUG("No changes to sync for attribute '" << attr << "'.");
    return false;
}
Esempio n. 2
0
void Character::sendStatus()
{
    MessageOut attribMsg(GPMSG_PLAYER_ATTRIBUTE_CHANGE);
    for (std::set<size_t>::const_iterator i = mModifiedAttributes.begin(),
         i_end = mModifiedAttributes.end(); i != i_end; ++i)
    {
        int attr = *i;
        attribMsg.writeInt16(attr);
        attribMsg.writeInt32(getAttribute(attr) * 256);
        attribMsg.writeInt32(getModifiedAttribute(attr) * 256);
    }
    if (attribMsg.getLength() > 2) gameHandler->sendTo(this, attribMsg);
    mModifiedAttributes.clear();

    MessageOut expMsg(GPMSG_PLAYER_EXP_CHANGE);
    for (std::set<size_t>::const_iterator i = mModifiedExperience.begin(),
         i_end = mModifiedExperience.end(); i != i_end; ++i)
    {
        int skill = *i;
        expMsg.writeInt16(skill);
        expMsg.writeInt32(getExpGot(skill));
        expMsg.writeInt32(getExpNeeded(skill));
        expMsg.writeInt16(levelForExp(getExperience(skill)));
    }
    if (expMsg.getLength() > 2) gameHandler->sendTo(this, expMsg);
    mModifiedExperience.clear();

    if (mUpdateLevelProgress)
    {
        mUpdateLevelProgress = false;
        MessageOut progressMessage(GPMSG_LEVEL_PROGRESS);
        progressMessage.writeInt8(mLevelProgress);
        gameHandler->sendTo(this, progressMessage);
    }
}
Esempio n. 3
0
bool Attribute::add(unsigned short duration, double value,
                    unsigned layer, int id)
{
    assert(mMods.size() > layer);
    LOG_DEBUG("Adding modifier to attribute with duration " << duration
              << ", value " << value
              << ", at layer " << layer
              << " with id " << id);
    if (mMods.at(layer)->add(duration, value,
                            (layer ? mMods.at(layer - 1)->getCachedModifiedValue()
                                   : mBase)
                            , id))
    {
        while (++layer < mMods.size())
        {
            if (!mMods.at(layer)->recalculateModifiedValue(
                       mMods.at(layer - 1)->getCachedModifiedValue()))
            {
                LOG_DEBUG("Modifier added, but modified value not changed.");
                return false;
            }
        }
        LOG_DEBUG("Modifier added. Base value: " << mBase << ", new modified "
                  "value: " << getModifiedAttribute() << ".");
        return true;
    }
    LOG_DEBUG("Failed to add modifier!");
    return false;
}
Esempio n. 4
0
void Character::flagAttribute(int attr)
{
    // Inform the client of this attribute modification.
    accountHandler->updateAttributes(getDatabaseID(), attr,
                                     getAttribute(attr),
                                     getModifiedAttribute(attr));
    mModifiedAttributes.insert(attr);
}
Esempio n. 5
0
void Monster::processAttack()
{
    if (!mTarget)
    {
        setAction(STAND);
        return;
    }

    if (!mCurrentAttack)
        return;

    mAttackTimeout.set(mCurrentAttack->aftDelay
                                 + mCurrentAttack->preDelay);

    float damageFactor = mCurrentAttack->damageFactor;

    Damage dmg;
    dmg.skill   = 0;
    dmg.base    = getModifiedAttribute(MOB_ATTR_PHY_ATK_MIN) * damageFactor;
    dmg.delta   = getModifiedAttribute(MOB_ATTR_PHY_ATK_DELTA) * damageFactor;
    dmg.cth     = getModifiedAttribute(ATTR_ACCURACY);
    dmg.element = mCurrentAttack->element;
    dmg.range   = mCurrentAttack->range;

    int hit = performAttack(mTarget, dmg);

    if (!mCurrentAttack->scriptEvent.empty() && hit > -1)
    {
        Script::Ref function = mSpecy->getEventCallback(mCurrentAttack->scriptEvent);
        if (function.isValid())
        {
            Script *script = ScriptManager::currentState();
            script->setMap(getMap());
            script->prepare(function);
            script->push(this);
            script->push(mTarget);
            script->push(hit);
            script->execute();
        }
    }
}
Esempio n. 6
0
void Character::processAttacks()
{
    // Ticks attacks even when not attacking to permit cooldowns and warmups.
    std::list<AutoAttack> attacksReady;
    mAutoAttacks.tick(&attacksReady);

    if (mAction != ATTACK || !mTarget)
    {
        mAutoAttacks.stop();
        return;
    }

    // Deal with the ATTACK action.

    // Install default bare knuckle attack if no attacks were added from config.
    // TODO: Get this from configuration.
    if (!mAutoAttacks.getAutoAttacksNumber())
    {
        int damageBase = getModifiedAttribute(ATTR_STR);
        int damageDelta = damageBase / 2;
        Damage knuckleDamage;
        knuckleDamage.skill = skillManager->getDefaultSkillId();
        knuckleDamage.base = damageBase;
        knuckleDamage.delta = damageDelta;
        knuckleDamage.cth = 2;
        knuckleDamage.element = ELEMENT_NEUTRAL;
        knuckleDamage.type = DAMAGE_PHYSICAL;
        knuckleDamage.range = (getSize() < DEFAULT_TILE_LENGTH) ?
                    DEFAULT_TILE_LENGTH : getSize();

        AutoAttack knuckleAttack(knuckleDamage, 7, 3);
        mAutoAttacks.add(knuckleAttack);
    }

    if (attacksReady.empty())
    {
        if (!mAutoAttacks.areActive())
            mAutoAttacks.start();
    }
    else
    {
        // Performs all ready attacks.
        for (std::list<AutoAttack>::iterator it = attacksReady.begin();
             it != attacksReady.end(); ++it)
        {
            performAttack(mTarget, it->getDamage());
        }
    }
}
Esempio n. 7
0
void Character::recalculateBaseAttribute(unsigned attr)
{
    // `attr' may or may not have changed. Recalculate the base value.
    LOG_DEBUG("Received update attribute recalculation request at Character "
              "for " << attr << ".");
    if (!mAttributes.count(attr))
        return;

    if (attr == ATTR_STR && mKnuckleAttackInfo)
    {
        // TODO: dehardcode this
        Damage &knuckleDamage = mKnuckleAttackInfo->getDamage();
        knuckleDamage.base = getModifiedAttribute(ATTR_STR);
        knuckleDamage.delta = knuckleDamage.base / 2;
    }
    Being::recalculateBaseAttribute(attr);

}
Esempio n. 8
0
uint16_t Player::getModifiedMinDamage() const
{
	uint16_t inventoryMinDamage = getModifiedAttribute( inventory, this, 0, &getItemMinDamageHelper, &getSpellMinDamageHelper, NON_NULLABLE_ATTRIBUTE_MIN );
	return inventoryMinDamage;
}
Esempio n. 9
0
uint16_t Player::getModifiedSpellEffectElementModifierPoints( ElementType::ElementType elementType ) const
{
	return getModifiedAttribute( elementType, inventory, this, getSpellEffectElementModifierPoints( elementType ) + getSpellEffectAllModifierPoints(), &getItemSpellEffectElementModifierPointsHelper, &getSpellSpellEffectElementModifierPointsHelper, NULLABLE_ATTRIBUTE_MIN ) + StatsSystem::getStatsSystem()->calculateSpellEffectElementModifierPoints( elementType, this );
}
Esempio n. 10
0
uint16_t Player::getModifiedSpellCriticalModifierPoints() const
{
	return getModifiedAttribute( inventory, this, getSpellCriticalModifierPoints(), &getItemSpellCriticalModifierPointsHelper, &getSpellSpellCriticalModifierPointsHelper, NULLABLE_ATTRIBUTE_MIN ) + StatsSystem::getStatsSystem()->calculateSpellCriticalModifierPoints( this );
}
Esempio n. 11
0
uint16_t Player::getModifiedFatigueRegen() const
{
	return getModifiedAttribute( inventory, this, getFatigueRegen(), &getItemFatigueRegenHelper, &getSpellFatigueRegenHelper, NULLABLE_ATTRIBUTE_MIN );
}
Esempio n. 12
0
uint16_t Player::getModifiedArmor() const
{
	return getModifiedAttribute( inventory, this, getArmor(), &getItemArmorHelper, &getSpellArmorHelper, NULLABLE_ATTRIBUTE_MIN ) + StatsSystem::getStatsSystem()->calculateDamageReductionPoints( this );
}
Esempio n. 13
0
uint16_t Player::getModifiedMaxDamage() const
{
	uint16_t inventoryMaxDamage = getModifiedAttribute( inventory, this, 0, &getItemMaxDamageHelper, &getSpellMaxDamageHelper, getModifiedMinDamage() );
	return inventoryMaxDamage;
}
Esempio n. 14
0
uint16_t Player::getModifiedMaxMana() const
{
	return getModifiedAttribute( inventory, this, getMaxMana(), &getItemManaHelper, &getSpellManaHelper, NULLABLE_ATTRIBUTE_MIN );
}
Esempio n. 15
0
uint16_t Player::getModifiedMaxHealth() const
{
	return getModifiedAttribute( inventory, this, getMaxHealth(), &getItemHealthHelper, &getSpellHealthHelper, NON_NULLABLE_ATTRIBUTE_MIN );
}
Esempio n. 16
0
uint16_t Player::getModifiedWisdom() const
{
	return getModifiedAttribute( inventory, this, getWisdom(), &getItemWisdomHelper, &getSpellWisdomHelper, NON_NULLABLE_ATTRIBUTE_MIN );
}
Esempio n. 17
0
uint16_t Player::getModifiedIntellect() const
{
	return getModifiedAttribute( inventory, this, getIntellect(), &getItemIntellectHelper, &getSpellIntellectHelper, NON_NULLABLE_ATTRIBUTE_MIN );
}
Esempio n. 18
0
uint16_t Player::getModifiedVitality() const
{
	return getModifiedAttribute( inventory, this, getVitality(), &getItemVitalityHelper, &getSpellVitalityHelper, NON_NULLABLE_ATTRIBUTE_MIN );
}