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

[TFS 1.2] Need Critical hit system

Lopaskurwa

Active Member
Joined
Oct 6, 2017
Messages
873
Solutions
2
Reaction score
49
Hi
maybe someone have critical system script? That works like this, lets say you have "10 sword fighting you have 1% chance to hit critical hit", "20 sword fighting you have 2% chance to hit critical hit", "30 sword fighting you have 3% chance to hit critical hit" and etc and when you hit critical hit it sends some kind of magic effect and thats it.
 
Solution

Try this:

1. Create file critical_hit_system.lua in data\creaturescripts\scripts and add the following:

Lua:
local config = {
    magic_effect = 15, -- magic effect you want to send when critical hit lands
    damage_multiplier = 10 -- default damage * 10 = critical damage
}

function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if attacker == nil then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    if not attacker:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    local skill = attacker:getEffectiveSkillLevel(SKILL_SWORD)
    local chance = (skill...
Change skilllvl to skillLvl and test, please
I can't test :( I've just noticed that I used uppercase in one of them and lowercase in other..
If possible, tell me the error after that
Changed. Still not working. It doeesnt have any errors or warnings in console its just seems like it doesnt functional at all
 
Critical system perfect!
not is necesary a explication...
:oops:
Code:
local criticalDefaultChance = 5
local criticalDefaultDamage = 2

local weaponTypeToSkillType = {
    [WEAPON_SWORD] = function(p) return p:getEffectiveSkillLevel(SKILL_SWORD) end,
    [WEAPON_AXE] = function(p) return p:getEffectiveSkillLevel(SKILL_AXE) end,
    [WEAPON_CLUB] = function(p) return p:getEffectiveSkillLevel(SKILL_CLUB) end,
    [WEAPON_AMMO] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_DISTANCE] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_WAND] = function(p) return p:getMagicLevel() end
}

function getSkillByYouWeapon(player)
    local skillValue = 0
    local weapon = player:getSlotItem(CONST_SLOT_LEFT)
    if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
        skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
    else
        weapon = player:getSlotItem(CONST_SLOT_RIGHT)
        if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
            skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
        end
    end
    return skillValue
end

function onHealthChange(creature, attacker, pD, pT, sD, sT, origin)
    if isPlayer(attacker) then
        local skill = getSkillByYouWeapon(attacker)
        if math.random(100 + skill) <= (criticalDefaultChance + (skill / 2)) then
            if origin == ORIGIN_MELEE then
                creature:say("SKULLBASH!", TALKTYPE_MONSTER_SAY)
            elseif origin == ORIGIN_RANGED then
                creature:say("HEADSHOT!", TALKTYPE_MONSTER_SAY)
            end
            pD = pD * criticalDefaultDamage
        end
    end
    return pD, pT, sD, sT
end
 
Critical system perfect!
not is necesary a explication...
:oops:
Code:
local criticalDefaultChance = 5
local criticalDefaultDamage = 2

local weaponTypeToSkillType = {
    [WEAPON_SWORD] = function(p) return p:getEffectiveSkillLevel(SKILL_SWORD) end,
    [WEAPON_AXE] = function(p) return p:getEffectiveSkillLevel(SKILL_AXE) end,
    [WEAPON_CLUB] = function(p) return p:getEffectiveSkillLevel(SKILL_CLUB) end,
    [WEAPON_AMMO] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_DISTANCE] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_WAND] = function(p) return p:getMagicLevel() end
}

function getSkillByYouWeapon(player)
    local skillValue = 0
    local weapon = player:getSlotItem(CONST_SLOT_LEFT)
    if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
        skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
    else
        weapon = player:getSlotItem(CONST_SLOT_RIGHT)
        if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
            skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
        end
    end
    return skillValue
end

