• 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 Upgrade system + auction system

gmstrikker

Well-Known Member
Joined
Jul 30, 2014
Messages
458
Solutions
1
Reaction score
50
Hello guys, i've helping my friend in him project
And with searches here on forum i edit this auction system almost exactly like he want (thanks to @tokenzz , @slawkens , and me XD)
But there is only one thing that i don't find and don't know how to do
It's been hard to me and i need a experient member to help me

Let this upgrade items system:
PHP:
--PERFECT UPGRADE SYSTEM

    UpgradeHandler = {
        nameLv = {
            [1] = "UNIQ",
            [2] = "RARE",
            [3] = "EPIC"
        },
        levels = {
            [1] = {50, false, false},
            [2] = {20, false, false},
            [3] = {10, true, true}
        },
        broadcast = 4,
        attributes = {
            ["attack"] = 3,
            ["defense"] = 2,
            ["armor"] = 1
        },
        message = {
              console = "Trying to refine %s to level +%s with %s%% success rate.",
              success = "You have upgraded %s to level +%s",
              fail = "You have failed in upgrade of %s to level +%s",
              downgrade = "The upgrade level of %s has downgraded to +%s",
              erase = "The upgrade level of %s has been erased.",
              maxlevel = "The targeted %s is already on max upgrade level.",
              notupgradeable = "This item is not upgradeable.",
              broadcast = "The player %s was successful in upgrading %s to level +%s.\nCongratulations!!",
              invalidtool = "This is not a valid upgrade tool.",
              toolrange = "This upgrade tool can only be used in items with level between +%s and +%s"
        },
        tools = {
            [8306] = {range = {0, 10}, info = {chance = 0, removeable = true}},
            [8300] = {range = {0, 10}, info = {chance = 20, removeable = true}}
        },
        isEquipment = function(self)
            local weaponType = self:getItemWeaponType()
            return ((weaponType > 0 and weaponType < 8) or self.item.armor ~= 0)
        end,
        setItemName = function(self, name)
            return doItemSetAttribute(self.item.uid, "name", name)
        end,
        chance = function(self)
            local chances = {}
            chances.upgrade = (self.levels[self.item.level + 1][1] or 100)
            chances.downgrade = (self.item.level * 5)
            chances.erase = (self.item.level * 3)
            return chances
        end
    }

    function UpgradeHandler:new(item)
        local obj, ret = {}
        obj.item = {}
        obj.item.level = 0
        obj.item.uid = item.uid
        for key, value in pairs(getItemInfo(item.itemid)) do
            obj.item[key] = value
        end
        ret = setmetatable(obj, {
            __index = function(self, index)
                if _G[index] then
                    return (setmetatable({callback = _G[index]},
                        {__call = function(self, ...)
                            return self.callback(item.uid, ...)
                        end}
                    ))
                else
                    return UpgradeHandler[index]
                end
        end})

        if ret:isEquipment() then
            ret:update()
            return ret
        end
        return false
    end


    function UpgradeHandler:update()
       -- this will return the level by the quality or 0 if it has no quality.
        self.item.level = 0
        for r, v in ipairs(self.nameLv) do
            if self:getItemName():find(v) then
                self.item.level = r
            end
        end
    end

    function UpgradeHandler:refine(uid, item)
        if not self.item then
            doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, self.message.notupgradeable)
            return "miss"
        end

        local tool = self.tools[item.itemid]
        if(tool == nil) then
            doPlayerSendTextMessage(uid, MESSAGE_EVENT_DEFAULT, self.message.invalidtool)
            return "miss"
        end

        if(self.item.level > #self.levels) then
            doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.maxlevel:format(self.item.name))
            return "miss"
        end

        if(tool.range[1] and self.item.level < tool.range[1]) or (tool.range[2] and self.item.level >= tool.range[2]) then
            doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.toolrange:format(unpack(tool.range)))
            return "miss"
        end

        local chance = (self:chance().upgrade + tool.info.chance)
        doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, self.message.console:format(self.item.name, (self.item.level + 1), math.min(100, chance)))
        if(tool.info.removeable == true) then
            doRemoveItem(item.uid, 1)
        end

        if chance * 100 > math.random(1, 10000) then
            doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_ORANGE, self.message.success:format(self.item.name, (self.item.level + 1)))
            if (self.item.level + 1) >= self.broadcast then
                doBroadcastMessage(self.message.broadcast:format(getCreatureName(uid), self.item.name, (self.item.level + 1)))
            end
            -- it says if the item's level is greater then 0 (meaning is level equal to 1 or more) if it is add 1 more
            -- if the current level equals 0 add 1 to it
            self:setItemName(self.item.level > 0 and self.nameLv[self.item.level + 1].." "..(self:getItemName():gsub(self.nameLv[self.item.level].." ", "")) or self.nameLv[1].." "..self:getItemName())
            for key, value in pairs(self.attributes) do
                if getItemAttribute(self.item.uid, key) ~= nil or self.item[key] ~= 0 then
                    doItemSetAttribute(self.item.uid, key, (self.item.level > 0 and getItemAttribute(self.item.uid, key) or self.item[key]) + value)
                end
            end
            return "success"
        else
            if item.itemid == 8300 then
                if self.item.level > 0 then
                    -- this will remove any number with a + sign in front of it from the string
                    self:setItemName(self:getItemName():gsub((self.nameLv[self.item.level].." "), ""))
                    for key, value in pairs(self.attributes) do
                        if getItemAttribute(self.item.uid, key) ~= nil or self.item[key] ~= 0 then
                            doItemSetAttribute(self.item.uid, key, getItemAttribute(self.item.uid, key) - self.item.level * value)
                        end
                    end
                end
            else
                doRemoveItem(self.item.uid, 1)
            end
            doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, item.itemid == 8300 and "Your item level has been reseted." or "You have broken your item while trying to upgrade it.")
        end
    end


