• 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!

Critical system

Kutomi9999

New Member
Joined
Oct 28, 2017
Messages
5
Reaction score
0
Hi I want to create a Critical Skill. That skill will be replaced with AXE SKILL
If axe skill reach 100 crit chance will be 100% thats all what I need to do
So.. in weapon.cpp I just do that
WeaponMelee -> Wklejka #3289588 – Wklej.org this script is working only whem Im using a weapon with axe atribute

FIST -> Wklejka #3289586 – Wklej.org that script is working

this is my weapon.cpp
Wklejka #3289596 – Wklej.org

ohh.. that scripts works but if I have an weapon like this:
weapon.xml -> <melee id="2450" level="60" event="script" value="weapon.lua"/>
weapon.lua -> Wklejka #3289647 – Wklej.org
it doesnt work
 
Last edited:
Solution
I forgot that monsters can go through it too. So before we we check AXE_SKILL we need to make sure were working with player, so

C++:
if (attacker && attacker->getPlayer())
{
    Player* player = attacker->getPlayer();
    <crit function>

}

Otherwise if it try to read AXE_SKILL from monster object, the server will crash.


To make sure the dmg is coming from weapon you need to trace damage from begining (some getWeaponDmg function) add there bool meleeDmg = true and follow the dmg to the
combatChangeHealth(CombatType_t combatType, Creature* attacker, Creature* target, int32_t healthChange, MagicEffect_t hitEffect/* = MAGIC_EFFECT_UNKNOWN*/, TextColor_t hitColor/* = TEXTCOLOR_UNKNOWN*/, bool force/* = false*/) func. In...
You are checking only dmg coming from melee weapons.
The combat is some kind of magic damage (but player see it as normal melee)



To checkout every dmg you need to get into another function.
Do the check for critical chance in combatchangehealth method in game.cpp file. Also add the dmg multiplier there.
 
Well, you have really interesting function there. May I ask what version is it?

As you can read there is main IF function if(healthChange > 0). We are interested in negative value of healthChange since its the damage, so we go into else brackets.

After if(damage != 0), we can start to modifty the damage. You should put there your critical function

C++:
uint32_t critx = attacker->getSkill(SKILL_AXE, SKILL_LEVEL); //uint32_t is too big, since our number will be always in range 0-100, but anyway I think it can be ignored, wont make any change :D
if (random_range(1, 100) <= critx) //use that random function if it works for you, but I used to always use the uniform_random(int,int) func on tfs

   {                       
           //maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));   // you have powered the damage instead of multiplying? Was that intentional?
           damage =* g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL); // damage = damage * CRITICAL_HIT_MUL
           target->sendCritical(); // idk what is this func? crit dmg animation? should be sent to target then
   }

Should be something like this. Keep in mind it would work for every kind of dmg, melee, spells etc. To separate them, you would need to trace the source of damage and select it somehow where it come from (weapon or spell).


You also have there some damage changer based on fishing skill that is interesting.
 
Something is wrong with 7th line
probably it should be something like this but I need to change the value but I really dont know what exactly should I change
C++:
    int32_t attackSkill = player->getWeaponSkill(item);
    int32_t attackValue = std::max((int32_t)0, (int32_t(item->getAttack() + item->getExtraAttack()) - elementDamage));
    float attackFactor = player->getAttackFactor();
double maxValue = Weapons::getMaxWeaponDamage(player->getLevel(), attackSkill, attackValue, attackFactor);
Player* player = attacker->getPlayer();
  uint32_t critx = player->getSkill(SKILL_AXE, SKILL_LEVEL);
if (random_range(1, 100) <= critx)
          {     
        maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));
player->sendCritical();
}

C++:
Player* player = attacker->getPlayer();
        uint32_t critx = player->getSkill(SKILL_AXE, SKILL_LEVEL); //uint32_t is too big, since our number will be always in range 0-100, but anyway I think it can be ignored, wont make any change :D
        if (random_range(1, 100) <= critx) //use that random function if it works for you, but I used to always use the uniform_random(int,int) func on tfs
        {                 
           //maxValue = std::pow(maxValue, g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL));   // you have powered the damage instead of multiplying? Was that intentional?
           damage *= g_config.getDouble(ConfigManager::CRITICAL_HIT_MUL); // damage = damage * CRITICAL_HIT_MUL
           player->sendCritical(); // idk what is this func? crit dmg animation? should be sent to target then
         }

or maybe should we write a lua script that check if player is using an weapon with physical damage and put into this code my critical skill check ?
 
Last edited:
I forgot that monsters can go through it too. So before we we check AXE_SKILL we need to make sure were working with player, so

C++:
if (attacker && attacker->getPlayer())
{
    Player* player = attacker->getPlayer();
    <crit function>

}

Otherwise if it try to read AXE_SKILL from monster object, the server will crash.


To make sure the dmg is coming from weapon you need to trace damage from begining (some getWeaponDmg function) add there bool meleeDmg = true and follow the dmg to the
combatChangeHealth(CombatType_t combatType, Creature* attacker, Creature* target, int32_t healthChange, MagicEffect_t hitEffect/* = MAGIC_EFFECT_UNKNOWN*/, TextColor_t hitColor/* = TEXTCOLOR_UNKNOWN*/, bool force/* = false*/) func. In the end we should have this function with new argument meleeDmg. Thats the way I see it. In newer tfs its easier, since there is complete dmg object (dmg,type,value and shit), where you can simply add that bool.

Anyway I think there are more option to do it, but its up to you programmer :)
 
Solution
Back
Top