function onHealthChange(creature, attacker, pD, pT, sD, sT, origin)
    if isPlayer(attacker) then
        local skill = getSkillByYouWeapon(attacker)
        if math.random(100 + skill) <= (criticalDefaultChance + (skill / 2)) then
            if origin == ORIGIN_MELEE then
                creature:say("SKULLBASH!", TALKTYPE_MONSTER_SAY)
            elseif origin == ORIGIN_RANGED then
                creature:say("HEADSHOT!", TALKTYPE_MONSTER_SAY)
            end
            pD = pD * criticalDefaultDamage
        end
    end
    return pD, pT, sD, sT
end
Very nice..
Actually, I think you should also implement this on onManaChange, right? otherwise, the critical system will work only when a monster loses health (or a player loses health, but not player with manashield)

And also, I think he'll need to register the event on every creature of the server, and also in onLogin (so it will works with players aswell)
But very well detailed xD nice
 
Critical system perfect!
not is necesary a explication...
:oops:
Code:
local criticalDefaultChance = 5
local criticalDefaultDamage = 2

local weaponTypeToSkillType = {
    [WEAPON_SWORD] = function(p) return p:getEffectiveSkillLevel(SKILL_SWORD) end,
    [WEAPON_AXE] = function(p) return p:getEffectiveSkillLevel(SKILL_AXE) end,
    [WEAPON_CLUB] = function(p) return p:getEffectiveSkillLevel(SKILL_CLUB) end,
    [WEAPON_AMMO] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_DISTANCE] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_WAND] = function(p) return p:getMagicLevel() end
}

function getSkillByYouWeapon(player)
    local skillValue = 0
    local weapon = player:getSlotItem(CONST_SLOT_LEFT)
    if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
        skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
    else
        weapon = player:getSlotItem(CONST_SLOT_RIGHT)
        if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
            skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
        end
    end
    return skillValue
end

function onHealthChange(creature, attacker, pD, pT, sD, sT, origin)
    if isPlayer(attacker) then
        local skill = getSkillByYouWeapon(attacker)
        if math.random(100 + skill) <= (criticalDefaultChance + (skill / 2)) then
            if origin == ORIGIN_MELEE then
                creature:say("SKULLBASH!", TALKTYPE_MONSTER_SAY)
            elseif origin == ORIGIN_RANGED then
                creature:say("HEADSHOT!", TALKTYPE_MONSTER_SAY)
            end
            pD = pD * criticalDefaultDamage
        end
    end
    return pD, pT, sD, sT
end
Lul why it doesnt work for me?
 
Lul why it doesnt work for me?
I guess you aren't registering the event in login.lua and in every monster xml
if you register the event in login.lua (Creaturescript), it should work with players, but not with creatures (since the creatures are the ones which the health is changing), so you need to register the event in the monsters too... probrably there's a way to do it automatically, but I don't know for now (I'm not programming along TFS for long time ago, just check this forum from time to time)
 
for the players use login.lua and for the monster use
data/events/scripts/creature.lua - function onTargetCombat
md5svPCFQUip2XlmdXBjxQ.png

now use this script criticalSystem.lua:
Code:
local criticalDefaultChance = 5
local criticalDefaultDamage = 2

local weaponTypeToSkillType = {
    [WEAPON_SWORD] = function(p) return p:getEffectiveSkillLevel(SKILL_SWORD) end,
    [WEAPON_AXE] = function(p) return p:getEffectiveSkillLevel(SKILL_AXE) end,
    [WEAPON_CLUB] = function(p) return p:getEffectiveSkillLevel(SKILL_CLUB) end,
    [WEAPON_AMMO] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_DISTANCE] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_WAND] = function(p) return p:getMagicLevel() end
}

function getSkillByYouWeapon(player)
    local skillValue = 0
    local weapon = player:getSlotItem(CONST_SLOT_LEFT)
    if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
        skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
    else
        weapon = player:getSlotItem(CONST_SLOT_RIGHT)
        if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
            skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
        end
    end
    return skillValue
end