Together to this auction system, to players can sell and buy
Unc,Rare,Epic (+1, +2, +3) items upgradeds

PHP:
--[[
Offline player to player item trader (Auction System) by vDk
Script version: 1.4 [ -- FIXED CLONE ITEMS BUG -- ]
]]--
local config = {
    levelRequiredToAdd = 20,
    maxOffersPerPlayer = 1, -- la embaixo outra verificação com lvl
    SendOffersOnlyInPZ = true,
    blocked_items = {2165, 2152, 2148, 2160, 2166, 2167, 2168, 2169, 2202, 2203, 2204, 2205, 2206, 2207, 2208, 2209, 2210, 2211, 2212, 2213, 2214, 2215, 2343, 2433, 2640, 6132, 6300, 6301, 9932, 9933}
}

function onSay(cid, words, param, channel)
    if(param == '') then
            local msg = "Market:\n\n/market buy, ID\n/market remove, ID\n/market add, ItemName, ItemPrice, ItemCount\n\nMore information look in us website!"
            doPlayerPopupFYI(cid, msg)
        return true
    end

    local t = string.explode(param, ",")
    if(t[1] == "add") then
        if((not t[2]) or (not t[3]) or (not t[4])) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Command requires param.")
            return true
        end

        if getPlayerTown(cid) == 9 or getPlayerTown(cid) == 7 then
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Only players in main can use this command.")
                return true
        end

        if(not tonumber(t[3]) or (not tonumber(t[4]))) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You don't set valid price or items count.")
            return true
        end

        if(string.len(t[3]) > 7 or (string.len(t[4]) > 3)) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "This price or item count is too high.")
            return true
        end

        local item = getItemIdByName(t[2], false)
        if(not item) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Item wich such name does not exists.")
            return true
        end

        if(getPlayerLevel(cid) < config.levelRequiredToAdd) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You don't have required (" .. config.levelRequiredToAdd .. ") level.")
            return true
        end

        if(isInArray(config.blocked_items, item)) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "This item is blocked.")
            return true
        end

        if(getPlayerItemCount(cid, item) < (tonumber(t[4]))) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Sorry, you don't have this item(s).")
            return true
        end

        config.maxOffersPerPlayer = math.floor(getPlayerLevel(cid) / 20)
        local check = db.getResult("SELECT `id` FROM `auction_system` WHERE `player` = " .. getPlayerGUID(cid) .. ";")
        if(check:getID() == -1) then
        elseif(check:getRows(true) >= config.maxOffersPerPlayer) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Sorry you can't add more offers! Each 20 levels you recive more one space to add a item. You able to use: " .. config.maxOffersPerPlayer .. " spaces")
            return true
        end

        if(config.SendOffersOnlyInPZ) then
            if(not getTilePzInfo(getPlayerPosition(cid))) then
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You must be in PZ area when you add offert to database.")
                return true
            end
        end

        local valorporoferta = 500
        if(getPlayerBalance(cid) < valorporoferta) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You don't have money enoguh in your bank. You need ".. valorporoferta .. " in your bank balance.")
            return true
        else
            doPlayerSetBalance(cid, getPlayerBalance(cid) - valorporoferta)
        end

        if(tonumber(t[4]) < 1 or (tonumber(t[3]) < 1)) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have to type a number higher than 0.")
            return true
        end

        local itemcount, costgp = math.floor(t[4]), math.floor(t[3])
        doPlayerRemoveItem(cid, item, itemcount)
        db.executeQuery("INSERT INTO `auction_system` (`player`, `item_name`, `item_id`, `count`, `cost`, `date`) VALUES (" .. getPlayerGUID(cid) .. ", \"" .. t[2] .. "\", " .. getItemIdByName(t[2]) .. ", " .. itemcount .. ", " .. costgp ..", " .. os.time() .. ")")
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You successfully add " .. itemcount .." " .. t[2] .." for " .. costgp .. " gps to offerts database.")
    end

    if(t[1] == "buy") then
        if(not tonumber(t[2])) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Wrong ID.")
            return true
        end

        local buy = db.getResult("SELECT * FROM `auction_system` WHERE `id` = " .. (tonumber(t[2])) .. ";")
        if(buy:getID() ~= -1) then
            if(getPlayerBalance(cid) < buy:getDataInt("cost")) then
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You don't have money enoguh in your bank.")
                buy:free()
                return true
            end

            if(getPlayerName(cid) == getPlayerNameByGUID(buy:getDataInt("player"))) then
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Sorry, you can't buy your own items.")
                buy:free()
                return true
            end

            if(getPlayerFreeCap(cid) < getItemWeightById(buy:getDataInt("item_id"), buy:getDataInt("count")))then
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You try to buy a " .. buy:getDataString("item_name") .. ". It weight " .. getItemWeightById(buy:getDataInt("item_id"), buy:getDataInt("count")) .. " cap oz. and you have only " .. getPlayerFreeCap(cid) .. " oz. free capacity. Put some items to depot and try again.")
                buy:free()
                return true
            end

            if(isItemStackable((buy:getDataString("item_id")))) then
                doPlayerAddItem(cid, buy:getDataString("item_id"), buy:getDataInt("count"))
            else
                for i = 1, buy:getDataInt("count") do
                    doPlayerAddItem(cid, buy:getDataString("item_id"), 1)
                end
            end
            doPlayerSetBalance(cid, getPlayerBalance(cid) - buy:getDataInt("cost"))
            db.executeQuery("DELETE FROM `auction_system` WHERE `id` = " .. t[2] .. ";")
            doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You bought " .. buy:getDataInt("count") .. " ".. buy:getDataString("item_name") .. " for " .. buy:getDataInt("cost") .. " gps!")
          
            local tid = getPlayerByGUID(buy:getDataInt("player"))
            if(isPlayer(tid)) then
                doPlayerSetBalance(tid, getPlayerBalance(tid) + buy:getDataInt("cost"))
            else
                db.executeQuery("UPDATE `players` SET `balance` = `balance` + " .. buy:getDataInt("cost") .. " WHERE `id` = " .. buy:getDataInt("player") .. ";")
            end

            buy:free()
        else
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Wrong ID.")
        end
    end

    if(t[1] == "remove") then
        if((not tonumber(t[2]))) then
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Wrong ID.")
            return true
        end

        if(config.SendOffersOnlyInPZ) then
            if(not getTilePzInfo(getPlayerPosition(cid))) then
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You must be in PZ area when you remove offerts from database.")
                return true
            end
        end

        local delete = db.getResult("SELECT * FROM `auction_system` WHERE `id` = " .. (tonumber(t[2])) .. ";")
        if(delete:getID() ~= -1) then
            if(getPlayerGUID(cid) == delete:getDataInt("player")) then
                db.executeQuery("DELETE FROM `auction_system` WHERE `id` = " .. t[2] .. ";")
                if(isItemStackable(delete:getDataString("item_id"))) then
                    doPlayerAddItem(cid, delete:getDataString("item_id"), delete:getDataInt("count"))
                else
                    for i = 1, delete:getDataInt("count") do
                        doPlayerAddItem(cid, delete:getDataString("item_id"), 1)
                    end
                end

                doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Your offert has been deleted from offerts database.")
            else
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "This is not your offert!")
            end
          
            delete:free()
        else
            doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Wrong ID.")
        end
    end
    return true
