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

CreatureEvent [TFS 1.1] Crafting System - ModalWindows

I'm guessing the skill name had a typo on it for scarab coin?

Was the storage, in scarab coin was 40010 and the right storage is 40011, and when i want to put more storages or more type of skills like Basic, Advanced And "Legendary" Smelting, the serv give a error
 
Was the storage, in scarab coin was 40010 and the right storage is 40011, and when i want to put more storages or more type of skills like Basic, Advanced And "Legendary" Smelting, the serv give a error

Code:
local training = {
        [40011] = "Basic Smelting",
        [40012] = "Advanced Smelting",
}
The skills that can be used by the system are defined here, but those skills also must exist in lib/skills.lua
 
How should look smelting?

When i check for egzample: Piece of Hell steel and click Expand, modal window just disappear.

No error in console :/ Someone can help me?
 
hey man, so i implemented this awesome system, but i get some errors in console when i start up.
Code:
>> Loading script systems
[Warning - Event::checkScript] Can not load script: scripts/crafting/smith.lua
cannot open data/actions/scripts/crafting/smith.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/smith.lua
cannot open data/actions/scripts/crafting/smith.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/smith.lua
cannot open data/actions/scripts/crafting/smith.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/smith.lua
cannot open data/actions/scripts/crafting/smith.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/smelt.lua
cannot open data/actions/scripts/crafting/smelt.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/tan.lua
cannot open data/actions/scripts/crafting/tan.lua: No such file or directory

this is my login.lua from data/creaturescripts/scripts

Code:
function onLogin(player)
   local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
   if player:getLastLoginSaved() <= 0 then
     loginStr = loginStr .. " Please choose your outfit."
     player:sendOutfitWindow()
   else
     if loginStr ~= "" then
       player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
     end

       for i = 40000, 40012 do
  if player:getStorageValue(i) < 10 then
  player:setStorageValue(i, 10)
  player:setStorageValue(i + 1000, 0)
  end
  end
    
     loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
   end
   player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
  

   -- Stamina
   nextUseStaminaTime[player.uid] = 0
  
   -- Promotion
   local vocation = player:getVocation()
   local promotion = vocation:getPromotion()
   if player:isPremium() then
     local value = player:getStorageValue(STORAGEVALUE_PROMOTION)
     if not promotion and value ~= 1 then
       player:setStorageValue(STORAGEVALUE_PROMOTION, 1)
     elseif value == 1 then
       player:setVocation(promotion)
     end
   elseif not promotion then
     player:setVocation(vocation:getDemotion())
   end

   -- Events
   player:registerEvent("PlayerDeath")
   player:registerEvent("DropLoot")
   player:registerEvent("smith_modal")
  player:registerEvent("smelt_modal")
  player:registerEvent("tan_modal")
   return true
end
 
hey man, so i implemented this awesome system, but i get some errors in console when i start up.
Code:
>> Loading script systems
[Warning - Event::checkScript] Can not load script: scripts/crafting/smith.lua
cannot open data/actions/scripts/crafting/smith.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/smith.lua
cannot open data/actions/scripts/crafting/smith.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/smith.lua
cannot open data/actions/scripts/crafting/smith.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/smith.lua
cannot open data/actions/scripts/crafting/smith.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/smelt.lua
cannot open data/actions/scripts/crafting/smelt.lua: No such file or directory
[Warning - Event::checkScript] Can not load script: scripts/crafting/tan.lua
cannot open data/actions/scripts/crafting/tan.lua: No such file or directory

this is my login.lua from data/creaturescripts/scripts

