• 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.2+] Simple Smithing Skill w/ Options

Ramirow

Veteran OT User
Joined
Aug 22, 2009
Messages
584
Solutions
15
Reaction score
301
Location
Argentina
YouTube
ramirogrant
First of all, I know I'm not a good scripter myself, but I made this and I wanted to share it.

Requirements:
CODEX NG's Spell Experience
system: Player - Spell Experience - 1.2

Optional:
Zbizu's UISS
: CreatureEvent - [TFS 1.1] Ultimate item stat system (elements, skills, exp, loot and more)

Just register the item you want to use it with in Actions.xml, change the position at the top of the script to suit your map and it's done.
I've commented the script almost everywhere so you understand how to config it. Feel free to ask any questions or anything.

Little picture of it:
241nn2v.png


HOW THIS WORKS:
1) You place crystals (Or any item you configure) and a material.
2) You hit them with the registered item of your choice (in Actions.xml)
3) You create an item or fail.
4) You gain exp towards advancing the skill (which increases your sucess rate and will unlock better items)
5) You may also get a refined item (+1, +2, etc) if you enable Zbizu's UISS option, higher skill gives you higher chance and more powerful refines.

Code:
-- Smithing Skill
-- For TFS versions 1.2+
-- Uses CODEX NG's Spell Experience: https://otland.net/threads/player-spell-experience-1-2.238208/
-- Optionals: Zbizu's Ultimate Item Stat System: https://otland.net/threads/tfs-1-1-ultimate-item-stat-system-elements-skills-exp-loot-and-more.229771/

local name = "Smithing"        -- Spell Experience Skill Name
local storage = 15019        -- Spell Experience storage

local anvilPos = Position(1036, 550, 7)        --Anvil Position
local materialPos = Position(1036, 551, 7)        --Material Position
local rewardPos = Position(1036, 549, 7)    --Item Craft Position

local useItemStats = false        --Enables or disables Zbizu's Ultimate Item Stat System