local function onChange(creature, attacker, damage, origin)
    local skill = getSkillByYouWeapon(attacker)
    if math.random(100 + skill) <= (criticalDefaultChance + (skill / 2)) then
        if origin == ORIGIN_MELEE then
            creature:say("SKULLBASH!", TALKTYPE_MONSTER_SAY)
        elseif origin == ORIGIN_RANGED then
            creature:say("HEADSHOT!", TALKTYPE_MONSTER_SAY)
        end
        damage = damage * criticalDefaultDamage
    end
    return damage
end

function onHealthChange(creature, attacker, pD, pT, sD, sT, origin)
    if isPlayer(attacker) then
        pD = onChange(creature, attacker, pD, origin)
    end
    return pD, pT, sD, sT
end

function onManaChange(creature, attacker, manaChange, origin)
    if isPlayer(attacker) then
        manaChange = onChange(creature, attacker, manaChange, origin)
    end
    return manaChange
end
in creaturescripts do register
8lhJrLZyQwK7JffyXQYuqg.png
 
for the players use login.lua and for the monster use
data/events/scripts/creature.lua - function onTargetCombat
md5svPCFQUip2XlmdXBjxQ.png

now use this script criticalSystem.lua:
Code:
local criticalDefaultChance = 5
local criticalDefaultDamage = 2

local weaponTypeToSkillType = {
    [WEAPON_SWORD] = function(p) return p:getEffectiveSkillLevel(SKILL_SWORD) end,
    [WEAPON_AXE] = function(p) return p:getEffectiveSkillLevel(SKILL_AXE) end,
    [WEAPON_CLUB] = function(p) return p:getEffectiveSkillLevel(SKILL_CLUB) end,
    [WEAPON_AMMO] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_DISTANCE] = function(p) return p:getEffectiveSkillLevel(SKILL_DISTANCE) end,
    [WEAPON_WAND] = function(p) return p:getMagicLevel() end
}

function getSkillByYouWeapon(player)
    local skillValue = 0
    local weapon = player:getSlotItem(CONST_SLOT_LEFT)
    if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
        skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
    else
        weapon = player:getSlotItem(CONST_SLOT_RIGHT)
        if weapon and ItemType(weapon:getId()):getWeaponType() > 0 then
            skillValue = weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()] and weaponTypeToSkillType[ItemType(weapon:getId()):getWeaponType()](player) or 0
        end
    end
    return skillValue
end

local function onChange(creature, attacker, damage, origin)
    local skill = getSkillByYouWeapon(attacker)
    if math.random(100 + skill) <= (criticalDefaultChance + (skill / 2)) then
        if origin == ORIGIN_MELEE then
            creature:say("SKULLBASH!", TALKTYPE_MONSTER_SAY)
        elseif origin == ORIGIN_RANGED then
            creature:say("HEADSHOT!", TALKTYPE_MONSTER_SAY)
        end
        damage = damage * criticalDefaultDamage
    end
    return damage
end

function onHealthChange(creature, attacker, pD, pT, sD, sT, origin)
    if isPlayer(attacker) then
        pD = onChange(creature, attacker, pD, origin)
    end
    return pD, pT, sD, sT
end

function onManaChange(creature, attacker, manaChange, origin)
    if isPlayer(attacker) then
        manaChange = onChange(creature, attacker, manaChange, origin)
    end
    return manaChange
end
in creaturescripts do register
8lhJrLZyQwK7JffyXQYuqg.png
Still the same or i'm just stupid and missing something.
data/creaturescript
Code:
    <event type="healthchange" name="CriticalSystemHp" script="criticalSystem.lua" />
    <event type="manachange" name="CriticalSystemMp" script="criticalSystem.lua" />
data/creaturescript/script
I made criticalSystem.lua with critical system code
Then
data/event/script/creature.lua
Code:
function Creature:onChangeOutfit(outfit)
    return true
end

