• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

C++ How to make critical hit works for wands damage?

KingKing

Member
Joined
Nov 6, 2019
Messages
33
Reaction score
6
Hello,

I see that critical hit only work for melee weapons and distance weapons but not for wands.
I want to edit the source to make it work for wands also.
This is my weapons.cpp

Look to this lines ( melee weapon has the line of critical damage )
C++:
int32_t WeaponMelee::getWeaponDamage(const Player* player, const Creature*, const Item* item, bool maxDamage /*= false*/) const
{
    int32_t attackSkill = player->getWeaponSkill(item), attackValue = std::max((int32_t)0,
        (int32_t(item->getAttack() + item->getExtraAttack()) - item->getElementDamage()));
    float attackFactor = player->getAttackFactor();

    double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
    if(player->getCriticalHitChance() + g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE) >= random_range(1, 100))
    {
        maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
        player->sendCritical();
    }

    Vocation* vocation = player->getVocation();
    if(vocation && vocation->getMultiplier(MULTIPLIER_MELEE) != 1.0)
        maxValue *= vocation->getMultiplier(MULTIPLIER_MELEE);

    int32_t ret = (int32_t)std::floor(maxValue);
    if(maxDamage)
        return -ret;

    return -random_range(0, ret, DISTRO_NORMAL);
}

Look at this lines ( wand weapon ) no have the critical line like melee weapon
C++:
int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
    float multiplier = 1.0f;
    if(Vocation* vocation = player->getVocation())
        multiplier = vocation->getMultiplier(MULTIPLIER_WAND);
   
    int32_t maxValue = (int32_t)(maxChange * multiplier);
    if(maxDamage)
    {
        player->sendCritical();
        return -maxValue;
    }

    int32_t minValue = (int32_t)(minChange * multiplier);
    return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}

I just need help to make wands work with critical hit also.
 
Hello,

I see that critical hit only work for melee weapons and distance weapons but not for wands.
I want to edit the source to make it work for wands also.
This is my weapons.cpp

Look to this lines ( melee weapon has the line of critical damage )
C++:
int32_t WeaponMelee::getWeaponDamage(const Player* player, const Creature*, const Item* item, bool maxDamage /*= false*/) const
{
    int32_t attackSkill = player->getWeaponSkill(item), attackValue = std::max((int32_t)0,
        (int32_t(item->getAttack() + item->getExtraAttack()) - item->getElementDamage()));
    float attackFactor = player->getAttackFactor();

    double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
    if(player->getCriticalHitChance() + g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE) >= random_range(1, 100))
    {
        maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
        player->sendCritical();
    }

    Vocation* vocation = player->getVocation();
    if(vocation && vocation->getMultiplier(MULTIPLIER_MELEE) != 1.0)
        maxValue *= vocation->getMultiplier(MULTIPLIER_MELEE);

    int32_t ret = (int32_t)std::floor(maxValue);
    if(maxDamage)
        return -ret;

    return -random_range(0, ret, DISTRO_NORMAL);
}

Look at this lines ( wand weapon ) no have the critical line like melee weapon
C++:
int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
    float multiplier = 1.0f;
    if(Vocation* vocation = player->getVocation())
        multiplier = vocation->getMultiplier(MULTIPLIER_WAND);
 
    int32_t maxValue = (int32_t)(maxChange * multiplier);
    if(maxDamage)
    {
        player->sendCritical();
        return -maxValue;
    }

    int32_t minValue = (int32_t)(minChange * multiplier);
    return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}

I just need help to make wands work with critical hit also.
try this not tested
C++:
int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
    float multiplier = 1.0f;
    if(Vocation* vocation = player->getVocation())
        multiplier = vocation->getMultiplier(MULTIPLIER_WAND);

    int32_t maxValue = (int32_t)(maxChange * multiplier);
    if(maxDamage)
    {
    ///    player->sendCritical();
        return -maxValue;
    }
    double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
    if(player->getCriticalHitChance() + g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE) >= random_range(1, 100))
    {
        maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
        player->sendCritical();
    }

    int32_t minValue = (int32_t)(minChange * multiplier);
    return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}
 
try this not tested
C++:
int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
    float multiplier = 1.0f;
    if(Vocation* vocation = player->getVocation())
        multiplier = vocation->getMultiplier(MULTIPLIER_WAND);

    int32_t maxValue = (int32_t)(maxChange * multiplier);
    if(maxDamage)
    {
    ///    player->sendCritical();
        return -maxValue;
    }
    double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
    if(player->getCriticalHitChance() + g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE) >= random_range(1, 100))
    {
        maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
        player->sendCritical();
    }

    int32_t minValue = (int32_t)(minChange * multiplier);
    return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}

I got these errors

