• 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!
  • 2026 staff recruitment is open! Check it out and consider applying!

OTClient OTCv8/otclientv8 new item to store ingame

Yes, it's possible, but your OTX, I'm not sure if it has the opcode support in the source. It's good to analyze if it doesn't have it. I recommend you download the OTX from FeTads which is more recent. It has complete support for opcodes and other functional features.

I helped a guy who was using DBO. I converted the TFS 1.x scripts to 0.x and it worked.

I got it from here GitHub - OTCv8/otcv8-tools: Tools for otclientv8 (https://github.com/OTCv8/otcv8-tools), adapted it to 0.x.

Use OTX GitHub - FeTads/otxserver: OpenServer tibia / Tutorials and scripts (https://github.com/FeTads/otxserver) - much better, it has a reset system, critical and dodge, life leech and mana leech etc. This OTX worked for me with opcode stores and other modules that use opcode.

I tested the old OTX and nothing worked at all. Anyway, that's it, I hope I helped.
 
Last edited:
i tried with chatg gpt and got this:
LUA:
-- shop.lua
-- OTClient 8+ / OTX 2.16 compatible
-- Ready-to-use shop with categories and items

local SHOP_EXTENDED_OPCODE = 201
local CUSTOM_OFFERS = {
    -- ITEMS
    { id=1, category="Items", type="image", image="images/items/crystal_coin_bp.png", cost=25, title="Backpack Crystal Coin", description="Backpack with 100 Crystal Coins" },
    { id=2, category="Items", type="image", image="images/items/gold_coin.png", cost=10, title="100 Gold Coins", description="Pack of 100 gold coins" },

    -- WEAPONS
    { id=3, category="Weapons", type="image", image="images/items/sword_iron.png", cost=50, title="Iron Sword", description="A sturdy iron sword." },
    { id=4, category="Weapons", type="image", image="images/items/sword_steel.png", cost=100, title="Steel Sword", description="A sharp steel sword." },

    -- OUTFITS
    { id=5, category="Outfits", type="outfit", outfit=35, addons=3, cost=150, title="Demon Outfit", description="Full demon outfit with 3 addons" }
}

local shop, shopButton, msgWindow = nil, nil, nil
local CATEGORIES, STATUS = {}, { points = 1000 } -- example points

-- Sends a buy request
local function sendAction(action, data)
    if not g_game.getFeature(GameExtendedOpcode) then return end
    local protocolGame = g_game.getProtocolGame()
    if protocolGame then
        protocolGame:sendExtendedJSONOpcode(SHOP_EXTENDED_OPCODE, { action=action, data=data })
    end
end

-- Show confirmation dialog
local function showConfirm(offer)
    if msgWindow then msgWindow:destroy() msgWindow=nil end
    local title = "Buying from shop"
    local msg = "Do you want to buy "..offer.title.." for "..offer.cost.." points?"
    msgWindow = displayGeneralBox(title, msg, {
        { text="Yes", callback=function() sendAction("buy", offer) end },
        { text="No", callback=function() msgWindow:destroy() msgWindow=nil end }
    })
    msgWindow:show()
    msgWindow:raise()
end

-- Adds an offer to UI
local function addOfferToUI(offer)
    local widget
    if offer.type == "image" then
        widget = g_ui.createWidget('ShopOfferImage', shop.offers)
        widget.image:setImageSource(offer.image)
    elseif offer.type == "outfit" then
        widget = g_ui.createWidget('ShopOfferCreature', shop.offers)
        widget.creature:setOutfit({ type=offer.outfit, addons=offer.addons })
        widget.creature:setAutoRotating(true)
    end
    widget.title:setText(offer.title.." ("..offer.cost.." points)")
    widget.description:setText(offer.description)
    widget.buyButton.onClick = function() showConfirm(offer) end
end

-- Change category
local function changeCategory(widget, newCategory)
    if not newCategory then return end
    shop.offers:destroyChildren()
    local id = tonumber(newCategory:getId():split("_")[2])
    local category = CATEGORIES[id]
    if category and category.offers then
        for _, offer in ipairs(category.offers) do
            addOfferToUI(offer)
        end
    end
end

-- Create shop UI
local function createShopUI()
    if shop then return end
    shop = g_ui.displayUI('shop')
    shop:hide()
    shopButton = modules.client_topmenu.addRightGameToggleButton('shopButton', "Shop", '/images/topbuttons/shop', function()
        if shop:isVisible() then shop:hide() else shop:show() end
    end, false, 8)

    -- Build categories
    CATEGORIES = {}
    local categoryNames = {}
    for _, offer in ipairs(CUSTOM_OFFERS) do
        if not categoryNames[offer.category] then
            categoryNames[offer.category] = true
            table.insert(CATEGORIES, { name=offer.category, offers={} })
        end
    end

    -- Assign offers to categories
    for _, offer in ipairs(CUSTOM_OFFERS) do
        for _, category in ipairs(CATEGORIES) do
            if category.name == offer.category then
                table.insert(category.offers, offer)
            end
        end
    end

    -- Add category widgets
    for i, category in ipairs(CATEGORIES) do
        local widget = g_ui.createWidget('ShopCategoryItem', shop.categories)
        widget:setId("category_"..i)
        widget.name:setText(category.name)
        widget.onClick = function() changeCategory(nil, widget) end
    end

    -- Show first category
    if #CATEGORIES > 0 then
        local first = shop.categories:getChildByIndex(1)
        if first then changeCategory(nil, first) end
    end
end

-- Initialize shop
function init()
    createShopUI()
end

-- Terminate shop
function terminate()
    if shopButton then shopButton:destroy() shopButton=nil end
    if shop then shop:destroy() shop=nil end
    if msgWindow then msgWindow:destroy() msgWindow=nil end
end
and in store somethink comes : take a look :

GUI shop.webp
 
That's it. Nowadays AI is really advanced, true. 2 years ago it was dumb. AI is really evolving. Keep going, learn and explore the scripts and adapt them correctly to your store. Good luck!

You need to be careful as @Gesior.pl reported about the store hack, someone capable of abusing it etc. Check what he says: [WARNING] Custom OTC/OTCv8 Game Store hack (https://otland.net/threads/warning-custom-otc-otcv8-game-store-hack.291825/)
Post automatically merged:

you did it on the client side, totally wrong. The correct way is on the server side.

You'll need to create the script for store via opcode, it's creaturescript + register on onLogin so the server sends to the client to update and show the store offers, understand? Or as I showed you in the link otcv8-tools/server/shop/shop.lua at main · OTCv8/otcv8-tools (https://github.com/OTCv8/otcv8-tools/blob/main/server/shop/shop.lua), here you ask your AI to adapt it to OTX/TFS 0.x correctly. You would need to analyze which opcode function it would be, like doSendPlayerExtendedOpcode etc.
 
Last edited:
In Your link when I moved shop.lua to otc folder shop.lua occurs error .sth. line is debug. I have script in creaturescript but doesnt work correctly. Shows nothing in store. I will try convert Your shop.lua link to otx2.16
 
Back
Top