Code:
function onLogin(player)
   local loginStr = "Welcome to " .. configManager.getString(configKeys.SERVER_NAME) .. "!"
   if player:getLastLoginSaved() <= 0 then
     loginStr = loginStr .. " Please choose your outfit."
     player:sendOutfitWindow()
   else
     if loginStr ~= "" then
       player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
     end

       for i = 40000, 40012 do
  if player:getStorageValue(i) < 10 then
  player:setStorageValue(i, 10)
  player:setStorageValue(i + 1000, 0)
  end
  end
   
     loginStr = string.format("Your last visit was on %s.", os.date("%a %b %d %X %Y", player:getLastLoginSaved()))
   end
   player:sendTextMessage(MESSAGE_STATUS_DEFAULT, loginStr)
 

   -- Stamina
   nextUseStaminaTime[player.uid] = 0
 
   -- Promotion
   local vocation = player:getVocation()
   local promotion = vocation:getPromotion()
   if player:isPremium() then
     local value = player:getStorageValue(STORAGEVALUE_PROMOTION)
     if not promotion and value ~= 1 then
       player:setStorageValue(STORAGEVALUE_PROMOTION, 1)
     elseif value == 1 then
       player:setVocation(promotion)
     end
   elseif not promotion then
     player:setVocation(vocation:getDemotion())
   end

   -- Events
   player:registerEvent("PlayerDeath")
   player:registerEvent("DropLoot")
   player:registerEvent("smith_modal")
  player:registerEvent("smelt_modal")
  player:registerEvent("tan_modal")
   return true
end
It tells you exactly what the problem is. I keep my scripts in separate subfolders. Just put the scripts into the proper folders and that error will stop.
 
Is there an easy way to undo the crafts? Like select item from the list (if you have the item on yourself) and then remove the crafted item and randomly add the materials used.

I've been trying to use the table to do it, but its rather hard. Is not that easy with all the window options.
 
Is there an easy way to undo the crafts? Like select item from the list (if you have the item on yourself) and then remove the crafted item and randomly add the materials used.

I've been trying to use the table to do it, but its rather hard. Is not that easy with all the window options.
Liiike... have an option when you select the item from the list to either create one or destroy one?
 
yeah for exemple.. i did this with an NPC, but is fcking exhausting to do it with the more than 500 items that i made recipes for.. xD
Code:
if msgcontains(msg, 'plate armor') then
        npcHandler:say('You want to trade a plate armor for silver minerals?', cid)
        end
    if msgcontains(msg, 'yes') and getPlayerItemCount(cid, 26795) >= 1 then
            player:addItem(27007, math.random(1,4))
            player:removeItem(26795, 1)
                else

      if msgcontains(msg, 'yes') and getPlayerItemCount(cid, 26795) < 1 then
              npcHandler:say('You do NOT have that item.', cid)
              end
              return true
              end

So do this but with the same crafting system.. If you want to destroy the item, (if the cost for exemple is 8 silver mineral), it will give you random(1,4)..

Also just yesterday, I wanted to add money cost to recipes. But If you ask for 125 gold coins (id: 2148), people normally have platinum (id: 2152), and no gold coins. So its a bit messy..
I thing there was a "formula", somethin like gold coin == platinum coin == crystal coin (more elavorated obviously) which worked for this cases but dont really remember, and It doesnt
come to me right now the way to do it.

Also (this is just super extra), is it possible to show the item when you click on the list to see materials (and craft it if you have those materials)? To look at them. All my items are custom,
and most of the time, people doesnt know what they are crafting.

Any help would be appreciated!

Thanks for you time,
Great system!

~~Aeronx
 
yeah for exemple.. i did this with an NPC, but is fcking exhausting to do it with the more than 500 items that i made recipes for.. xD
Code:
if msgcontains(msg, 'plate armor') then
        npcHandler:say('You want to trade a plate armor for silver minerals?', cid)
        end
    if msgcontains(msg, 'yes') and getPlayerItemCount(cid, 26795) >= 1 then
            player:addItem(27007, math.random(1,4))
            player:removeItem(26795, 1)
                else

      if msgcontains(msg, 'yes') and getPlayerItemCount(cid, 26795) < 1 then
              npcHandler:say('You do NOT have that item.', cid)
              end
              return true
              end

So do this but with the same crafting system.. If you want to destroy the item, (if the cost for exemple is 8 silver mineral), it will give you random(1,4)..

Also just yesterday, I wanted to add money cost to recipes. But If you ask for 125 gold coins (id: 2148), people normally have platinum (id: 2152), and no gold coins. So its a bit messy..
I thing there was a "formula", somethin like gold coin == platinum coin == crystal coin (more elavorated obviously) which worked for this cases but dont really remember, and It doesnt
come to me right now the way to do it.

