• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Lua Getting values from LUA Tables.

elnelson

Lunaria World Dev
Joined
Jun 20, 2009
Messages
579
Solutions
2
Reaction score
58
Location
México
Hello, good morning!

I have a crafting system that uses a RNG to get skill level. But im struggling with getting values from the table i made.

Lua:
local itemlvl = {
    [1] = {bar=12808, exp = 10, amount},
    [2] = {bar=12814, exp = 50, amount},
    [3] = {bar=12815, exp = 100, amount}
    }
    local professionSkill = getPlayerStorageValue(cid, 1039) 
    if math.random(1, professionSkill*1.15) >= professionSkill then
    if professionSkill < 500 then
    setPlayerStorageValue(cid, 1039, professionSkill + 1)
    doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "You advanced in forging ["..professionSkill.."].")
    end
    end


I want to raise the chances to get the level if the item is better and uses more amount of items to craft.
At the moment i have 3 tier ore bars (copper, silver and mithril)
(E.G; recipe for brass armor uses 3 copper bar, then the math.random formula will be;
math.random(1+10(exp of bar)*3(amount of bars), professionSkill*1.15) >= professionSkil

If want to create a plate armor that uses 5 silver bars then
math.random(1+50(exp)*5(amount), professionSkill*1.15) >= professionSkil

Hope you guys could orientate me how to achieve this, in advance thanks!
 
Solution
Worked via teamviewer with elnelson to find a good solution to his overall problem.
To the original question he posed in this thread
Lua:
self.type.items[1][1] -- itemid
self.type.items[1][2] -- count
This was the answer.
like this..?
You really need to work on your explanations. lol
Lua:
local itemID = ????
local math_dot_random_formula = 0
for i = 1, #itemlvl do
    if itemID == itemlvl[i].bar then
        math_dot_random_formula = math.random(1 + itemlvl[i].exp * itemlvl[i].amount, professionSkill * 1.15)
        break
    end
end
if math_dot_random_formula == 0 then
    print("Item not found in table.")
end
 
like this..?
You really need to work on your explanations. lol
Lua:
local itemID = ????
local math_dot_random_formula = 0
for i = 1, #itemlvl do
    if itemID == itemlvl[i].bar then
        math_dot_random_formula = math.random(1 + itemlvl[i].exp * itemlvl[i].amount, professionSkill * 1.15)
        break
    end
end
if math_dot_random_formula == 0 then
    print("Item not found in table.")
end
sorry i was a little out of time, but im going to try to explain better.

If player craft a higher tier item (that needs better resources, and certain amount of materials) i want to raise the chances of getting the skill level.

If a player craft a brass helmet (lowest tier item), he wont get the bonus chance (or may the the lowest)
If a player craft a brass legs(requires level 5 in forge and 2 copper bars) then his chances will be better (increasing the lowest range)
If a player craft crown armor (requires 7 mithril bar) then the chances will be much better.

So, the formula will change based on the item you are crafting.
Hope this is enough to understand the issue :D

Now these are the scripts. They work with a pair of libraries (posted below)
Ironhammer.lua (data/actions)
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local anvil    = getThingFromPos({x=toPosition.x,y=toPosition.y,z=toPosition.z,stackpos=1})

if not(getTileItemById(toPosition,2555).itemid >= 1) then
        return true,doPlayerSendCancel(cid,"Use your hammer on the anvil.")
end
   
local recipe = nil
    for _, v in ipairs(Recipes) do
        recipe = v:get(toPosition)
        if(recipe ~= false) then
            break
        end
    end
    if(recipe) then
        recipe:create(cid)
    else
        doPlayerSendCancel(cid, "This is not a valid recipe.")
    end
    return true
end
[/spoiler]

forgesystem.lua (libs) This is the library that uses all functions for the scripts
Lua:
RecipeHandler = {
    itemtype = 0,
    items = {},
    level = 1,
    maglevel = 0,
    skills = {[0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0}
}

Forge = {
    type = nil,
    position = nil,
    magicEffect = CONST_ME_HITAREA,

    messages = {
        class = MESSAGE_STATUS_DEFAULT,
        success = "You have successfully forged a %s.",
        needskill = "You don't have enough %s to create a %s.",
        needlevel = "You need forge level %s  to create a %s.",
        needmaglevel = "You need magic level %s to create a %s."
    }
}


function RecipeHandler:new(itemtype, items, level, maglevel, skills)
    local obj = {
        itemtype = (itemtype or 0),
        items = (items or {}),
        level = (level or 1),
        maglevel = (maglevel or 0),
        skills = (skills or {[0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0})
    }
    table.insert(Recipes, obj)
    return setmetatable(obj, {__index = self})
end
function RecipeHandler:setItem(itemtype)
    self.itemtype = (itemtype or 0)
end
function RecipeHandler:setRecipe(...)
    self.items = {...}
end
function RecipeHandler:setRecipeItem(itemid, amount)
    table.insert(self.items, {itemid, amount})
end
function RecipeHandler:setSkill(skillid, value)
    self.skills[skillid] = value
end
function RecipeHandler:setLevel(value)
    self.level = value
end
function RecipeHandler:setMagLevel(value)
    self.maglevel = value
end
function RecipeHandler:check(position)
    local match = false
    for n, item in ipairs(self.items) do
        local thing = getTileItemById(position, item[1])
        if thing.uid > 0 and math.max(1, thing.type) == item[2] then
            if n == #self.items then
                match = true
            end
        else
            break
        end
    end
    return match
end

function RecipeHandler:get(position)
    if self:check(position) == true then
     return setmetatable({type = self, position = position}, {__index = Forge})
    end
    return false
end

function Forge:create(cid)
    if self.type.itemid == 0 then
        print("[FORGE SYSTEM - ERROR] ATTEMPT TO CREATE A RECIPE ITEMID 0")
        return
    end
    local status = true
    if(cid) then
        if getPlayerStorageValue(cid, 1039) < self.type.level then
            doPlayerSendTextMessage(cid, self.messages.class, self.messages.needlevel:format(self.type.level, getItemNameById(self.type.itemtype)))
            return
        end
        if getPlayerMagLevel(cid) < self.type.maglevel then
            doPlayerSendTextMessage(cid, self.messages.class, self.messages.needmaglevel:format(self.type.maglevel, getItemNameById(self.type.itemtype)))
            return
        end
        for skillid, value in pairs(self.type.skills) do
            if getPlayerSkillLevel(cid, skillid) < value then
                status = false
                doPlayerSendTextMessage(cid, self.messages.class,                    self.messages.needskill:format(SKILL_NAMES[skillid], getItemNameById(self.type.itemtype)))
                break
            end
        end
    end

   if status == true then
        for _, item in ipairs(self.type.items) do
            local thing = getTileItemById(self.position, item[1])
            doRemoveItem(thing.uid, item[2])
        end
        doSendMagicEffect(self.position, self.magicEffect)

--This is the part im trying to work, im thinking this can be done better on the iron-hammer.lua
    local itemlvl = {
    [1] = {bar=12808, exp = 10}, --copper bar (lowest tier)
    [2] = {bar=12814, exp = 50}, --silver bar (mid tier)
    [3] = {bar=12815, exp = 100} --mithril bar (high tier)
    } --

    local professionSkill = getPlayerStorageValue(cid, 1039)
    local R = math.random(professionSkill,500)
    if math.random(1, professionSkill*1.15) >= professionSkill then
--This is where i need some magic to make it work
    if professionSkill < 500 then     setPlayerStorageValue(cid, 1039, professionSkill + 1)
    doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "You advanced in forging ["..professionSkill.."].")
    end
    end

--End of the part that gives the skill

    if R < 100 then
        --doCreateItem(self.type.itemtype, self.position)
        doSendAnimatedText(self.position, "FAILED", TEXTCOLOR_RED)
        doPlayerSendTextMessage(cid, self.messages.class, "Your forge has failed.")
    end
    if R >= 100 and R < 500 then
        print(itemlvl[i])
        print(itemlvl[1])
        doCreateItem(self.type.itemtype, self.position)
        doSendAnimatedText(self.position, "SUCCESS!", TEXTCOLOR_LIGHTBLUE)
        doPlayerSendTextMessage(cid, self.messages.class, self.messages.success:format(getItemNameById(self.type.itemtype)))
    end
        if R >= 500 then
            doSendAnimatedText(self.position, "2X SUCCESS", TEXTCOLOR_YELLOW)
        doCreateItem(self.type.itemtype, self.position)
        doCreateItem(self.type.itemtype, self.position)
        doPlayerSendTextMessage(cid, self.messages.class, self.messages.success:format(getItemNameById(self.type.itemtype)))
    end
    end
end
dofile(getDataDir() .."/lib/recipes.lua")
[/spoiler]

recipes.lua --This is another lib that stores the recipes of the items
Lua:
Recipes = {}

--Copper Bars

brasshelmet = RecipeHandler:new()
brasshelmet:setItem(2460) -- ID of item to craft.
brasshelmet:setRecipeItem(12808, 1) --ID of copper bar, amount of copper bar.
brasshelmet:setLevel(1) --Forge skill needed to craft this item

brasslegs = RecipeHandler:new()
brasslegs:setItem(2478)
brasslegs:setRecipeItem(12808, 2)
brasslegs:setLevel(5)

brassarmor = RecipeHandler:new()
brassarmor:setItem(2465)
brassarmor:setRecipeItem(12808, 3)
brassarmor:setLevel(10)

--Silver bar

shadowsceptre = RecipeHandler:new()
shadowsceptre:setItem(7451)
shadowsceptre:setRecipeItem(12814, 3)
shadowsceptre:setLevel(40)

djinnblade = RecipeHandler:new()
djinnblade:setItem(7451)
djinnblade:setRecipeItem(12814, 4)
djinnblade:setLevel(40)

nobleaxe = RecipeHandler:new()
nobleaxe:setItem(7451)
nobleaxe:setRecipeItem(12814, 5)
nobleaxe:setLevel(40)




--mithril bar

crownhelmet = RecipeHandler:new()
crownhelmet:setItem(2491)
crownhelmet:setRecipeItem(12815, 6)
crownhelmet:setLevel(40)

crownarmor = RecipeHandler:new()
crownarmor:setItem(2487)
crownarmor:setRecipeItem(12815, 7)
crownarmor:setLevel(40)

crownlegs = RecipeHandler:new()
crownlegs:setItem(2488)
crownlegs:setRecipeItem(12815, 8)
crownlegs:setLevel(40)

[/spoiler]
 
sorry i was a little out of time, but im going to try to explain better.

If player craft a higher tier item (that needs better resources, and certain amount of materials) i want to raise the chances of getting the skill level.

If a player craft a brass helmet (lowest tier item), he wont get the bonus chance (or may the the lowest)
If a player craft a brass legs(requires level 5 in forge and 2 copper bars) then his chances will be better (increasing the lowest range)
If a player craft crown armor (requires 7 mithril bar) then the chances will be much better.

So, the formula will change based on the item you are crafting.
Hope this is enough to understand the issue :D

Now these are the scripts. They work with a pair of libraries (posted below)
Ironhammer.lua (data/actions)
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
local anvil    = getThingFromPos({x=toPosition.x,y=toPosition.y,z=toPosition.z,stackpos=1})

if not(getTileItemById(toPosition,2555).itemid >= 1) then
        return true,doPlayerSendCancel(cid,"Use your hammer on the anvil.")
end

local recipe = nil
    for _, v in ipairs(Recipes) do
        recipe = v:get(toPosition)
        if(recipe ~= false) then
            break
        end
    end
    if(recipe) then
        recipe:create(cid)
    else
        doPlayerSendCancel(cid, "This is not a valid recipe.")
    end
    return true
end
[/spoiler]

forgesystem.lua (libs) This is the library that uses all functions for the scripts
Lua:
RecipeHandler = {
    itemtype = 0,
    items = {},
    level = 1,
    maglevel = 0,
    skills = {[0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0}
}

Forge = {
    type = nil,
    position = nil,
    magicEffect = CONST_ME_HITAREA,

    messages = {
        class = MESSAGE_STATUS_DEFAULT,
        success = "You have successfully forged a %s.",
        needskill = "You don't have enough %s to create a %s.",
        needlevel = "You need forge level %s  to create a %s.",
        needmaglevel = "You need magic level %s to create a %s."
    }
}


function RecipeHandler:new(itemtype, items, level, maglevel, skills)
    local obj = {
        itemtype = (itemtype or 0),
        items = (items or {}),
        level = (level or 1),
        maglevel = (maglevel or 0),
        skills = (skills or {[0] = 0, [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0})
    }
    table.insert(Recipes, obj)
    return setmetatable(obj, {__index = self})
end
function RecipeHandler:setItem(itemtype)
    self.itemtype = (itemtype or 0)
end
function RecipeHandler:setRecipe(...)
    self.items = {...}
end
function RecipeHandler:setRecipeItem(itemid, amount)
    table.insert(self.items, {itemid, amount})
end
function RecipeHandler:setSkill(skillid, value)
    self.skills[skillid] = value
end
function RecipeHandler:setLevel(value)
    self.level = value
end
function RecipeHandler:setMagLevel(value)
    self.maglevel = value
end
function RecipeHandler:check(position)
    local match = false
    for n, item in ipairs(self.items) do
        local thing = getTileItemById(position, item[1])
        if thing.uid > 0 and math.max(1, thing.type) == item[2] then
            if n == #self.items then
                match = true
            end
        else
            break
        end
    end
    return match
end

function RecipeHandler:get(position)
    if self:check(position) == true then
     return setmetatable({type = self, position = position}, {__index = Forge})
    end
    return false
end

function Forge:create(cid)
    if self.type.itemid == 0 then
        print("[FORGE SYSTEM - ERROR] ATTEMPT TO CREATE A RECIPE ITEMID 0")
        return
    end
    local status = true
    if(cid) then
        if getPlayerStorageValue(cid, 1039) < self.type.level then
            doPlayerSendTextMessage(cid, self.messages.class, self.messages.needlevel:format(self.type.level, getItemNameById(self.type.itemtype)))
            return
        end
        if getPlayerMagLevel(cid) < self.type.maglevel then
            doPlayerSendTextMessage(cid, self.messages.class, self.messages.needmaglevel:format(self.type.maglevel, getItemNameById(self.type.itemtype)))
            return
        end
        for skillid, value in pairs(self.type.skills) do
            if getPlayerSkillLevel(cid, skillid) < value then
                status = false
                doPlayerSendTextMessage(cid, self.messages.class,                    self.messages.needskill:format(SKILL_NAMES[skillid], getItemNameById(self.type.itemtype)))
                break
            end
        end
    end

   if status == true then
        for _, item in ipairs(self.type.items) do
            local thing = getTileItemById(self.position, item[1])
            doRemoveItem(thing.uid, item[2])
        end
        doSendMagicEffect(self.position, self.magicEffect)

--This is the part im trying to work, im thinking this can be done better on the iron-hammer.lua
    local itemlvl = {
    [1] = {bar=12808, exp = 10}, --copper bar (lowest tier)
    [2] = {bar=12814, exp = 50}, --silver bar (mid tier)
    [3] = {bar=12815, exp = 100} --mithril bar (high tier)
    } --

    local professionSkill = getPlayerStorageValue(cid, 1039)
    local R = math.random(professionSkill,500)
    if math.random(1, professionSkill*1.15) >= professionSkill then
--This is where i need some magic to make it work
    if professionSkill < 500 then     setPlayerStorageValue(cid, 1039, professionSkill + 1)
    doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "You advanced in forging ["..professionSkill.."].")
    end
    end

--End of the part that gives the skill

    if R < 100 then
        --doCreateItem(self.type.itemtype, self.position)
        doSendAnimatedText(self.position, "FAILED", TEXTCOLOR_RED)
        doPlayerSendTextMessage(cid, self.messages.class, "Your forge has failed.")
    end
    if R >= 100 and R < 500 then
        print(itemlvl[i])
        print(itemlvl[1])
        doCreateItem(self.type.itemtype, self.position)
        doSendAnimatedText(self.position, "SUCCESS!", TEXTCOLOR_LIGHTBLUE)
        doPlayerSendTextMessage(cid, self.messages.class, self.messages.success:format(getItemNameById(self.type.itemtype)))
    end
        if R >= 500 then
            doSendAnimatedText(self.position, "2X SUCCESS", TEXTCOLOR_YELLOW)
        doCreateItem(self.type.itemtype, self.position)
        doCreateItem(self.type.itemtype, self.position)
        doPlayerSendTextMessage(cid, self.messages.class, self.messages.success:format(getItemNameById(self.type.itemtype)))
    end
    end
end
dofile(getDataDir() .."/lib/recipes.lua")
[/spoiler]

recipes.lua --This is another lib that stores the recipes of the items
Lua:
Recipes = {}

--Copper Bars

brasshelmet = RecipeHandler:new()
brasshelmet:setItem(2460) -- ID of item to craft.
brasshelmet:setRecipeItem(12808, 1) --ID of copper bar, amount of copper bar.
brasshelmet:setLevel(1) --Forge skill needed to craft this item

brasslegs = RecipeHandler:new()
brasslegs:setItem(2478)
brasslegs:setRecipeItem(12808, 2)
brasslegs:setLevel(5)

brassarmor = RecipeHandler:new()
brassarmor:setItem(2465)
brassarmor:setRecipeItem(12808, 3)
brassarmor:setLevel(10)

--Silver bar

shadowsceptre = RecipeHandler:new()
shadowsceptre:setItem(7451)
shadowsceptre:setRecipeItem(12814, 3)
shadowsceptre:setLevel(40)

djinnblade = RecipeHandler:new()
djinnblade:setItem(7451)
djinnblade:setRecipeItem(12814, 4)
djinnblade:setLevel(40)

nobleaxe = RecipeHandler:new()
nobleaxe:setItem(7451)
nobleaxe:setRecipeItem(12814, 5)
nobleaxe:setLevel(40)




--mithril bar

crownhelmet = RecipeHandler:new()
crownhelmet:setItem(2491)
crownhelmet:setRecipeItem(12815, 6)
crownhelmet:setLevel(40)

crownarmor = RecipeHandler:new()
crownarmor:setItem(2487)
crownarmor:setRecipeItem(12815, 7)
crownarmor:setLevel(40)

crownlegs = RecipeHandler:new()
crownlegs:setItem(2488)
crownlegs:setRecipeItem(12815, 8)
crownlegs:setLevel(40)

[/spoiler]
Right.. but that's just math.

I thought you just wanted to figure out how to grab the items from the table to use in your math.random equation?

If you want help creating the math portion of the script, I can help there as well, but you need to make it clear what you are actually asking for help with.
 
Right.. but that's just math.

I thought you just wanted to figure out how to grab the items from the table to use in your math.random equation?

If you want help creating the math portion of the script, I can help there as well, but you need to make it clear what you are actually asking for help with.

Yeah its pure math, but i need to add the values of the table to the formula, and thats the struggle im facing on. im trying to print the values but the appear nil on the console, i cant make it work x.x

to summarize the objective, i want to increase the chances of getting the skill if the player craft better items, this can be done with different ways. I was thinking on affect the lowest range (math.random(1+skillneed*tierResource+amount , skilllevel*1.15) >= skilllevel)

But there may be another ways to make it better.

is there something that was not clear at all? hehe im trying my best tho

BTW: gratz on your 2k likes :p
 
Last edited:
Worked via teamviewer with elnelson to find a good solution to his overall problem.
To the original question he posed in this thread
Lua:
self.type.items[1][1] -- itemid
self.type.items[1][2] -- count
This was the answer.
 
Solution
Back
Top