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

Lua Dodge system for TFS 1.3

Icaraii

Well-Known Member
Joined
Jan 5, 2020
Messages
469
Solutions
1
Reaction score
58
Hello guys,

Can anyone make a dodge system with this things:

  • Dodge means miss damage
  • Dodge will work with % of happening or not
  • The chance for the dodge happening will vary from item to item and not every item will have a % of dodge, that means the script need to be structured in a way that it's something like this:
Item id = 1111 = 30% chance of dodge happen
item id = 2222 = 5% chance of dodge happen
That means that all itens id 1111 will have a chance of 30% of dodge happening when they are equipped.

It can be lua or revscript.

I did found a lot of dodge system, but they did not miss damage, they just reduce the amount of damage the player received. Also I found dodge systems that the player needed to use a stone at the item to apply dodge by lvl, varing from 1 to 100 and those dodge systems ain't what I need.
 
Solution
Seems to pop up every once in awhile, so figured I'd post all of the fixes and updates in 1 spot.

Lua:
local dodgeStorage = 45001
local config = {
 -- [itemid] -- Dodge must be a whole number out of 10000. | 1000 = 10.00% | 2 = 00.02% 
    [111111] = {dodgePercent = 5, slot = "head"},
    [111111] = {dodgePercent = 5, slot = "necklace"},
    [111111] = {dodgePercent = 5, slot = "backpack"},
    [111111] = {dodgePercent = 5, slot = "armor"},
    [111111] = {dodgePercent = 5, slot = "hand"}, -- weapon or shield is 'hand'
    [111111] = {dodgePercent = 5, slot = "legs"},
    [111111] = {dodgePercent = 5, slot = "feet"},
    [111111] = {dodgePercent = 5, slot = "ring"},
    [111111] = {dodgePercent = 5, slot = "ammo"}
}

-- Don't touch under here.

-- Equip...
Hello guys,

Can anyone make a dodge system with this things:

  • Dodge means miss damage
  • Dodge will work with % of happening or not
  • The chance for the dodge happening will vary from item to item and not every item will have a % of dodge, that means the script need to be structured in a way that it's something like this:
Item id = 1111 = 30% chance of dodge happen
item id = 2222 = 5% chance of dodge happen
That means that all itens id 1111 will have a chance of 30% of dodge happening when they are equipped.

It can be lua or revscript.

I did found a lot of dodge system, but they did not miss damage, they just reduce the amount of damage the player received. Also I found dodge systems that the player needed to use a stone at the item to apply dodge by lvl, varing from 1 to 100 and those dodge systems ain't what I need.
Untested.

It's revscript.
Lua:
local dodgeStorage = 45001
local config = {
 -- [itemid] -- Dodge must be a whole number out of 10000. | 1000 = 10.00% | 2 = 00.02% 
    [111111] = {dodgePercent = 5, slot = "head"},
    [111111] = {dodgePercent = 5, slot = "necklace"},
    [111111] = {dodgePercent = 5, slot = "backpack"},
    [111111] = {dodgePercent = 5, slot = "armor"},
    [111111] = {dodgePercent = 5, slot = "hand"}, -- weapon or shield is 'hand'
    [111111] = {dodgePercent = 5, slot = "legs"},
    [111111] = {dodgePercent = 5, slot = "feet"},
    [111111] = {dodgePercent = 5, slot = "ring"},
    [111111] = {dodgePercent = 5, slot = "ammo"}
}

-- Don't touch under here.

-- Equip ------------------------------------------------------------------------------
local dodgeOnEquip = MoveEvent()

function dodgeOnEquip.onEquip(player, item, slot, isCheck)
    if not isCheck then
        local itemId = item:getId()
        if config[itemId] then
            local newValue = player:getStorageValue(dodgeStorage) + config[slotItem].dodgePercent
            player:setStorageValue(dodgeStorage, newValue)
        end
    end
    return true
end

for itemId, _ in pairs(config) do
    dodgeOnEquip:slot(config[itemId].slot)
    dodgeOnEquip:id(itemId)
end
dodgeOnEquip:register()

-- DeEquip ----------------------------------------------------------------------------
local dodgeOnDeEquip = MoveEvent()

function dodgeOnDeEquip.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        local itemId = item:getId()
        if config[itemId] then
            local newValue = player:getStorageValue(dodgeStorage) - config[slotItem].dodgePercent
            player:setStorageValue(dodgeStorage, newValue)
        end
    end
    return true
end

for itemId, _ in pairs(config) do
    dodgeOnDeEquip:slot(config[itemId].slot)
    dodgeOnDeEquip:id(itemId)