Also (this is just super extra), is it possible to show the item when you click on the list to see materials (and craft it if you have those materials)? To look at them. All my items are custom,
and most of the time, people doesnt know what they are crafting.

Any help would be appreciated!

Thanks for you time,
Great system!

~~Aeronx
Well, I'm not really very actively into OT in the past year or so
Probably not gonna be writing any new code, but I can give you some hints
if you want to add money, something like this would work
Code:
[3] = {name = "Blue Robe", learned = false, learnStorage = 0, storage = {40003}, level = {30}, tries = 4, count = 1, id = 2656, 
    needed = {
        [1] = {name = "blue pieces of cloth", id = 5912, count = 50},
        [2] = {name = "raw leather", id = 22539, count = 1},
        [3] = {name = "money", amount = 2000},
    }
},
from there, you can modify the code for checking/removing of requirements. alternatively if you wanted to make it a flat amount, you could just add a check for player:getMoney(). Could even make it an amount multiplied by the level requirement of the item, or something like that, to keep it dynamic. both these solutions would be faster and easier than adding individual costs to items and coding it into the system.
as for breaking down items, you could add another button on the menu that shows requirement, and you could name that button like.. Break or something like that.
then write a handler for it in the button just like the ones that already exist, could just have it check if you have one, then give you some of the materials back randomly. shouldn't take too much for this part.
As for displaying the item, this is unfortunately not supported by modalwindows. The only way to display items is to use text dialogs like a book does. However from here, you cannot get back into the modalwindow or craft the item, because it's not a modalwindow and does not have customizable mechanics.
 
Code:
Lua Script Error: [Action Interface]
data/actions/scripts/crafting/smelt.lua:onUse
data/lib/smelt.lua:98: attempt to call method 'getCSkill' (a nil value)
stack traceback:
        [C]: in function 'getCSkill'
        data/lib/smelt.lua:98: in function 'sendProductWindow'
        data/actions/scripts/crafting/smelt.lua:6: in function <data/actions/scripts/crafting/smelt.lua:1>

Hi I'm getting this error and Have no idea what to do. I'm using TFS 1.2. Been trying to add skills manually via talk action doesn't help and when I remove for loop in line 98 it loads normally but then further interaction are impossible.
Thank you
 
Code:
Lua Script Error: [Action Interface]
data/actions/scripts/crafting/smelt.lua:onUse
data/lib/smelt.lua:98: attempt to call method 'getCSkill' (a nil value)
stack traceback:
        [C]: in function 'getCSkill'
        data/lib/smelt.lua:98: in function 'sendProductWindow'
        data/actions/scripts/crafting/smelt.lua:6: in function <data/actions/scripts/crafting/smelt.lua:1>

