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

Action TFS 1.3 Small Dodge System ~ Revscript ~ EventCallback

Sarah Wesker

ค∂vαηcε รүηтαx ❤
Support Team
Joined
Mar 16, 2017
Messages
990
Solutions
98
Reaction score
1,017
Location
London
GitHub
MillhioreBT
I have created a small dodge system for you
Only work with oficial TFS 1.3

data/scripts/dodgesystem.lua

Lua:
-- Dodge System
local config = {
    -- Dodge Stone Setting
    maxDodgeChance = 5,
    maxDodgeAmount = 8,
    maxLevel = 10,

    -- Buy Dodge Stone Settings
    dodgeItemId = 11106,
    dodgeItemCount = 1,
    price = 100 * 10000, -- 100 Crystal Coins
    leverActionId = 9999
}

local function getPlayerDodge(player)
    local chance, amount = 0, 0
    for i = 0, 10 do
        local item = player:getSlotItem(i)
        if item then
            chance = chance + (item:getCustomAttribute("dodgeChance") or 0)
            amount = amount + (item:getCustomAttribute("dodgeAmount") or 0)
        end
    end
    return math.min(chance, 100), math.min(amount / 100, 1)
end

local function getItemLevel(item)
    local chance = (item:getCustomAttribute("dodgeChance") or 0)
    local amount = (item:getCustomAttribute("dodgeAmount") or 0)
    return math.ceil(math.min((chance / config.maxDodgeChance) * config.maxLevel, (amount / config.maxDodgeAmount)  * config.maxLevel))
end

local dodgeHealth = CreatureEvent("DodgeHealthEvent")
local dodgeSayDelay = 0