end
dodgeOnDeEquip:register()

-- Health Change ----------------------------------------------------------------------
local dodgeHealthChange = CreatureEvent("onHealthChange_dodgeChance")

function dodgeHealthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
    local storageValue = creature:getStorageValue(dodgeStorage)
    local rand = math.random(10000)
    if rand <= storageValue then
        primaryDamage = 0
        secondaryDamage = 0
        creature:say("Dodged!", TALKTYPE_MONSTER_SAY)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

dodgeHealthChange:register()


-- Mana Change ------------------------------------------------------------------------
local dodgeManaChange = CreatureEvent("onManaChange_dodgeChance")

function dodgeManaChange.onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
    local storageValue = creature:getStorageValue(dodgeStorage)
    local rand = math.random(10000)
    if rand <= storageValue then
        primaryDamage = 0
        secondaryDamage = 0
        creature:say("Dodged!", TALKTYPE_MONSTER_SAY)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

dodgeManaChange:register()


-- Login ------------------------------------------------------------------------------
local function updateDodgeStorage(playerId)
    local player = Player(playerId)
    if player then
        local storageValue = 0
        local slotItem
        for i = 1, 10 do
            slotItem = player:getSlotItem(i)
            if slotItem then
                slotItem = slotItem:getId()
                if config[slotItem] then
                    storageValue = storageValue + config[slotItem].dodgePercent
                end
            end
        end        
        player:setStorageValue(dodgeStorage, storageValue)
    end
end

local loginEvent = CreatureEvent("onLogin_updateDodgeStorage")
loginEvent:type("login")

function loginEvent.onLogin(player)
    player:registerEvent("onHealthChange_dodgeChance")
    player:registerEvent("onManaChange_dodgeChance")
    addEvent(updateDodgeStorage, 100, player:getId()) -- slight delay, cuz of login jank
    return true
end

loginEvent:register()
 
Last edited:
Untested.

It's revscript.
Lua:
local dodgeStorage = 45001
local config = {
-- [itemid] -- Dodge must be a whole number out of 10000. | 1000 = 10.00% | 2 = 00.02%
    [111111] = {dodgePercent = 5, slot = "head"}
    [111111] = {dodgePercent = 5, slot = "necklace"}
    [111111] = {dodgePercent = 5, slot = "backpack"}
    [111111] = {dodgePercent = 5, slot = "armor"}
    [111111] = {dodgePercent = 5, slot = "hand"} -- weapon or shield is 'hand'
    [111111] = {dodgePercent = 5, slot = "legs"}
    [111111] = {dodgePercent = 5, slot = "feet"}
    [111111] = {dodgePercent = 5, slot = "ring"}
    [111111] = {dodgePercent = 5, slot = "ammo"}
}

-- Don't touch under here.

-- Equip ------------------------------------------------------------------------------
local dodgeOnEquip = MoveEvent()

function dodgeOnEquip.onEquip(player, item, slot, isCheck)
    if not isCheck then
        local itemId = item:getId()
        if config[itemId] then
            local newValue = player:getStorageValue(dodgeStorage) + config[slotItem].dodgePercent
            player:setStorageValue(dodgeStorage, newValue)
        end
    end
    return true
end

for itemId, _ in pairs(config) do
    dodgeOnEquip:slot(config[itemId].slot)
    dodgeOnEquip:id(itemId)
end
dodgeOnEquip:register()

-- DeEquip ----------------------------------------------------------------------------
local dodgeOnDeEquip = MoveEvent()

function dodgeOnDeEquip.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        local itemId = item:getId()
        if config[itemId] then
            local newValue = player:getStorageValue(dodgeStorage) - config[slotItem].dodgePercent
            player:setStorageValue(dodgeStorage, newValue)
        end
    end
    return true
end

for itemId, _ in pairs(config) do
    onEquip_Head:slot(config[itemId].slot)
    onEquip_Head:id(itemId)
end
dodgeOnDeEquip:register()

-- Health Change ----------------------------------------------------------------------
local dodgeHealthChange = CreatureEvent("onHealthChange_dodgeChance")

function dodgeHealthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
    local storageValue = player:getStorageValue(dodgeStorage)
    local rand = math.random(10000)
    if rand <= storageValue then
        primaryDamage = 0
        secondaryDamage = 0
        creature:say("Dodged!", TALKTYPE_MONSTER_SAY)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

dodgeHealthChange:register()


-- Mana Change ------------------------------------------------------------------------
local dodgeManaChange = CreatureEvent("onManaChange_dodgeChance")