Hi I'm getting this error and Have no idea what to do. I'm using TFS 1.2. Been trying to add skills manually via talk action doesn't help and when I remove for loop in line 98 it loads normally but then further interaction are impossible.
Thank you
Likely you don't have the skills.lua in your lib folder
if you don't want to use the skills, you can use this smelt.lua instead
Code:
-- config
local useSkills = false
local modalId = 1003
local choice = {}
local recipes = {
    [1] = {name = "Iron Ingot", subname = "iron ore", count = 1, storage = 40011, level = 30, tries = 2, id = 18337,
        needed = {
            [1] = {name = "iron ore", id = 5880, count = 2}
        }
    },
    [2] = {name = "Iron Ingot", subname = "piece of iron", count = 1, storage = 40011, level = 20, tries = 1, id = 18337,
        needed = {
            [1] = {name = "pieces of iron", id = 2225, count = 5}
        }
    },
    [3] = {name = "Iron Ore", count = 3, storage = 40011, level = 10, tries = 1, id = 5880,
        needed = {
            [1] = {name = "vein of ore", id = 18429, count = 1}
        }
    },
    [4] = {name = "Huge Chunk of Crude Iron", count = 1, storage = 40011, level = 40, tries = 3, id = 5892, 
        needed = {
            [1] = {name = "iron ingots", id = 18337, count = 5}
        }
    },
    [5] = {name = "Piece of Iron", subname = "nails", count = 1, storage = 40011, level = 10, tries = 1, id = 2225, 
        needed = {
            [1] = {name = "nails", id = 8309, count = 2}
        }
    },
    [6] = {name = "Pieces of Iron", subname = "metal spike", count = 2, storage = 40011, level = 10, tries = 1, id = 2225, 
        needed = {
            [1] = {name = "metal spike", id = 11215, count = 1}
        }
    },
    [7] = {name = "Pieces of Iron", subname = "gear wheel", count = 5, storage = 40011, level = 10, tries = 1, id = 2225, 
        needed = {
            [1] = {name = "gear wheel", id = 9690, count = 1}
        }
    },
    [8] = {name = "Pieces of Iron", subname = "spiked iron ball", count = 3, storage = 40011, level = 10, tries = 1, id = 2225, 
        needed = {
            [1] = {name = "spiked iron ball", id = 11325, count = 1}
        }
    },
    [9] = {name = "Piece of Royal Steel", count = 1, storage = 40012, level = 60, tries = 4, id = 5887, 
        needed = {
            [1] = {name = "iron ore", id = 5880, count = 1},
            [2] = {name = "gold ore", id = 6547, count = 1}
        }
    },
    [10] = {name = "Piece of Draconian Steel", count = 1, storage = 40012, level = 50, tries = 3, id = 5889, 
        needed = {
            [1] = {name = "dragon shield", id = 2516, count = 1}
        }
    },
    [11] = {name = "Piece of Hell Steel", count = 1, storage = 40012, level = 40, tries = 2, id = 5888, 
        needed = {
            [1] = {name = "iron ores", id = 5880, count = 3},
            [2] = {name = "soul orbs", id = 5944, count = 3}
        }
    },
    [12] = {name = "Gold Ore", count = 2, storage = 40012, level = 10, tries = 1, id = 6547, 
        needed = {
            [1] = {name = "pulverized ore", id = 18427, count = 1}
        }
    },
    [13] = {name = "Gold Nugget", count = 1, storage = 40012, level = 20, tries = 2, id = 2157, 
        needed = {
            [1] = {name = "gold ore", id = 6547, count = 3}
        }
    },
    [14] = {name = "Gold Ingot", count = 1, storage = 40012, level = 30, tries = 3, id = 9971, 
        needed = {
            [1] = {name = "gold nuggets", id = 2157, count = 5}
        }
    },
   

}
local training = {
    [40011] = "Basic Smelting",
    [40012] = "Advanced Smelting",
}
function Player:hasReq(recipe)
    for i = 1, #recipe.needed do
        if self:getItemCount(recipe.needed[i].id) < recipe.needed[i].count then
            return false
        end
    end
    return true
end

function Player:sendProductWindow()
    local window = ModalWindow(modalId, "Smelting", "Expand the item you want to produce to view the requirements.\nYou are trained in the following specialties:\n")
    local choices = 0
    if useSkills then
        local temp = 0
        for i = 40011, 40012 do
            if self:getCSkill(training[i]) >= 10 then
                temp = temp + 1
                window:setMessage(window:getMessage() .. training[i] .. " (" .. self:getCSkill(training[i]) .. ")\n")
            end
        end
   
        if temp == 0 then
            window:setMessage(window:getMessage() .. "No specialty training.\n")
        end
    end
    for i = 1, #recipes do
        if recipes[i].subname then
            if recipes[i].count > 1 then
                window:addChoice(i, recipes[i].count .. " " .. recipes[i]["name"] .. " (" .. recipes[i].subname .. ")")
            else
                window:addChoice(i, recipes[i]["name"] .. " (" .. recipes[i].subname .. ")")
            end
        else
            if recipes[i].count > 1 then
                window:addChoice(i, recipes[i].count .. " " .. recipes[i]["name"])
            else
                window:addChoice(i, recipes[i]["name"])
            end
        end
        choices = choices + 1
    end
    if choices > 0 then
        window:addButton(1, "Expand")
        window:setDefaultEnterButton(1)
    end
    window:addButton(2, "Exit")
    window:setDefaultEscapeButton(2)
    window:sendToPlayer(self)
    return true