local config = {
    [18417] = {        --Brown Crystal Splinter
        itemid = 18417,
        tiers = {first = 1, second = 20},    --Level Tiers for different items
        tierOneItems = {2376, 2386, 2448, 2412, 2398, 2388},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet
        tierTwoItems = {2376, 2386, 2448, 2412, 2398, 2388, 2430, 8209, 2445},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet, Knight Axe, Crimson Sword, Crystal Mace
        level = {min = 1, success = 35},    --Min stands for minimun level in order to craft, success stands for the base chance of success at such level
        material = 5887,    --The material needed to craft
        skillSuccessIncrement = 1,    --How much sucess rate you gain with each level in the skill
        refine = {base = 1, increment = 0.1},    --Base refine rate and how much it increases per skill level (If using Zbizu's Ultimate Item Stat System)
        refineLevel = 10,    --Every X levels to get better refines (If using Zbizu's Ultimate Item Stat System)
        xp = {normalItem = 2, refinedItem = 5}    --Exp gained for succesful crafting or refined (refined requires Zbizu's System)
    }
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)
local player = type(cid) == 'number' and Player(cid) or cid
local smithingSkill = player:getCustomSkill(storage)
   
    if config[target.itemid] == nil then
        return false
    end
   
    if config[target.itemid] and toPosition == anvilPos then
        local itemLevel = config[target.itemid].level
                if smithingSkill < itemLevel.min then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need smithing level " .. itemLevel.min .. " for this combination.")
                    return true
                end
       
        local hasReagent = Tile(materialPos):getItemById(config[target.itemid].material)
   
        if not hasReagent then
            materialPos:sendMagicEffect(CONST_ME_TUTORIALSQUARE)
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need materials in order to craft.")
        return true
        end
   
        if hasReagent then
            local rank = config[target.itemid].tiers
            local chance = math.floor((math.random(1, 100)) - (smithingSkill * config[target.itemid].skillSuccessIncrement))
           
            if chance <= itemLevel.success then
                local bonusBase = config[target.itemid].refine
                local bonusChance = math.floor(math.random(1, 100) - (smithingSkill * bonusBase.increment))
                    if bonusChance <= bonusBase.base and useItemStats == true then
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(anvilPos):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(rewardPos):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, rewardPos)
                            local b = Tile(rewardPos):getItemById(config[target.itemid].tierOneItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            rewardPos:sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(anvilPos):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(rewardPos):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, rewardPos)
                            local b = Tile(rewardPos):getItemById(config[target.itemid].tierTwoItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            rewardPos:sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    else
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(anvilPos):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(rewardPos):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, rewardPos)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            rewardPos:sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(anvilPos):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(rewardPos):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, rewardPos)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            rewardPos:sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    return true
                    end
            else
                local removeCrystal = Tile(anvilPos):getItemById(target.itemid)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Crafting failed.")
                toPosition:sendMagicEffect(CONST_ME_POFF)
                hasReagent:remove(1)
                removeCrystal:remove(1)
            return true
            end
        return true
        end
    elseif toPosition ~= anvilPos then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to go to an special shop in order to craft.")
    else
        return false
    end
return true
end
 
Don't know how to update the main post. Changed a couple of things here and there, didn't test it. You're free to do it and tell me if there are any problems.

This changes allow you to use this smithing as long as you place an Anvil (ID: 2555) and an Empty Coal Basin just south of it. (ID: 1485).
This way you could add plenty of smithing stations instead of limiting them to one.

Code:
-- Smithing Skill v1.1
-- For TFS versions 1.2+
-- Uses CODEX NG's Spell Experience: https://otland.net/threads/player-spell-experience-1-2.238208/
-- Optionals: Zbizu's Ultimate Item Stat System: https://otland.net/threads/tfs-1-1-ultimate-item-stat-system-elements-skills-exp-loot-and-more.229771/

local name = "Smithing"        -- Spell Experience Skill Name
local storage = 15019        -- Spell Experience storage

local useItemStats = false        --Enables or disables Zbizu's Ultimate Item Stat System

local config = {
    [18417] = {        --Brown Crystal Splinter
        itemid = 18417,
        tiers = {first = 1, second = 20},    --Level Tiers for different items
        tierOneItems = {2376, 2386, 2448, 2412, 2398, 2388},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet
        tierTwoItems = {2376, 2386, 2448, 2412, 2398, 2388, 2430, 8209, 2445},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet, Knight Axe, Crimson Sword, Crystal Mace
        level = {min = 1, success = 35},    --Min stands for minimun level in order to craft, success stands for the base chance of success at such level
        material = 5887,    --The material needed to craft
        skillSuccessIncrement = 1,    --How much sucess rate you gain with each level in the skill
        refine = {base = 1, increment = 0.1},    --Base refine rate and how much it increases per skill level (If using Zbizu's Ultimate Item Stat System)
        refineLevel = 10,    --Every X levels to get better refines (If using Zbizu's Ultimate Item Stat System)
        xp = {normalItem = 2, refinedItem = 5}    --Exp gained for succesful crafting or refined (refined requires Zbizu's System)
    }
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)
local player = type(cid) == 'number' and Player(cid) or cid
local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemCountById(1485)

if checkAnvil == 1 and checkBasin == 1 then
    if config[target.itemid] then
        local hasReagent = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemById(config[target.itemid].material)
            if not hasReagent then
                Position(toPosition.x, toPosition.y + 1, toPosition.z):sendMagicEffect(CONST_ME_TUTORIALSQUARE)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need materials in order to craft.")
                return true
            end
        local itemLevel = config[target.itemid].level
        local smithingSkill = player:getCustomSkill(storage)
       
                if smithingSkill < itemLevel.min then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need smithing level " .. itemLevel.min .. " for this combination.")
                    return true
                end
   
        if hasReagent then
            local rank = config[target.itemid].tiers
            local chance = math.floor((math.random(1, 100)) - ((smithingSkill * config[target.itemid].skillSuccessIncrement) - itemLevel.min))
           
            if chance <= itemLevel.success then
                local bonusBase = config[target.itemid].refine
                local bonusChance = math.floor(math.random(1, 100) - (smithingSkill * bonusBase.increment))
                    if bonusChance <= bonusBase.base and useItemStats == true then
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierOneItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierTwoItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    else
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    return true
                    end
            else
                local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Crafting failed.")
                toPosition:sendMagicEffect(CONST_ME_POFF)
                hasReagent:remove(1)
                removeCrystal:remove(1)
            return true
            end
        return true
        end
    else
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    end
else
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to go to an special shop in order to craft.")
end
return true
end
 
not sure what i did wrong but, here it go.

i'm use TFS 1.2 protocol 10.98.

i've configure the crystal to ID: 18413 (blue crystal shard)
and to hit it with registered ID: 2557 (Hammer)

now, when i hit it, i get this
"You need smithing level 1 for this combination"
ive change from 1 to 0 and still can't and now tell me i need level 0 to combination.

so here the mess that ive done.
Lua:
    <!-- Smith -->
    <action itemid="2557" script="custom/smith.lua" />
    <action actionid="15019" script="custom/smith.lua" />

and the code that you provied i placed in folder data/action/scripts/custom.

PS: ive made sure the position of anvilPos, materialPos and rewardPos.
are correct and as for the moment im not using Zbizu's UISS.

and heres my Player.lua
Lua:
function Player:onBrowseField(position)
    return true
end

function Player:onLook(thing, position, distance)
    local description = "You see " .. thing:getDescription(distance)
    if self:getGroup():getAccess() then
        if thing:isItem() then
            description = string.format("%s\nItem ID: %d", description, thing:getId())

            local actionId = thing:getActionId()
            if actionId ~= 0 then
                description = string.format("%s, Action ID: %d", description, actionId)
            end

            local uniqueId = thing:getAttribute(ITEM_ATTRIBUTE_UNIQUEID)
            if uniqueId > 0 and uniqueId < 65536 then
                description = string.format("%s, Unique ID: %d", description, uniqueId)
            end

            local itemType = thing:getType()

            local transformEquipId = itemType:getTransformEquipId()
            local transformDeEquipId = itemType:getTransformDeEquipId()
            if transformEquipId ~= 0 then
                description = string.format("%s\nTransforms to: %d (onEquip)", description, transformEquipId)
            elseif transformDeEquipId ~= 0 then
                description = string.format("%s\nTransforms to: %d (onDeEquip)", description, transformDeEquipId)
            end

            local decayId = itemType:getDecayId()
            if decayId ~= -1 then
                description = string.format("%s\nDecays to: %d", description, decayId)
            end
        elseif thing:isCreature() then
            local str = "%s\nHealth: %d / %d"
            if thing:getMaxMana() > 0 then
                str = string.format("%s, Mana: %d / %d", str, thing:getMana(), thing:getMaxMana())
            end
            description = string.format(str, description, thing:getHealth(), thing:getMaxHealth()) .. "."
        end

        local position = thing:getPosition()
        description = string.format(
            "%s\nPosition: %d, %d, %d",
            description, position.x, position.y, position.z
        )

        if thing:isCreature() then
            if thing:isPlayer() then
                description = string.format("%s\nIP: %s.", description, Game.convertIpToString(thing:getIp()))
            end
        end
    end
    self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end

function Player:onLookInBattleList(creature, distance)
    local description = "You see " .. creature:getDescription(distance)
    if self:getGroup():getAccess() then
        local str = "%s\nHealth: %d / %d"
        if creature:getMaxMana() > 0 then
            str = string.format("%s, Mana: %d / %d", str, creature:getMana(), creature:getMaxMana())
        end
        description = string.format(str, description, creature:getHealth(), creature:getMaxHealth()) .. "."

        local position = creature:getPosition()
        description = string.format(
            "%s\nPosition: %d, %d, %d",
            description, position.x, position.y, position.z
        )

        if creature:isPlayer() then
            description = string.format("%s\nIP: %s", description, Game.convertIpToString(creature:getIp()))
        end
    end
    self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end

function Player:onLookInTrade(partner, item, distance)
    self:sendTextMessage(MESSAGE_INFO_DESCR, "You see " .. item:getDescription(distance))
end

function Player:onLookInShop(itemType, count)
    return true
end

function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    if item:getActionId() == CURSED_CHESTS_AID then return false end
    return true
end

function Player:onMoveCreature(creature, fromPosition, toPosition)
    return true
end

function Player:onTurn(direction)
    return true
end

function Player:onTradeRequest(target, item)
    return true
end

function Player:onTradeAccept(target, item, targetItem)
    return true
end

local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT)
soulCondition:setTicks(4 * 60 * 1000)
soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1)

local function useStamina(player)
    local staminaMinutes = player:getStamina()
    if staminaMinutes == 0 then
        return
    end

    local playerId = player:getId()
    local currentTime = os.time()
    local timePassed = currentTime - nextUseStaminaTime[playerId]
    if timePassed <= 0 then
        return
    end

    if timePassed > 60 then
        if staminaMinutes > 2 then
            staminaMinutes = staminaMinutes - 2
        else
            staminaMinutes = 0
        end
        nextUseStaminaTime[playerId] = currentTime + 120
    else
        staminaMinutes = staminaMinutes - 1
        nextUseStaminaTime[playerId] = currentTime + 60
    end
    player:setStamina(staminaMinutes)
end

function Player:onGainExperience(source, exp, rawExp)
    if not source or source:isPlayer() then
        return exp
    end

    -- Soul regeneration
    local vocation = self:getVocation()
    if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then
        soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000)
        self:addCondition(soulCondition)
    end

    -- Apply experience stage multiplier
    exp = exp * Game.getExperienceStage(self:getLevel())

    -- Stamina modifier
    if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
        useStamina(self)

        local staminaMinutes = self:getStamina()
        if staminaMinutes > 2400 and self:isPremium() then
            exp = exp * 1.5
        elseif staminaMinutes <= 840 then
            exp = exp * 0.5
        end
    end

    return exp
end

function Player:onLoseExperience(exp)
    return exp
end

function Player:onGainSkillTries(skill, tries)
    if APPLY_SKILL_MULTIPLIER == false then
        return tries
    end

    if skill == SKILL_MAGLEVEL then
        return tries * configManager.getNumber(configKeys.RATE_MAGIC)
    end
    return tries * configManager.getNumber(configKeys.RATE_SKILL)
end

function Player:getCustomSkill(storage)
    return self:getStorageValue(storage)
end
function Player:addCustomSkill(skillName, storage)
    local skillStorage = math.max(10, self:getStorageValue(storage))
    local skillTries =  math.max(0, self:getStorageValue(storage + 1))
    self:setStorageValue(storage, skillStorage + 1)
    self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You advanced to " .. string.lower(skillName) .. " level "..self:getCustomSkill(storage)..".")
    self:setStorageValue(storage + 1, 0)
end
function Player:addCustomSkillTry(skillName, storage)
    local skillStorage = math.max(10, self:getStorageValue(storage))
    local skillTries =  math.max(0, self:getStorageValue(storage + 1))
    self:setStorageValue(storage + 1, skillTries + 1)
    if skillTries > math.floor(20 * math.pow(1.1, (skillStorage - 11)) / 10) then
        self:addCustomSkill(skillName, storage)
    end
end
function Player:getCustomSkillPercent(storage)
    local skillStorage = math.max(10, self:getStorageValue(storage))
    local skillTries =  math.max(0, self:getStorageValue(storage + 1))
    local triesNeeded = math.floor(20 * math.pow(1.1, (skillStorage - 11)) / 10)
    local percent = math.floor(100 * (1 - skillTries / triesNeeded))
    if percent > 1 and percent <= 100 then
        return percent
    else
        percent = 1
        return percent
    end
end

-- base Custom Skill.
function Player:getCustomSkill(storage)
    return self:getStorageValue(storage)
end
function Player:addCustomSkill(skillName, storage)
    local skillStorage = math.max(10, self:getStorageValue(storage))
    local skillTries =  math.max(0, self:getStorageValue(storage + 1))
    self:setStorageValue(storage, skillStorage + 1)
    self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You advanced to " .. string.lower(skillName) .. " level "..self:getCustomSkill(storage)..".")
    self:setStorageValue(storage + 1, 0)
end
function Player:addCustomSkillTry(skillName, storage)
    local skillStorage = math.max(10, self:getStorageValue(storage))
    local skillTries =  math.max(0, self:getStorageValue(storage + 1))
    self:setStorageValue(storage + 1, skillTries + 1)
    if skillTries > math.floor(20 * math.pow(1.1, (skillStorage - 11)) / 10) then
        self:addCustomSkill(skillName, storage)
    end
end
function Player:getCustomSkillPercent(storage)
    local skillStorage = math.max(10, self:getStorageValue(storage))
    local skillTries =  math.max(0, self:getStorageValue(storage + 1))
    local triesNeeded = math.floor(20 * math.pow(1.1, (skillStorage - 11)) / 10)
    local percent = math.floor(100 * (1 - skillTries / triesNeeded))
    if percent > 1 and percent <= 100 then
        return percent
    else
        percent = 1
        return percent
    end
end
 
Last edited:
Hello mate n_n First of all, I reccomend you use the second script I posted here:
Don't know how to update the main post. Changed a couple of things here and there, didn't test it. You're free to do it and tell me if there are any problems.

This changes allow you to use this smithing as long as you place an Anvil (ID: 2555) and an Empty Coal Basin just south of it. (ID: 1485).
This way you could add plenty of smithing stations instead of limiting them to one.

Code:
-- Smithing Skill v1.1
-- For TFS versions 1.2+
-- Uses CODEX NG's Spell Experience: https://otland.net/threads/player-spell-experience-1-2.238208/
-- Optionals: Zbizu's Ultimate Item Stat System: https://otland.net/threads/tfs-1-1-ultimate-item-stat-system-elements-skills-exp-loot-and-more.229771/

local name = "Smithing"        -- Spell Experience Skill Name
local storage = 15019        -- Spell Experience storage

local useItemStats = false        --Enables or disables Zbizu's Ultimate Item Stat System

local config = {
    [18417] = {        --Brown Crystal Splinter
        itemid = 18417,
        tiers = {first = 1, second = 20},    --Level Tiers for different items
        tierOneItems = {2376, 2386, 2448, 2412, 2398, 2388},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet
        tierTwoItems = {2376, 2386, 2448, 2412, 2398, 2388, 2430, 8209, 2445},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet, Knight Axe, Crimson Sword, Crystal Mace
        level = {min = 1, success = 35},    --Min stands for minimun level in order to craft, success stands for the base chance of success at such level
        material = 5887,    --The material needed to craft
        skillSuccessIncrement = 1,    --How much sucess rate you gain with each level in the skill
        refine = {base = 1, increment = 0.1},    --Base refine rate and how much it increases per skill level (If using Zbizu's Ultimate Item Stat System)
        refineLevel = 10,    --Every X levels to get better refines (If using Zbizu's Ultimate Item Stat System)
        xp = {normalItem = 2, refinedItem = 5}    --Exp gained for succesful crafting or refined (refined requires Zbizu's System)
    }
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)
local player = type(cid) == 'number' and Player(cid) or cid
local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemCountById(1485)

if checkAnvil == 1 and checkBasin == 1 then
    if config[target.itemid] then
        local hasReagent = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemById(config[target.itemid].material)
            if not hasReagent then
                Position(toPosition.x, toPosition.y + 1, toPosition.z):sendMagicEffect(CONST_ME_TUTORIALSQUARE)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need materials in order to craft.")
                return true
            end
        local itemLevel = config[target.itemid].level
        local smithingSkill = player:getCustomSkill(storage)
     
                if smithingSkill < itemLevel.min then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need smithing level " .. itemLevel.min .. " for this combination.")
                    return true
                end
 
        if hasReagent then
            local rank = config[target.itemid].tiers
            local chance = math.floor((math.random(1, 100)) - ((smithingSkill * config[target.itemid].skillSuccessIncrement) - itemLevel.min))
         
            if chance <= itemLevel.success then
                local bonusBase = config[target.itemid].refine
                local bonusChance = math.floor(math.random(1, 100) - (smithingSkill * bonusBase.increment))
                    if bonusChance <= bonusBase.base and useItemStats == true then
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierOneItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierTwoItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    else
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    return true
                    end
            else
                local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Crafting failed.")
                toPosition:sendMagicEffect(CONST_ME_POFF)
                hasReagent:remove(1)
                removeCrystal:remove(1)
            return true
            end
        return true
        end
    else
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    end
else
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to go to an special shop in order to craft.")
end
return true
end
If you use this code, you won't need to configure any position, it will work if you place a Coal Basin (ID: 1485) just one sqm south of an Anvil (ID: 2555) and it will calculate the Material and Reward position based on that. (Do remember that the item will be created just north of the anvil, so leave a counter or something there.)

Now for the issue at hand, it's just not registered as an storage when you try to use it. You need to assign these storages (the skill itself is stored in them) to the player onLogin (If they are already created) or on the firstitems.lua script (For new players).

You can add this on firstitems.lua or the login.lua script. Replace the 'xxxx' value for the storage of your smithing skill.
Code:
local customSkill = xxxx

if player:getStorageValue(customSkill) == -1 then    
    player:setStorageValue(customSkill, 1)
    player:setStorageValue(customSkill + 1, 0)
end
 
well, thank you so much!
it works! ♥

how do i stop it from remove items in the rewardPos?
 
Last edited:
well, thank you so much!
it works! ♥

how do i stop it from remove items in the rewardPos?
I don't actually remember why I made it like that, I think it has something to do with applying the refining from Zbizu's System (If there were many stacked items sometimes it won't work I believe).
But since you're not using it, I can edit the script so it won't erase any created items from the rewardPos, just replace your script for this one:
Code:
-- Smithing Skill v1.1
-- For TFS versions 1.2+
-- Uses CODEX NG's Spell Experience: https://otland.net/threads/player-spell-experience-1-2.238208/
-- Optionals: Zbizu's Ultimate Item Stat System: https://otland.net/threads/tfs-1-1-ultimate-item-stat-system-elements-skills-exp-loot-and-more.229771/

local name = "Smithing"        -- Spell Experience Skill Name
local storage = 15019        -- Spell Experience storage

local useItemStats = false        --Enables or disables Zbizu's Ultimate Item Stat System

local config = {
    [18417] = {        --Brown Crystal Splinter
        itemid = 18417,
        tiers = {first = 1, second = 20},    --Level Tiers for different items
        tierOneItems = {2376, 2386, 2448, 2412, 2398, 2388},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet
        tierTwoItems = {2376, 2386, 2448, 2412, 2398, 2388, 2430, 8209, 2445},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet, Knight Axe, Crimson Sword, Crystal Mace
        level = {min = 1, success = 35},    --Min stands for minimun level in order to craft, success stands for the base chance of success at such level
        material = 5887,    --The material needed to craft
        skillSuccessIncrement = 1,    --How much sucess rate you gain with each level in the skill
        refine = {base = 1, increment = 0.1},    --Base refine rate and how much it increases per skill level (If using Zbizu's Ultimate Item Stat System)
        refineLevel = 10,    --Every X levels to get better refines (If using Zbizu's Ultimate Item Stat System)
        xp = {normalItem = 2, refinedItem = 5}    --Exp gained for succesful crafting or refined (refined requires Zbizu's System)
    }
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)
local player = type(cid) == 'number' and Player(cid) or cid
local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemCountById(1485)

if checkAnvil == 1 and checkBasin == 1 then
    if config[target.itemid] then
        local hasReagent = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemById(config[target.itemid].material)
            if not hasReagent then
                Position(toPosition.x, toPosition.y + 1, toPosition.z):sendMagicEffect(CONST_ME_TUTORIALSQUARE)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need materials in order to craft.")
                return true
            end
        local itemLevel = config[target.itemid].level
        local smithingSkill = player:getCustomSkill(storage)
       
                if smithingSkill < itemLevel.min then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need smithing level " .. itemLevel.min .. " for this combination.")
                    return true
                end
   
        if hasReagent then
            local rank = config[target.itemid].tiers
            local chance = math.floor((math.random(1, 100)) - ((smithingSkill * config[target.itemid].skillSuccessIncrement) - itemLevel.min))
           
            if chance <= itemLevel.success then
                local bonusBase = config[target.itemid].refine
                local bonusChance = math.floor(math.random(1, 100) - (smithingSkill * bonusBase.increment))
                    if bonusChance <= bonusBase.base and useItemStats == true then
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierOneItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierTwoItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    else
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    return true
                    end
            else
                local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Crafting failed.")
                toPosition:sendMagicEffect(CONST_ME_POFF)
                hasReagent:remove(1)
                removeCrystal:remove(1)
            return true
            end
        return true
        end
    else
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    end
else
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to go to an special shop in order to craft.")
end
return true
end
There! If you enable Zbizu's system it will delete any item in the reward position prior to creating the refined one. If you're not using that system it will create item after item without deleting them, haven't tested it
 
i might add Zbizu's system in the future, so i better not mess around if it's important.

but, ive been looking at the code, and i was thinking to add more crafting tiers.
(tier 1 (levels 1-19),
(tier 2 (levels 20-39),
(tier 3 (levels 40-59),
(tier 4 (levels 60-89),
(tier 5 (levels 90-∞).

i know i mess something up but no idea where i went worng :x

Lua:
-- Smithing Skill v1.1
-- For TFS versions 1.2+
-- Uses CODEX NG's Spell Experience: https://otland.net/threads/player-spell-experience-1-2.238208/
-- Optionals: Zbizu's Ultimate Item Stat System: https://otland.net/threads/tfs-1-1-ultimate-item-stat-system-elements-skills-exp-loot-and-more.229771/

local name = "Smithing"        -- Spell Experience Skill Name
local storage = 15019        -- Spell Experience storage

local useItemStats = false        --Enables or disables Zbizu's Ultimate Item Stat System

local config = {
    [18413] = {        --Brown Crystal Splinter
        itemid = 18413,
        tiers = {first = 1, second = 20, third = 40, fourth = 60, fifth = 90}, --Level Tiers for different items
        tierOneItems = {3962}, --: Beastslayer Axe
        tierTwoItems = {15451}, --: Warrior's Axe
        tierThreeItems = {2389}, --: Heroic Axe
        tierFourItems = {2431}, --: Stonecutter Axe
        tierFiveItems = {8925}, --: Solar Axe
        level = {min = 1, success = 35},    --Min stands for minimun level in order to craft, success stands for the base chance of success at such level
        material = 5887,    --The material needed to craft
        skillSuccessIncrement = 1,    --How much sucess rate you gain with each level in the skill
        refine = {base = 1, increment = 0.1},    --Base refine rate and how much it increases per skill level (If using Zbizu's Ultimate Item Stat System)
        refineLevel = 10,    --Every X levels to get better refines (If using Zbizu's Ultimate Item Stat System)
        xp = {normalItem = 2, refinedItem = 5}    --Exp gained for succesful crafting or refined (refined requires Zbizu's System)
    }
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)
local player = type(cid) == 'number' and Player(cid) or cid
local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x - 1, toPosition.y, toPosition.z):getItemCountById(1485)

if checkAnvil == 1 and checkBasin == 1 then
    if config[target.itemid] then
        local hasReagent = Tile(toPosition.x - 1, toPosition.y, toPosition.z):getItemById(config[target.itemid].material)
            if not hasReagent then
                Position(toPosition.x - 1, toPosition.y, toPosition.z):sendMagicEffect(CONST_ME_TUTORIALARROW)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need materials in order to craft.")
                return true
            end
        local itemLevel = config[target.itemid].level
        local smithingSkill = player:getCustomSkill(storage)
 
                if smithingSkill < itemLevel.min then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need smithing level " .. itemLevel.min .. " for this combination.")
                    return true
                end

        if hasReagent then
            local rank = config[target.itemid].tiers
            local chance = math.floor((math.random(1, 100)) - ((smithingSkill * config[target.itemid].skillSuccessIncrement) - itemLevel.min))
     
            if chance <= itemLevel.success then
                local bonusBase = config[target.itemid].refine
                local bonusChance = math.floor(math.random(1, 100) - (smithingSkill * bonusBase.increment))
                    if bonusChance <= bonusBase.base and useItemStats == true then
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid) -- start of tier 1
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierOneItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end -- end of tier 1
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid) -- start of tier 2
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierTwoItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end --end of tier 2
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)-- start of tier 3
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierThreeItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierThreeItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierThreeItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end    --end of tier 3
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)-- start of tier 4
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierFourItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierFourItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierFourItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end    --end of tier 4
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)-- start of tier 5
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierFiveItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierFiveItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierFiveItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end    --end of tier 5
                    else
                        if smithingSkill < rank.second then -- start of tier 1
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end -- end of tier 1
                        else
                        if smithingSkill < rank.third then -- start of tier 2
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end -- end of tier 2
                            else
                        if smithingSkill < rank.fourth then -- start of thier 3
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierThreeItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierThreeItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end -- end of tier 3
                            else
                        if smithingSkill < rank.fifth then -- start of thier 4
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierFourItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierFourItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end -- end of thier 4
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid) -- start of tier 5
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierFiveItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierFiveItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end -- end of thier 5
                        end
                    return true
                    end
            else
                local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Crafting failed.")
                toPosition:sendMagicEffect(CONST_ME_POFF)
                hasReagent:remove(1)
                removeCrystal:remove(1)
            return true
            end
        return true
        end
    else
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    end
else
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to go to an special shop in order to craft.")
end
return true
end

i tried to do add this all by myself but i guess i still have long way to go :c
i have no idea how to do if / else statement that include extra tiers

i mean
Lua:
if smithingSkill < rank.second + rank.third then
bla "first tier crafted" bla

        end
else
        bla " second tier crafted" bla
        end
now what to do for third? another else? lol
 
Last edited:
I've made this script some time ago and there's a lot of room to improve it I believe (Or shorten it) but yeah, it should we working like, for example:

Code:
tiers = {first = 1, second = 20, third = 40, fourth = 60, fifth = 90},

if smithingSkill < tiers.second then
    --Tier 1 crafting
elseif smithingSkill < tiers.third and smithingSkill >= tiers.second then
    --Tier 2 crafting
elseif smithingSkill < tiers.fourth and smithingSkill >= tiers.third then
    --Tier 3 crafting
elseif smithingSkill < tiers.fifth and smithingSkill >= tiers.fourth then
    --Tier 4 crafting
elseif smithingSkill >= tiers.fifth then
    --Tier 5 crafting
return true
end
 
well, now that make more sense..
thanks a lot!

i don't want to be more bother than i already am, but i get this weird error, and im not sure what is it or even how to analyze it

Lua:
-- Smithing Skill v1.1
-- For TFS versions 1.2+
-- Uses CODEX NG's Spell Experience: https://otland.net/threads/player-spell-experience-1-2.238208/
-- Optionals: Zbizu's Ultimate Item Stat System: https://otland.net/threads/tfs-1-1-ultimate-item-stat-system-elements-skills-exp-loot-and-more.229771/

local name = "Smithing"        -- Spell Experience Skill Name
local storage = 15019        -- Spell Experience storage

local useItemStats = true        --Enables or disables Zbizu's Ultimate Item Stat System

local config = {
    [18413] = {        --Blue Crystal Shard
        itemid = 18413,
        tiers = {first = 1, second = 20, third = 40, fourth = 60, fifth = 90}, --Level Tiers for different items |
        tierOneItems = {3962}, --: Beastslayer Axe
        tierTwoItems = {15451, 3962}, --: Warrior's Axe + every item from previous tiers (tier 1 + 2)
        tierThreeItems = {2389, 15451, 3962}, --: Heroic Axe + every item from previous tiers (tier 1, 2 & 3)
        tierFourItems = {2431, 2389, 15451, 3962}, --: Stonecutter Axe + every item from previous tiers (tier 1, 2, 3 & 4)
        tierFiveItems = {8925, 2431, 2389, 15451, 3962}, --: Solar Axe + every item from previous tiers (tier 1, 2, 3, 4 and 5)
        level = {min = 1, success = 20},    --Min stands for minimun level in order to craft, success stands for the base chance of success at such level
        material = 5887,    --The material needed to craft
        skillSuccessIncrement = 1,    --How much sucess rate you gain with each level in the skill
        refine = {base = 1, increment = 0.1},    --Base refine rate and how much it increases per skill level (If using Zbizu's Ultimate Item Stat System)
        refineLevel = 20,    --Every X levels to get better refines (If using Zbizu's Ultimate Item Stat System)
        xp = {normalItem = 2, refinedItem = 5}    --Exp gained for succesful crafting or refined (refined requires Zbizu's System)
    }
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)
local player = type(cid) == 'number' and Player(cid) or cid
local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemCountById(1485)

if checkAnvil == 1 and checkBasin == 1 then
    if config[target.itemid] then
        local hasReagent = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemById(config[target.itemid].material)
            if not hasReagent then
                Position(toPosition.x, toPosition.y + 1, toPosition.z):sendMagicEffect(CONST_ME_TUTORIALARROW)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need materials in order to craft.")
                return true
            end
        local itemLevel = config[target.itemid].level
        local smithingSkill = player:getCustomSkill(storage)
      
                if smithingSkill < itemLevel.min then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need smithing level " .. itemLevel.min .. " for this combination.")
                    return true
                end
  
        if hasReagent then
            local rank = config[target.itemid].tiers
            local chance = math.floor((math.random(1, 100)) - ((smithingSkill * config[target.itemid].skillSuccessIncrement) - itemLevel.min))
          
            if chance <= itemLevel.success then
                local bonusBase = config[target.itemid].refine
                local bonusChance = math.floor(math.random(1, 100) - (smithingSkill * bonusBase.increment))
                    if bonusChance <= bonusBase.base and useItemStats == true then
                        if smithingSkill < rank.second then
    --Tier 1 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierOneItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            elseif smithingSkill < rank.third and smithingSkill >= rank.second then
    --Tier 2 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierTwoItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            elseif smithingSkill < rank.fourth and smithingSkill >= rank.third then
    --Tier 3 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierThreeItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierThreeItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierThreeItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            elseif smithingSkill < rank.fifth and smithingSkill >= rank.fourth then
    --Tier 4 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierFourItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierFourItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierFourItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            elseif smithingSkill >= rank.fifth then
    --Tier 5 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierFiveItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierFiveItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierFiveItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        return true
                    end
                    else
                        if smithingSkill < rank.second then
    --Tier 1 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            elseif smithingSkill < rank.third and smithingSkill >= rank.second then
    --Tier 2 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            elseif smithingSkill < rank.fourth and smithingSkill >= rank.third then
    --Tier 3 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierThreeItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierThreeItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            elseif smithingSkill < rank.fifth and smithingSkill >= rank.fourth then
    --Tier 4 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierFourItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierFourItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            elseif smithingSkill >= rank.fifth then
    --Tier 5 crafting
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierFiveItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierFiveItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                            end
                        return true
                    end
            else
                local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Crafting failed.")
                toPosition:sendMagicEffect(CONST_ME_POFF)
                hasReagent:remove(1)
                removeCrystal:remove(1)
            return true
            end
        return true
        end
    else
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    end
else
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to go to an special shop in order to craft.")
end
return true
end


first error: when i use the item on the crystal on my backpack. insted getting the "You need to place crystals on top of the anvil."
Code:
 player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")

i get this:
Error 1.png


when i craft the item, i get this:
Error 2.png


again, sorry to bother u like that, but what on earth is that? "0x7ff6dbcc2e20"
i don't know where to start the fix!
 
It's no bother friend, I think it's because my script is trying to check the position of the anvil and such by taking information from the tile you use your hammer with (In your case, there's no tile, as you're trying to use the crystal from your backpack). You want to rework it so it uses crystals directly from your backpack?
 
no, i don't want to use it from backpack :),
i just run few tests to see what can cause bugs, so i found it kinda by accident, is there way to either stop the server log to show it or to tell the script,
Lua:
 player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
if player try to use item (Hammer) on crystal in inventory (hands slot, tool slot, backpack and its contents)?

also, bigger error was the second one, where its says "0x7ff6dbcc2e20" of function 'createItem'.
 
The second error doesn't happen on my version of the script, so it has something to do with the modified one you made, altough I didn't check what may cause it, I will if I have time.
About the first one, It's been a long time since I stopped coding altogether but, I think it may be caused because the script is trying to check toPosition tile information (Where you use your hammer) and since you're pointing to your backpack it may pass a nil value as toPosition only works with tile position (any experienced coder that reads this please correct me). Anyways, maybe we could try to catch an exception before indexing the value:

Something like this may work, perhaps
Code:
local player = type(cid) == 'number' and Player(cid) or cid
if toPosition == nil then
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    return true
end

local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemCountById(1485)
 
ive found out that even if i use the brand new script
Lua:
-- Smithing Skill v1.1
-- For TFS versions 1.2+
-- Uses CODEX NG's Spell Experience: https://otland.net/threads/player-spell-experience-1-2.238208/
-- Optionals: Zbizu's Ultimate Item Stat System: https://otland.net/threads/tfs-1-1-ultimate-item-stat-system-elements-skills-exp-loot-and-more.229771/

local name = "Smithing"        -- Spell Experience Skill Name
local storage = 15019        -- Spell Experience storage

local useItemStats = false        --Enables or disables Zbizu's Ultimate Item Stat System

local config = {
    [18417] = {        --Brown Crystal Splinter
        itemid = 18417,
        tiers = {first = 1, second = 20},    --Level Tiers for different items
        tierOneItems = {2376, 2386, 2448, 2412, 2398, 2388},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet
        tierTwoItems = {2376, 2386, 2448, 2412, 2398, 2388, 2430, 8209, 2445},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet, Knight Axe, Crimson Sword, Crystal Mace
        level = {min = 1, success = 35},    --Min stands for minimun level in order to craft, success stands for the base chance of success at such level
        material = 5887,    --The material needed to craft
        skillSuccessIncrement = 1,    --How much sucess rate you gain with each level in the skill
        refine = {base = 1, increment = 0.1},    --Base refine rate and how much it increases per skill level (If using Zbizu's Ultimate Item Stat System)
        refineLevel = 10,    --Every X levels to get better refines (If using Zbizu's Ultimate Item Stat System)
        xp = {normalItem = 2, refinedItem = 5}    --Exp gained for succesful crafting or refined (refined requires Zbizu's System)
    }
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)
local player = type(cid) == 'number' and Player(cid) or cid
local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemCountById(1485)

if checkAnvil == 1 and checkBasin == 1 then
    if config[target.itemid] then
        local hasReagent = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemById(config[target.itemid].material)
            if not hasReagent then
                Position(toPosition.x, toPosition.y + 1, toPosition.z):sendMagicEffect(CONST_ME_TUTORIALSQUARE)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need materials in order to craft.")
                return true
            end
        local itemLevel = config[target.itemid].level
        local smithingSkill = player:getCustomSkill(storage)

                if smithingSkill < itemLevel.min then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need smithing level " .. itemLevel.min .. " for this combination.")
                    return true
                end

        if hasReagent then
            local rank = config[target.itemid].tiers
            local chance = math.floor((math.random(1, 100)) - ((smithingSkill * config[target.itemid].skillSuccessIncrement) - itemLevel.min))
    
            if chance <= itemLevel.success then
                local bonusBase = config[target.itemid].refine
                local bonusChance = math.floor(math.random(1, 100) - (smithingSkill * bonusBase.increment))
                    if bonusChance <= bonusBase.base and useItemStats == true then
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierOneItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierTwoItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    else
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, toPosition.x, toPosition.y - 1, toPosition.z)
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    return true
                    end
            else
                local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Crafting failed.")
                toPosition:sendMagicEffect(CONST_ME_POFF)
                hasReagent:remove(1)
                removeCrystal:remove(1)
            return true
            end
        return true
        end
    else
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    end
else
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to go to an special shop in order to craft.")
end
return true
end
where i can have multiple crafting stations i get this
error 3.png
. first script don't give me that error. (also without modification).


the only modification i want to add are: have 5 tiers, change position from west face stations to north face stations and
Lua:
local player = type(cid) == 'number' and Player(cid) or cid
if toPosition == nil then
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    return true
end

local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemCountById(1485)
ill attach the modified script below if anyone can look at it see where i mess things up and find the issue (says line 277) but looks about right :c

if can't find a fix here ill move it to requests see if anyone there might locate the problem
 

Attachments

Last edited:
@oshrigames was right. The updated one I posted contains some bugs.

Here it's fixed:
Code:
-- Smithing Skill v1.2
-- For TFS versions 1.2+
-- Uses CODEX NG's Spell Experience: https://otland.net/threads/player-spell-experience-1-2.238208/
-- Optionals: Zbizu's Ultimate Item Stat System: https://otland.net/threads/tfs-1-1-ultimate-item-stat-system-elements-skills-exp-loot-and-more.229771/

local name = "Smithing"        -- Spell Experience Skill Name
local storage = 15019        -- Spell Experience storage

local useItemStats = false        --Enables or disables Zbizu's Ultimate Item Stat System

local config = {
    [18417] = {        --Brown Crystal Splinter
        itemid = 18417,
        tiers = {first = 1, second = 20},    --Level Tiers for different items
        tierOneItems = {2376, 2386, 2448, 2412, 2398, 2388},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet
        tierTwoItems = {2376, 2386, 2448, 2412, 2398, 2388, 2430, 8209, 2445},    --IN ORDER: Sword, Axe, Studded Club, Katana, Mace, Hatchet, Knight Axe, Crimson Sword, Crystal Mace
        level = {min = 1, success = 35},    --Min stands for minimun level in order to craft, success stands for the base chance of success at such level
        material = 5887,    --The material needed to craft
        skillSuccessIncrement = 1,    --How much sucess rate you gain with each level in the skill
        refine = {base = 1, increment = 0.1},    --Base refine rate and how much it increases per skill level (If using Zbizu's Ultimate Item Stat System)
        refineLevel = 10,    --Every X levels to get better refines (If using Zbizu's Ultimate Item Stat System)
        xp = {normalItem = 2, refinedItem = 5}    --Exp gained for succesful crafting or refined (refined requires Zbizu's System)
    }
}

function onUse(cid, item, fromPosition, target, toPosition, isHotkey)
local player = type(cid) == 'number' and Player(cid) or cid

if toPosition == nil or Tile(toPosition) == nil then
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    return true
end

local checkAnvil = Tile(toPosition):getItemCountById(2555)
local checkBasin = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemCountById(1485)

if checkAnvil == 1 and checkBasin == 1 then
    if config[target.itemid] then
        local hasReagent = Tile(toPosition.x, toPosition.y + 1, toPosition.z):getItemById(config[target.itemid].material)
            if not hasReagent then
                Position(toPosition.x, toPosition.y + 1, toPosition.z):sendMagicEffect(CONST_ME_TUTORIALSQUARE)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need materials in order to craft.")
                return true
            end
        local itemLevel = config[target.itemid].level
        local smithingSkill = player:getCustomSkill(storage)
       
                if smithingSkill < itemLevel.min then
                    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need smithing level " .. itemLevel.min .. " for this combination.")
                    return true
                end
   
        if hasReagent then
            local rank = config[target.itemid].tiers
            local chance = math.floor((math.random(1, 100)) - ((smithingSkill * config[target.itemid].skillSuccessIncrement) - itemLevel.min))
           
            if chance <= itemLevel.success then
                local bonusBase = config[target.itemid].refine
                local bonusChance = math.floor(math.random(1, 100) - (smithingSkill * bonusBase.increment))
                    if bonusChance <= bonusBase.base and useItemStats == true then
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, Position(toPosition.x, toPosition.y - 1, toPosition.z))
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierOneItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local refineDice = math.floor(math.random(1,smithingSkill / config[target.itemid].refineLevel))
                                if refineDice < 1 then
                                    refineDice = 1
                                end
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                    for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                    end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                    if itemBefore ~= nil then
                                        itemBefore:remove()
                                    end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, Position(toPosition.x, toPosition.y - 1, toPosition.z))
                            local b = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getItemById(config[target.itemid].tierTwoItems[tierDice])
                            b:generateLooted(refineDice)
                            player:say("REFINED item crafted!", TALKTYPE_MONSTER_SAY)
                            player:getPosition():sendMagicEffect(CONST_ME_FIREWORK_RED)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.refinedItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    else
                        if smithingSkill < rank.second then
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierOneItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierOneItems[tierDice], 1, Position(toPosition.x, toPosition.y - 1, toPosition.z))
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        else
                            local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                            local tierAmount = 0
                            local getTable = config[target.itemid]
                                for k, v in pairs(getTable.tierTwoItems) do
                                    tierAmount = tierAmount + 1
                                end
                            local tierDice = math.floor(math.random(1,tierAmount))
                            local itemBefore = Tile(toPosition.x, toPosition.y - 1, toPosition.z):getTopDownItem()
                                if itemBefore ~= nil then
                                    itemBefore:remove()
                                end
                            hasReagent:remove(1)
                            removeCrystal:remove(1)
                            Game.createItem(config[target.itemid].tierTwoItems[tierDice], 1, Position(toPosition.x, toPosition.y - 1, toPosition.z))
                            player:say("Item crafted!", TALKTYPE_MONSTER_SAY)
                            Position(toPosition.x, toPosition.y - 1, toPosition.z):sendMagicEffect(CONST_ME_MAGIC_RED)
                            toPosition:sendMagicEffect(CONST_ME_BLOCKHIT)
                            local loopExp = config[target.itemid].xp
                                for i = loopExp.normalItem, 1, -1 do
                                    player:addCustomSkillTry(name, storage)
                                end
                        end
                    return true
                    end
            else
                local removeCrystal = Tile(toPosition):getItemById(target.itemid)
                player:sendTextMessage(MESSAGE_STATUS_SMALL, "Crafting failed.")
                toPosition:sendMagicEffect(CONST_ME_POFF)
                hasReagent:remove(1)
                removeCrystal:remove(1)
            return true
            end
        return true
        end
    else
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to place crystals on top of the anvil.")
    end
else
    player:sendTextMessage(MESSAGE_STATUS_SMALL, "You need to go to an special shop in order to craft.")
end
return true
end
 
question about craft wands and rods with refine status add to them.
is it possbole (without edit source) to make the wand/rod hit for more damage based on each refine level?

lets say
a level 7 wand/rod with +0 will hit 8-18
a level 7 wand/rod with +1 will hit for 9-19
a level 7 wand/rod with + 2 will hit 11-21
a level 7 wand/rod with + 3 will hit 14-24
a level 7 wand/rod with + 4 will hit 18-28
and so on.. (the refine level will add the same value to min and max damage)..

formula is add the refine level to the damage on top of the previous one.
wand/rod+3 refine = 14 min damage - 24 max damage.
so..
wand/rod+4 refine = 14+4 = new min damage (18) - 24+4 = new max damage (28)
 
As far as I know, no. Or at least not with Zbizu's system (It would add the +1, +2 but it won't modify the damage, only the range). I didn't experiment much with onHealthChange functions, but if we could check if player is sorcerer/druid and is using wand/rod in his weapon slot (which means the attack is coming from the weapon) we could add the damage amplification that way, checking first for the upgrade level it has so we know how much to add.
 
well, sounds like a pain tbh.

how about magic level.. can we include something from Zbizu's system that add 1 magic level per refine level?
this system is nearly perfect.
i can't have unbalanced systems its will kill the server.
just need to make sure all vocations can enjoy it equally.
 
Back
Top