function dodgeManaChange.onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
    local storageValue = player:getStorageValue(dodgeStorage)
    local rand = math.random(10000)
    if rand <= storageValue then
        primaryDamage = 0
        secondaryDamage = 0
        creature:say("Dodged!", TALKTYPE_MONSTER_SAY)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

dodgeManaChange:register()


-- Login ------------------------------------------------------------------------------
local function updateDodgeStorage(playerId)
    local player = Player(playerId)
    if player then
        local storageValue = 0
        local slotItem
        for i = 1, 10 do
            slotItem = player:getSlotItem(i)
            if slotItem then
                slotItem = slotItem:getId()
                if config[slotItem] then
                    storageValue = storageValue + config[slotItem].dodgePercent
                end
            end
        end       
        player:setStorageValue(dodgeStorage, storageValue)
    end
end

local loginEvent = CreatureEvent("onLogin_updateDodgeStorage")
loginEvent:type("login")

function loginEvent.onLogin(player)
    player:registerEvent("onHealthChange_dodgeChance")
    player:registerEvent("onManaChange_dodgeChance")
    addEvent(updateDodgeStorage, 100, player:getId()) -- slight delay, cuz of login jank
    return true
end

loginEvent:register()
Shouldn't this part be with ,?
local config = {
-- [itemid] -- Dodge must be a whole number out of 10000. | 1000 = 10.00% | 2 = 00.02%
[111111] = {dodgePercent = 5, slot = "head"},
[111111] = {dodgePercent = 5, slot = "necklace"},
[111111] = {dodgePercent = 5, slot = "backpack"},
[111111] = {dodgePercent = 5, slot = "armor"},
[111111] = {dodgePercent = 5, slot = "hand"}, -- weapon or shield is 'hand'
[111111] = {dodgePercent = 5, slot = "legs"},
[111111] = {dodgePercent = 5, slot = "feet"},
[111111] = {dodgePercent = 5, slot = "ring"},
[111111] = {dodgePercent = 5, slot = "ammo"},
}
Also I got this error on TFS:
Lua Script Error: [Scripts Interface]
C:\opentibia\data\scripts\dodgesystem.lua
C:\opentibia\data\scripts\dodgesystem.lua:52: attempt to index global 'onEquip_Head' (a nil value)
stack traceback:
[C]: in function '__index'
C:\opentibia\data\scripts\dodgesystem.lua:52: in main chunk
dodgesystem.lua [error]
 
When I use without " , " I get this error:

^ C:\opentibia\data\scripts\dodgesystem.lua:5: '}' expected (to close '{' at line 2) near '['

I put the " , " and test your edited post and when I receive damage with the itens with dodge, I got this error:

Lua Script Error: [Scripts Interface]
C:\opentibia\data\scripts\dodgesystem.lua:callback
C:\opentibia\data\scripts\dodgesystem.lua:64: attempt to index global 'player' (a nil value)
stack traceback:
[C]: in function '__index'
C:\opentibia\data\scripts\dodgesystem.lua:64: in function <C:\opentibia\data\scripts\dodgesystem.lua:60>
 
Untested.

It's revscript.
Lua:
local dodgeStorage = 45001
local config = {
-- [itemid] -- Dodge must be a whole number out of 10000. | 1000 = 10.00% | 2 = 00.02%
    [111111] = {dodgePercent = 5, slot = "head"},
    [111111] = {dodgePercent = 5, slot = "necklace"},
    [111111] = {dodgePercent = 5, slot = "backpack"},
    [111111] = {dodgePercent = 5, slot = "armor"},
    [111111] = {dodgePercent = 5, slot = "hand"}, -- weapon or shield is 'hand'
    [111111] = {dodgePercent = 5, slot = "legs"},
    [111111] = {dodgePercent = 5, slot = "feet"},
    [111111] = {dodgePercent = 5, slot = "ring"},
    [111111] = {dodgePercent = 5, slot = "ammo"}
}

-- Don't touch under here.

-- Equip ------------------------------------------------------------------------------
local dodgeOnEquip = MoveEvent()

function dodgeOnEquip.onEquip(player, item, slot, isCheck)
    if not isCheck then
        local itemId = item:getId()
        if config[itemId] then
            local newValue = player:getStorageValue(dodgeStorage) + config[slotItem].dodgePercent
            player:setStorageValue(dodgeStorage, newValue)
        end
    end
    return true
end

for itemId, _ in pairs(config) do
    dodgeOnEquip:slot(config[itemId].slot)
    dodgeOnEquip:id(itemId)
end
dodgeOnEquip:register()