function Creature:onAreaCombat(tile, isAggressive)
    return true
end

function Creature:onTargetCombat(target)
if not self then
return true
end

if self:getIsCastleDefender(target) then
return false
end

if target:isMonster() then
target:registerEvent('CriticalSystem')
end
 

Try this:

1. Create file critical_hit_system.lua in data\creaturescripts\scripts and add the following:

Lua:
local config = {
    magic_effect = 15, -- magic effect you want to send when critical hit lands
    damage_multiplier = 10 -- default damage * 10 = critical damage
}

function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if attacker == nil then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    if not attacker:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    local skill = attacker:getEffectiveSkillLevel(SKILL_SWORD)
    local chance = (skill * 0.1)
 
    if math.random(100) <= chance then
        attacker:getPosition():sendMagicEffect(config.magic_effect)
        return primaryDamage * config.damage_multiplier, primaryType, secondaryDamage, secondaryType
    end
     
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

2. In data\creaturescripts\creaturescripts.xml add this line at the top, inside <creaturescripts>

Lua:
<event type="healthchange" name="criticalHitSystemX" script="critical_hit_system.lua"/>

3. In data\creaturescripts\scripts\login.lua under player:registerEvent("PlayerDeath"), add the following line:

Lua:
player:registerEvent("criticalHitSystemX")

4. This step is optional, and only required if you want to make this work with monsters - you will have to add that code for each monster that you want the critical hit system to work with. Under </flags>, add the following:

XML:
<script>
        <event name="criticalHitSystemX"/>
</script>
 
Solution
Try this:

1. Create file critical_hit_system.lua in data\creaturescripts\scripts and add the following:

Lua:
local config = {
    magic_effect = 15, -- magic effect you want to send when critical hit lands
    damage_multiplier = 10 -- default damage * 10 = critical damage
}

function onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if attacker == nil then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    if not attacker:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
    local skill = attacker:getEffectiveSkillLevel(SKILL_SWORD)
    local chance = (skill * 0.1)
 
    if math.random(100) <= chance then
        attacker:getPosition():sendMagicEffect(config.magic_effect)
        return primaryDamage * config.damage_multiplier, primaryType, secondaryDamage, secondaryType
    end
    
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

2. In data\creaturescripts\creaturescripts.xml add this line at the top, inside <creaturescripts>

Lua:
<event type="healthchange" name="criticalHitSystemX" script="critical_hit_system.lua"/>

3. In data\creaturescripts\scripts\login.lua under player:registerEvent("PlayerDeath"), add the following line:

Lua:
player:registerEvent("criticalHitSystemX")

4. This step is optional, and only required if you want to make this work with monsters - you will have to add that code for each monster that you want the critical hit system to work with. Under </flags>, add the following:

XML:
<script>
        <event name="criticalHitSystemX"/>
</script>
Probably this script works because it sends effect, so thats means it works. As i understand it gives more chance to hit critical if i have more SKILL_SWORD, right? And how to send magic_effect to enemy not to me?
 
Probably this script works because it sends effect, so thats means it works. As i understand it gives more chance to hit critical if i have more SKILL_SWORD, right? And how to send magic_effect to enemy not to me?

Yes, the higher the sword skill level, the higher the chance to land critical hit. You said, skill level 10 = 1%, skill level 20 = 2% and that's how it's made

To send magic effect to enemy just change this line:
Lua:
attacker:getPosition():sendMagicEffect(config.magic_effect)

To this:
Lua:
creature:getPosition():sendMagicEffect(config.magic_effect)
 
Yes, the higher the sword skill level, the higher the chance to land critical hit. You said, skill level 10 = 1%, skill level 20 = 2% and that's how it's made

To send magic effect to enemy just change this line:
Lua:
attacker:getPosition():sendMagicEffect(config.magic_effect)

To this:
Lua:
creature:getPosition():sendMagicEffect(config.magic_effect)
Well thank u very much :)
 
Back
Top