Code:
Error    1    error C2371: 'maxValue' : redefinition; different basic types   \weapons.cpp    981    1    tfs

Error    2    error C2065: 'attackSkill' : undeclared identifier   \weapons.cpp    981    1    tfs

Error    3    error C2065: 'attackValue' : undeclared identifier   \weapons.cpp    981    1    tfs

Error    4    error C2065: 'attackFactor' : undeclared identifier   \weapons.cpp    981    1    tfs

    5    IntelliSense: identifier "attackSkill" is undefined    \weapons.cpp    981    71    tfs

    6    IntelliSense: identifier "attackValue" is undefined   \weapons.cpp    981    84    tfs

    7    IntelliSense: identifier "attackFactor" is undefined   \weapons.cpp    981    97    tfs
 
I made a change to lines

From:

C++:
int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
    float multiplier = 1.0f;
    if(Vocation* vocation = player->getVocation())
        multiplier = vocation->getMultiplier(MULTIPLIER_WAND);

    int32_t maxValue = (int32_t)(maxChange * multiplier);
    if(maxDamage)
    {
    ///    player->sendCritical();
        return -maxValue;
    }
    double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
    if(player->getCriticalHitChance() + g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE) >= random_range(1, 100))
    {
        maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
        player->sendCritical();
    }

    int32_t minValue = (int32_t)(minChange * multiplier);
    return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}

To:

C++:
int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
    float multiplier = 1.0f;

    double maxValue = (int32_t)(maxChange * multiplier);
    if(player->getCriticalHitChance() + g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE) >= random_range(1, 100))
    {
        maxValue *= g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL);
        player->sendCritical();
    }

    Vocation* vocation = player->getVocation();
    if(vocation && vocation->getMultiplier(MULTIPLIER_WAND) != 1.0)
        maxValue *= vocation->getMultiplier(MULTIPLIER_WAND);

    int32_t ret = (int32_t)std::floor(maxValue);
    if(maxDamage)
        return -ret;

    int32_t minValue = (int32_t)(minChange * multiplier);
    return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}

It worked for wands which is working by default like this one
Code:
<wand id="8920" level="37" mana="13" min="55" max="75" type="energy" swing="true" event="function" value="default">
But not working for wands which is working with script like this one
Code:
<wand id="7426" level="1" mana="5" swing="true" event="script" value="staff.lua">

I don't know how to fix it, any help?
 
Some codes just execute on C++ OR on Lua scripts. I think thats the case. You have to duplicate the system to the staff.lua script or make it execute on C++ AND on Lua script.
 
I made a change to lines

From:

C++:
int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
    float multiplier = 1.0f;
    if(Vocation* vocation = player->getVocation())
        multiplier = vocation->getMultiplier(MULTIPLIER_WAND);

    int32_t maxValue = (int32_t)(maxChange * multiplier);
    if(maxDamage)
    {
    ///    player->sendCritical();
        return -maxValue;
    }
    double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
    if(player->getCriticalHitChance() + g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE) >= random_range(1, 100))
    {
        maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
        player->sendCritical();
    }

    int32_t minValue = (int32_t)(minChange * multiplier);
    return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}

To:

C++:
int32_t WeaponWand::getWeaponDamage(const Player* player, const Creature*, const Item*, bool maxDamage /* = false*/) const
{
    float multiplier = 1.0f;

    double maxValue = (int32_t)(maxChange * multiplier);
    if(player->getCriticalHitChance() + g_config.getNumber(ConfigManager::CRITICAL_HIT_CHANCE) >= random_range(1, 100))
    {
        maxValue *= g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL);
        player->sendCritical();
    }

    Vocation* vocation = player->getVocation();
    if(vocation && vocation->getMultiplier(MULTIPLIER_WAND) != 1.0)
        maxValue *= vocation->getMultiplier(MULTIPLIER_WAND);

    int32_t ret = (int32_t)std::floor(maxValue);
    if(maxDamage)
        return -ret;

    int32_t minValue = (int32_t)(minChange * multiplier);
    return random_range(-minValue, -maxValue, DISTRO_NORMAL);
}

It worked for wands which is working by default like this one
Code:
<wand id="8920" level="37" mana="13" min="55" max="75" type="energy" swing="true" event="function" value="default">
But not working for wands which is working with script like this one
Code:
<wand id="7426" level="1" mana="5" swing="true" event="script" value="staff.lua">

I don't know how to fix it, any help?
because getWeaponDamage can be called when the attack is default with min/max formula and only working with melee .
 
Hello @Togu

I still away from home, but here you are the script


I made some edits on mine to make it easier with config and check if you wear x weapons but when i tested it i found a problem.


i still searching for a solution for that.
 
Last edited:
Back
Top