-- DeEquip ----------------------------------------------------------------------------
local dodgeOnDeEquip = MoveEvent()

function dodgeOnDeEquip.onDeEquip(player, item, slot, isCheck)
    if not isCheck then
        local itemId = item:getId()
        if config[itemId] then
            local newValue = player:getStorageValue(dodgeStorage) - config[slotItem].dodgePercent
            player:setStorageValue(dodgeStorage, newValue)
        end
    end
    return true
end

for itemId, _ in pairs(config) do
    dodgeOnDeEquip:slot(config[itemId].slot)
    dodgeOnDeEquip:id(itemId)
end
dodgeOnDeEquip:register()

-- Health Change ----------------------------------------------------------------------
local dodgeHealthChange = CreatureEvent("onHealthChange_dodgeChance")

function dodgeHealthChange.onHealthChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
    local storageValue = creature:getStorageValue(dodgeStorage)
    local rand = math.random(10000)
    if rand <= storageValue then
        primaryDamage = 0
        secondaryDamage = 0
        creature:say("Dodged!", TALKTYPE_MONSTER_SAY)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

dodgeHealthChange:register()


-- Mana Change ------------------------------------------------------------------------
local dodgeManaChange = CreatureEvent("onManaChange_dodgeChance")

function dodgeManaChange.onManaChange(creature, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not creature:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
    local storageValue = creature:getStorageValue(dodgeStorage)
    local rand = math.random(10000)
    if rand <= storageValue then
        primaryDamage = 0
        secondaryDamage = 0
        creature:say("Dodged!", TALKTYPE_MONSTER_SAY)
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

dodgeManaChange:register()


-- Login ------------------------------------------------------------------------------
local function updateDodgeStorage(playerId)
    local player = Player(playerId)
    if player then
        local storageValue = 0
        local slotItem
        for i = 1, 10 do
            slotItem = player:getSlotItem(i)
            if slotItem then
                slotItem = slotItem:getId()
                if config[slotItem] then
                    storageValue = storageValue + config[slotItem].dodgePercent
                end
            end
        end       
        player:setStorageValue(dodgeStorage, storageValue)
    end
end

local loginEvent = CreatureEvent("onLogin_updateDodgeStorage")
loginEvent:type("login")

function loginEvent.onLogin(player)
    player:registerEvent("onHealthChange_dodgeChance")
    player:registerEvent("onManaChange_dodgeChance")
    addEvent(updateDodgeStorage, 100, player:getId()) -- slight delay, cuz of login jank
    return true
end

loginEvent:register()
It works perfectly, thanks so much.
 
Listen, I test the problem and it happens in my server when:

Player has full dodge set and log out, then log in and immediately take of the set, then player has dodge without set until he dies or relog
 
Guys, I found a problem, when another player uses exura sio into someone that is using a set with dodge, it has a chance to miss the heal, how can we fix it?
 
@Xikini, could you take a look at a problem in this script? When the player that has dodge chance heal himself, or get healed by someone else, it also get dodged. Is there a way to fix it? The dodge can happen when player heal with spell and potion aswel.
 
@Xikini, could you take a look at a problem in this script? When the player that has dodge chance heal himself, or get healed by someone else, it also get dodged. Is there a way to fix it? The dodge can happen when player heal with spell and potion aswel.
Use @zbizu's code for the healthChange
Use the code below for the manaChange
Lua:
    if primaryType == COMBAT_MANADRAIN and primaryDamage > 0 then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
 
Lua Script Error: [Scripts Interface]
C:\vcpkg\forgottenserver\data\scripts\dodge_system.lua:callback
C:\vcpkg\forgottenserver\data\scripts\dodge_system.lua:24: attempt to index a nil value
stack traceback:
[C]: in function '__index'
C:\vcpkg\forgottenserver\data\scripts\dodge_system.lua:24: in function <C:\vcpkg\forgottenserver\data\scripts\dodge_system.lua:20>
anyone can help fix this ?
 
Lua Script Error: [Scripts Interface]
C:\vcpkg\forgottenserver\data\scripts\dodge_system.lua:callback
C:\vcpkg\forgottenserver\data\scripts\dodge_system.lua:24: attempt to index a nil value
stack traceback:
[C]: in function '__index'
C:\vcpkg\forgottenserver\data\scripts\dodge_system.lua:24: in function <C:\vcpkg\forgottenserver\data\scripts\dodge_system.lua:20>
anyone can help fix this ?
in both onEquip and deEquip change config[slotItem].dodgePercent to config[itemId].dodgePercent
 
Back
Top