end

Anybody know how to do this?
 
The right way to do this is add a table on DB?
PHP:
ALTER TABLE `auction_system` ADD `rarity` TINYINT(1) NOT NULL DEFAULT '0' AFTER `date`;

Official DB:
PHP:
CREATE TABLE `auction_system` (
  `id` int(11) NOT NULL auto_increment,
  `player` int(11),
  `item_id` int(11),
  `item_name` varchar(255),
  `count` int(11),
  `cost` int(11),
  `date` int(11),
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

ALTER TABLE `players` ADD `auction_balance` INT( 11 ) NOT NULL DEFAULT '0';

And add this rarity on
PHP:
if(t[1] == "add") then
???

(i don't know how to do it, i just trying to help who will help me, i don't know even it is the right way)
 
Last edited:
Yeah a db field for the rarity levels would be an easy way of doing it for this system. Im currently baffled trying to figure out a way to do it for this system: https://otland.net/threads/mod-random-item-stats.130295/

I think this server use the same system then you, maybe can give you a idea:
http://www.noxiousot.com/?subtopic=market&page=1

---

I thought it should work but i don't know how to check if item is upgraded when player set to sell
And don't know how to add upgrade when player buy a upgraded item
This is script is too advanced to me
 
im looking for this too. i was thinking in adding an AID on upgraded ítem, or making another ítem id for +1,+2, etc so auction will sell an upgraded ítem with its own id
 
Back
Top