end

function Player:sendRecipeWindow(product)
    local window = ModalWindow(modalId + 1, product["name"], "To produce this item, you need:\n")
   
    for i = 1, #product.needed do
        window:setMessage(window:getMessage() .. product.needed[i].count .. " " .. product.needed[i].name .. " (" .. self:getItemCount(product.needed[i].id) .. ")\n")
    end
    if useSkills then
        if product.storage then
            local lev = self:getCSkill(training[product.storage])
            window:setMessage(window:getMessage() .. training[product.storage] .. " " .. product.level .. " (" .. lev .. ")\n")
        end
    end
    for j = 1, #product.needed do
        if self:getItemCount(product.needed[j].id) < product.needed[j].count or (useSkills and (product.storage and self:getCSkill(training[product.storage]) < product.level)) then
            return window:addButton(2, "Back"), window:setDefaultEscapeButton(2), window:setDefaultEnterButton(2), window:sendToPlayer(self)
        end
    end
    window:addButton(1, "Make It!")
    window:setDefaultEnterButton(1)
    window:addButton(2, "Back")
    window:setDefaultEscapeButton(2)
    window:sendToPlayer(self)
    return true
end

function Player:productWindowChoice(windowId, buttonId, choiceId)
    local p = self:getGuid()
    if windowId == modalId then
        if buttonId == 1 then
            choice[p] = choiceId
            self:sendRecipeWindow(recipes[choiceId])
            return true
        else
            choice[p] = nil
            return false
        end
    end
    return false
end

function Player:recipeWindowChoice(windowId, buttonId, choiceId)
    local p = self:getGuid()
    if windowId == modalId + 1 then
        if buttonId == 1 then
            for i = 1, #recipes[choice[p]].needed do
                self:removeItem(recipes[choice[p]].needed[i].id, recipes[choice[p]].needed[i].count)
            end
            self:addItem(recipes[choice[p]].id, recipes[choice[p]].count)
            self:sendTextMessage(MESSAGE_INFO_DESCR, "You have crafted " .. recipes[choice[p]].count .. " " .. recipes[choice[p]].name .. "!")
            if useSkills then
                self:addCSkillTries(training[recipes[choice[p]].storage], recipes[choice[p]].tries)
            end
            return self:hasReq(recipes[choice[p]]) and self:sendRecipeWindow(recipes[choice[p]]) or self:sendProductWindow()
        elseif buttonId == 2 then
            self:sendProductWindow()
        end
        return false
    end
   
    return false
end
if you have the same problem with the other scripts (smith and tan) you'll have to look at what I've done here and reproduce it as needed.
best solution is to just add skills.lua to your lib folder and remove the storages from any items you don't want to use skills on.
example:
Code:
[1] = {name = "Iron Ingot", subname = "iron ore", count = 1, storage = 40011, level = 30, tries = 2, id = 18337,
would become
Code:
[1] = {name = "Iron Ingot", subname = "iron ore", count = 1, level = 30, tries = 2, id = 18337,
 
Thank you. I have added skills in the lib folder and it is working now.
Could help me adding options to the smelting script like in smiting one. When I tried to adapt smith script array it just give me an error and im not too experienced with lua yet.
 
Hi bro, I'm testing the system and it works excellent, but I would like to know if the menus can be modified? Example subdivide the categories into 3 as basic, medium and expert leaving basic items easier to craft, in the middle those that are a little more difficult and so on?
 
NVM, Solved.
Thought I don't need this fix since data/lib already existed.

--------

Hey,

Got this error:
Lua:
Lua Script Error: [Action Interface]
data/actions/scripts/crafting/smith.lua:onUse
data/actions/scripts/crafting/smith.lua:6: attempt to call method 'sendEquipmentWindow' (a nil value)
stack traceback:
        [C]: in function 'sendEquipmentWindow'
        data/actions/scripts/crafting/smith.lua:6: in function <data/actions/scripts/crafting/smith.lua:1>

TFS1.4.
 
Last edited:
What is the best practice for a new charcter to start with only several receipes "learned" and all other possible receiples to be obtained via using items, gaining xp/skill level or being bought from NPC?
 
Back
Top