function dodgeHealth.onHealthChange(player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not attacker or not attacker:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end

    if attacker ~= player then
        local chance, amount = getPlayerDodge(player)
        if chance > 0 and amount > 0 then
            if chance >= math.random(100) then
                if dodgeSayDelay <= os.mtime() then
                    player:say("Dodge!")
                    dodgeSayDelay = os.mtime() + 3000
                end
                if amount >= 1 then
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                end
                return primaryDamage - (amount * primaryDamage), primaryType, secondaryDamage - (amount * secondaryDamage), secondaryType
            end
        end
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

dodgeHealth:register()

local dodgeMana = CreatureEvent("DodgeManaEvent")

function dodgeMana.onManaChange(player, attacker, primaryDamage, primaryType, secondaryDamage, secondaryType, origin)
    if not attacker or not attacker:isPlayer() then
        return primaryDamage, primaryType, secondaryDamage, secondaryType
    end
    
    if attacker ~= player then
        local chance, amount = getPlayerDodge(player)
        if chance > 0 and amount > 0 then
            if chance >= math.random(100) then
                if dodgeSayDelay <= os.mtime() then
                    player:say("Dodge!")
                    dodgeSayDelay = os.mtime() + 3000
                end
                if amount >= 1 then
                    player:getPosition():sendMagicEffect(CONST_ME_POFF)
                end
                return primaryDamage - (amount * primaryDamage), primaryType, secondaryDamage - (amount * secondaryDamage), secondaryType
            end
        end
    end
    return primaryDamage, primaryType, secondaryDamage, secondaryType
end

dodgeMana:register()

local function isDodgeItem(iType)
    local weaponType = iType:getWeaponType()
    return weaponType ~= WEAPON_NONE or iType:getAttack() ~= 0 or iType:getDefense() ~= 0 or iType:getExtraDefense() ~= 0 or iType:getHitChance() ~= 0
end

local dodgeStone = Action()

function dodgeStone.onUse(player, item, fromPos, target, toPos, isHotkey)
    if not target or target.uid == 0 or target:isCreature() then
        player:sendCancelMessage("This item only works on items.")
        return true
    end

    if not isDodgeItem(target:getType()) then
        player:sendCancelMessage("Only items with base attributes can be upgraded.")
        return true
    end

    if getItemLevel(target) >= config.maxLevel then
        player:sendCancelMessage("This item is already fully upgraded.")
        return true
    end

    target:setCustomAttribute("dodgeChance", (target:getCustomAttribute("dodgeChance") or 0) + (config.maxDodgeChance / config.maxLevel))
    target:setCustomAttribute("dodgeAmount", (target:getCustomAttribute("dodgeAmount") or 0) + (config.maxDodgeAmount / config.maxLevel))
    target:getPosition():sendMagicEffect(CONST_ME_FIREWORK_YELLOW)
    local itemLevel = getItemLevel(target)
    player:say(string.format("DodgeSuccess +%d!", itemLevel))
    player:sendCancelMessage(string.format("The %s o has been upgraded to level %d!", target:getName(), itemLevel))
    return true
end

dodgeStone:id(config.dodgeItemId)
dodgeStone:register()

local dodgeBuy = Action()

function dodgeBuy.onUse(player, item, fromPos, target, toPos, isHotkey)
    if not player:removeMoney(config.price) then
        player:sendCancelMessage(string.format("You don't have enough money, you need %s crystal coins.", config.price / 10000))
        return true
    end

    local dodgeItem = player:addItem(config.dodgeItemId, config.dodgeItemCount)
    if not dodgeItem then
        player:sendCancelMessage("You have no space, free up your inventory.")
        return true
    end

    local position = player:getPosition()
    fromPos:sendDistanceEffect(position, CONST_ANI_SMALLSTONE)
    player:say("DodgeBuySuccess!")
    position:sendMagicEffect(CONST_ME_STUN)

    local itemId = item:getId()
    if itemId == 1945 or itemId == 1946 then
        item:transform(itemId == 1945 and 1946 or 1945)
    end
    return true
end

dodgeBuy:aid(config.leverActionId)
dodgeBuy:register()

local dodgeLook = EventCallback

function dodgeLook.onLook(player, thing, position, distance, description)
    if thing:isItem() then
        local chance = (thing:getCustomAttribute("dodgeChance") or 0)
        local amount = (thing:getCustomAttribute("dodgeAmount") or 0)
        if chance ~= 0 and amount ~= 0 then
            description = string.format("%s\n[ Dodge Chance: %s%%, Amount: %s%% ]", description, chance, amount)
        end
    elseif thing:isPlayer() then
        local chance, amount = getPlayerDodge(player)
        if chance ~= 0 and amount ~= 0 then
            description = string.format("%s\n[ Dodge Chance: %s%%, Amount: %s%% ]", description, chance, amount * 100)
        end
    end
    return description
end

dodgeLook:register(2)

local dodgeLogin = CreatureEvent("DodgeLogin")

function dodgeLogin.onLogin(player)
    player:registerEvent("DodgeHealthEvent")
    player:registerEvent("DodgeManaEvent")
    return true
end

dodgeLogin:register()

You only have to configure the itemId of the dodge stone and the actionId for the lever with which the dodge stone is purchased

System caracteristics:
* Added to the end of the description of the items information about dodge chance and amount if you has them
1620585634539.png

* Added to the end of the description of the players information about dodge chance and amount exactly the total of your all items equiped if you has them

1620585664032.png
* Lever for buy dodge stones with actionId leverActionId = 9999
GIF 09-05-2021 02-55-24 p. m..gif1620587402229.png

* Just dodge players damages only
 
Last edited:

jel

Member
Joined
Mar 22, 2014
Messages
207
Reaction score
8
how to use in tfs 1.3 without eventcallback??
I tried here but I have this error, any solution?
[2021-14-07 21:47:01.561] [error] Lua script error: data/events/scripts/player.lua:p[email protected]
[2021-14-07 21:47:01.561] [error] data/events/scripts/player.lua:102: attempt to call method 'isItem' (a nil value)
stack traceback:
[C]: in function 'isItem'
data/events/scripts/player.lua:102: in function <data/events/scripts/player.lua:100>
I tried to use it like this in the onlook function
if thing:isItem() then
local chance = (thing:getCustomAttribute("dodgeChance") or 0)
local amount = (thing:getCustomAttribute("dodgeAmount") or 0)
if chance ~= 0 and amount ~= 0 then
description = string.format("%s\n[ Dodge Chance: %s%%, Amount: %s%% ]", description, chance, amount)
end
elseif thing:isPlayer() then
local chance, amount = getPlayerDodge(player)
if chance ~= 0 and amount ~= 0 then
description = string.format("%s\n[ Dodge Chance: %s%%, Amount: %s%% ]", description, chance, amount * 100)
end
end
 
OP
Sarah Wesker

Sarah Wesker

ค∂vαηcε รүηтαx ❤
Support Team
Joined
Mar 16, 2017
Messages
990
Solutions
98
Reaction score
1,017
Location
London
GitHub
MillhioreBT
how to use in tfs 1.3 without eventcallback??
I tried here but I have this error, any solution?

I tried to use it like this in the onlook function
In your case you should try adding this piece of code to the onLook event in events/scripts/player.lua
Lua:
if thing:isItem() then
    local chance = (thing:getCustomAttribute("dodgeChance") or 0)
    local amount = (thing:getCustomAttribute("dodgeAmount") or 0)
    if chance ~= 0 and amount ~= 0 then
        description = string.format("%s\n[ Dodge Chance: %s%%, Amount: %s%% ]", description, chance, amount)
    end
elseif thing:isPlayer() then
    local chance, amount = getPlayerDodge(player)
    if chance ~= 0 and amount ~= 0 then
        description = string.format("%s\n[ Dodge Chance: %s%%, Amount: %s%% ]", description, chance, amount * 100)
    end
end
 
Top