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

Roulette Revscript problem

richardestro

New Member
Joined
Oct 23, 2023
Messages
14
Reaction score
1
Hello, i'm trying to add a roulette to my server and i found a Revscript for that, but currently it's giving me 2 errors in the console.
the first one it's at the moment I start the server:
Lua:
Lua Script Error: [Scripts Interface]
D:\Escritorio\Basureron't\Pruebas del canaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua
...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:245: attempt to index local 'disableMovingItemsToRoulettePositions' (a nil value)
stack traceback:
        [C]: in function '__newindex'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:245: in main chunk
> newlottery5.lua [error]

And the second error it's at the moment I try to use the roulette.
Code:
Lua Script Error: [Scripts Interface]
D:\Escritorio\Basureron't\Pruebas del canaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:callback
...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:93: attempt to call method 'hasShowCharges' (a nil value)
stack traceback:
        [C]: in function 'hasShowCharges'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:93: in function 'updateRoulette'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:192: in function 'roulette'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:228: in function <...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:206>

Here is the Revscript that I currently using
Code:
local config = {
    actionId = 18570, -- on lever
    lever = {
        left = 1945,
        right = 1946
    },
    playItem = {
        itemId = 27058, -- item required to pull lever nota del canas puse tcs por mientras
        count = 10
    },
    rouletteOptions = {
        rareItemChance_broadcastThreshold = 500,
        ignoredItems = {}, -- if you have tables/counters/other items on the roulette tiles, add them here
        winEffects = {CONST_ANI_FIRE, CONST_ME_SOUND_YELLOW, CONST_ME_SOUND_PURPLE, CONST_ME_SOUND_BLUE, CONST_ME_SOUND_WHITE}, -- first effect needs to be distance effect
        effectDelay = 333,
        spinTime = {min = 8, max = 12}, -- seconds
        spinSlowdownRamping = 5,
        rouletteStorage = 100 -- required storage to avoid player abuse (if they logout/die before roulette finishes.. they can spin again for free)
    },
    prizePool = {
        {itemId = 2160, count = {10, 100},   chance = 9001}, -- {itemId = itemid, count = {min, max}, chance = chance/10000} (crystal coins)
        {itemId = 2488, count = {1, 1},    chance = 9002 }, -- crown legs
        {itemId = 2195, count = {1, 1},    chance = 9003 }, -- boots of haste
        {itemId = 2498, count = {1, 1},    chance = 9004 }, -- royal helmet
        {itemId = 33318, count = {1, 1},   chance = 9005 }, -- book backpack
        {itemId = 10521, count = {1, 1}, chance = 9006 }, -- moon backpack
        {itemId = 27058, count = {1, 5},    chance = 9007 }, -- otro tiro
        {itemId = 2470, count = {1, 1},    chance = 9008 }, -- golden legs
        {itemId = 2472, count = {1, 1},    chance = 9009 }, -- magic plate armor
        {itemId = 2493, count = {1, 1},    chance = 9010 }, -- demon helmet
        {itemId = 6391, count = {1, 1},    chance = 9011 }, -- nightmare shield
        {itemId = 2431, count = {1, 1},    chance = 9012 }, -- stonecutter axe
        {itemId = 15646, count = {1, 1},    chance = 9013 }, -- buggy backpack
        {itemId = 11119, count = {1, 1},    chance = 9014 }, -- heart backback
        {itemId = 2647, count = {1, 1},    chance = 8500 }, -- basura
        {itemId = 2643, count = {1, 1},    chance = 8501 }, -- basura
        {itemId = 2649, count = {1, 1},    chance = 8502 }, -- basura
        {itemId = 2461, count = {1, 1},    chance = 8503 }, -- basura
        {itemId = 9078, count = {1, 1},    chance = 8504 }, -- basura
        {itemId = 2490, count = {1, 1},    chance = 8505 }, -- basura
        {itemId = 2457, count = {1, 1},    chance = 8506 }, -- basura
        {itemId = 2148, count = {1, 100},    chance = 8507 }, -- basura gps
        {itemId = 2398, count = {1, 1},    chance = 8508 }, -- basura
        {itemId = 2386, count = {1, 1},    chance = 8509 }, -- basura
        {itemId = 2152, count = {1, 100},    chance = 8510 }, -- basura pts
        {itemId = 38817, count = {1, 1},    chance = 6015  },  -- donate rp
        {itemId = 2646, count = {1, 1},    chance = 9015  }  -- golden boots
    
    },
    roulettePositions = { -- hard-coded to 7 positions.
        Position(474, 137, 5),
        Position(475, 137, 5),
        Position(476, 137, 5),
        Position(477, 137, 5), -- position 4 in this list is hard-coded to be the reward location, which is the item given to the player
        Position(478, 137, 5),
        Position(479, 137, 5),
        Position(480, 137, 5),
    }
}

function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end
 
    if hasEventCallback(EVENT_CALLBACK_ONMOVEITEM) then
        return EventCallback(EVENT_CALLBACK_ONMOVEITEM, self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    end
    return RETURNVALUE_NOERROR
end

local chancedItems = {} -- used for broadcast. don't edit

local function resetLever(position)
    local lever = Tile(position):getItemById(config.lever.right)
    lever:transform(config.lever.left)
end

local function updateRoulette(newItemInfo)
    local positions = config.roulettePositions
    for i = #positions, 1, -1 do
        local item = Tile(positions[i]):getTopVisibleThing()
        if item and item:getId() ~= Tile(positions[i]):getGround():getId() and not table.contains(config.rouletteOptions.ignoredItems, item:getId()) then
            if i ~= 7 then
                item:moveTo(positions[i + 1])
            else
                item:remove()
            end
        end
    end
    if ItemType(newItemInfo.itemId):hasShowCharges() then
        local item = Game.createItem(newItemInfo.itemId, 1, positions[1])
        item:setAttribute("charges", newItemInfo.count)
    else
        Game.createItem(newItemInfo.itemId, newItemInfo.count, positions[1])
    end
end

local function clearRoulette(newItemInfo)
    local positions = config.roulettePositions
    for i = #positions, 1, -1 do
        local item = Tile(positions[i]):getTopVisibleThing()
        if item and item:getId() ~= Tile(positions[i]):getGround():getId() and not table.contains(config.rouletteOptions.ignoredItems, item:getId()) then
            item:remove()
        end
        if newItemInfo == nil then
            positions[i]:sendMagicEffect(CONST_ME_POFF)
        else
            if ItemType(newItemInfo.itemId):hasShowCharges() then
                local item = Game.createItem(newItemInfo.itemId, 1, positions[i])
                item:setAttribute("charges", newItemInfo.count)
            else
                Game.createItem(newItemInfo.itemId, newItemInfo.count, positions[i])
            end
        end
    end
end

local function chanceNewReward()
    local newItemInfo = {itemId = 0, count = 0}
    
    local rewardTable = {}
    while #rewardTable < 1 do
        for i = 1, #config.prizePool do
            if config.prizePool[i].chance >= math.random(10000) then
                rewardTable[#rewardTable + 1] = i
            end
        end
    end
    
    local rand = math.random(#rewardTable)
    newItemInfo.itemId = config.prizePool[rewardTable[rand]].itemId
    newItemInfo.count = math.random(config.prizePool[rewardTable[rand]].count[1], config.prizePool[rewardTable[rand]].count[2])
    chancedItems[#chancedItems + 1] = config.prizePool[rewardTable[rand]].chance
    
    return newItemInfo
end

local function initiateReward(leverPosition, effectCounter)
    if effectCounter < #config.rouletteOptions.winEffects then
        effectCounter = effectCounter + 1
        if effectCounter == 1 then
            config.roulettePositions[1]:sendDistanceEffect(config.roulettePositions[4], config.rouletteOptions.winEffects[1])
            config.roulettePositions[7]:sendDistanceEffect(config.roulettePositions[4], config.rouletteOptions.winEffects[1])
        else
            for i = 1, #config.roulettePositions do
                config.roulettePositions[i]:sendMagicEffect(config.rouletteOptions.winEffects[effectCounter])
            end
        end
        if effectCounter == 2 then
            local item = Tile(config.roulettePositions[4]):getTopVisibleThing()
            local newItemInfo = {itemId = item:getId(), count = item:getCount()}
            clearRoulette(newItemInfo)
        end
        addEvent(initiateReward, config.rouletteOptions.effectDelay, leverPosition, effectCounter)
        return
    end
    resetLever(leverPosition)
end

local function rewardPlayer(playerId, leverPosition)
    local player = Player(playerId)
    if not player then
        return
    end
    
    local item = Tile(config.roulettePositions[4]):getTopVisibleThing()
    
    if ItemType(item:getId()):hasShowCharges() then
        local addedItem = player:addItem(item:getId(), 1, true)
        addedItem:setAttribute("charges", item:getCharges())
    else
        player:addItem(item:getId(), item:getCount(), true)
    end

    player:setStorageValue(config.rouletteOptions.rouletteStorage, -1)
    if chancedItems[#chancedItems - 3] <= config.rouletteOptions.rareItemChance_broadcastThreshold then
        Game.broadcastMessage("The player " .. player:getName() .. " has won " .. item:getName() .. " from the roulette!", MESSAGE_EVENT_ADVANCE)
    end
end

local function roulette(playerId, leverPosition, spinTimeRemaining, spinDelay)
    local player = Player(playerId)
    if not player then
        resetLever(leverPosition)
        return
    end
    
    local newItemInfo = chanceNewReward()
    updateRoulette(newItemInfo)
    
    if spinTimeRemaining > 0 then
        spinDelay = spinDelay + config.rouletteOptions.spinSlowdownRamping
        addEvent(roulette, spinDelay, playerId, leverPosition, spinTimeRemaining - (spinDelay - config.rouletteOptions.spinSlowdownRamping), spinDelay)
        return
    end
    
    initiateReward(leverPosition, 0)
    rewardPlayer(playerId, leverPosition)
end

local casinoRoulette = Action()

function casinoRoulette.onUse(player, item, fromPosition, target, toPosition, isHotkey)
    if item:getId() == config.lever.right then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, "Casino Roulette is currently in progress. Please wait.")
        return true
    end
    
    if player:getItemCount(config.playItem.itemId) < config.playItem.count then
        if player:getStorageValue(config.rouletteOptions.rouletteStorage) < 1 then
            player:sendTextMessage(MESSAGE_STATUS_SMALL, "Casino Roulette requires " .. config.playItem.count .. " " .. (ItemType(config.playItem.itemId):getName()) .. " to use.")
            return true
        end
        -- player:sendTextMessage(MESSAGE_STATUS_SMALL, "Free Spin being used due to a previous unforeseen error.")
    end
    
    item:transform(config.lever.right)
    clearRoulette()
    chancedItems = {}
    
    player:removeItem(config.playItem.itemId, config.playItem.count)
    player:setStorageValue(config.rouletteOptions.rouletteStorage, 1)
    
    local spinTimeRemaining = math.random((config.rouletteOptions.spinTime.min * 1000), (config.rouletteOptions.spinTime.max * 1000))
    roulette(player:getId(), toPosition, spinTimeRemaining, 100)
    return true
end

casinoRoulette:aid(config.actionId)
casinoRoulette:register()


local disableMovingItemsToRoulettePositions = EventCallback

disableMovingItemsToRoulettePositions.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end
    return true
end

disableMovingItemsToRoulettePositions:register()

Got the original here: Roulette System (https://otland.net/threads/roulette-system.284569/)

I found a guy that had a similar problem, I tried to do what he only answer said but didn't work here: Roulette system (https://otland.net/threads/roulette-system.286314/)

I really appreciate the help :)
 
Lua Script Error: [Scripts Interface] D:\Escritorio\Basureron't\Pruebas del canaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:245: attempt to index local 'disableMovingItemsToRoulettePositions' (a nil value) stack traceback: [C]: in function '__newindex' ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:245: in main chunk > newlottery5.lua [error]
Does your TFS support EventCallback?
attempt to call method 'hasShowCharges
This gave errors saying it doesn't exist in your source. Have you checked that? The function 'hasShowCharges'.?
 
error: Now the variable disableMovingItemsToRoulettePositions is correctly initialized as an instance of EventCallback.
C++:
local disableMovingItemsToRoulettePositions = EventCallback

disableMovingItemsToRoulettePositions.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end
    return true
end

disableMovingItemsToRoulettePositions:register()

change for

C++:
local disableMovingItemsToRoulettePositions = EventCallback()

disableMovingItemsToRoulettePositions.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end
    return true
end

disableMovingItemsToRoulettePositions:register()

Likely, the itemId in newItemInfo does not correspond to a valid item in the game.

in:

C++:
local function updateRoulette(newItemInfo)
    local positions = config.roulettePositions
    for i = #positions, 1, -1 do
        local item = Tile(positions[i]):getTopVisibleThing()
        if item and item:getId() ~= Tile(positions[i]):getGround():getId() and not table.contains(config.rouletteOptions.ignoredItems, item:getId()) then
            if i ~= 7 then
                item:moveTo(positions[i + 1])
            else
                item:remove()
            end
        end
    end
    if ItemType(newItemInfo.itemId):hasShowCharges() then
        local item = Game.createItem(newItemInfo.itemId, 1, positions[1])
        item:setAttribute("charges", newItemInfo.count)
    else
        Game.createItem(newItemInfo.itemId, newItemInfo.count, positions[1])
    end
end

change for:

C++:
local function updateRoulette(newItemInfo)
    local positions = config.roulettePositions
    for i = #positions, 1, -1 do
        local item = Tile(positions[i]):getTopVisibleThing()
        if item and item:getId() ~= Tile(positions[i]):getGround():getId() and not table.contains(config.rouletteOptions.ignoredItems, item:getId()) then
            if i ~= 7 then
                item:moveTo(positions[i + 1])
            else
                item:remove()
            end
        end
    end
    if newItemInfo and ItemType(newItemInfo.itemId) then
        if ItemType(newItemInfo.itemId):hasShowCharges() then
            local item = Game.createItem(newItemInfo.itemId, 1, positions[1])
            item:setAttribute("charges", newItemInfo.count)
        else
            Game.createItem(newItemInfo.itemId, newItemInfo.count, positions[1])
        end
    else
        print("Invalid item ID for new roulette reward!")
    end
end
 
local disableMovingItemsToRoulettePositions = EventCallback()
Here in the line is incorrect... when turning on, errors will appear in the console. The correct line is local disableMovingItemsToRoulettePositions = EventCallback without using (). I hope this helps. Just a reminder for those using TFS 1.3, it may or may not support it. need to check if the server has EventCallback or not. If it doesn't, of course, it won't work. In that case, add this to data/event/player.lua, find the line Player:eek:nMoveItem, and add this. Just give it a try!

Lua:
for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end


Just remove the entire line.
Lua:
local disableMovingItemsToRoulettePositions = EventCallback

disableMovingItemsToRoulettePositions.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end
    return true
end

disableMovingItemsToRoulettePositions:register()
 
I foget, i use TSF 1.3 I tried both solutions, first i did this changes:
C++:
local disableMovingItemsToRoulettePositions = EventCallback()

disableMovingItemsToRoulettePositions.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end
    return true
end

disableMovingItemsToRoulettePositions:register()

Likely, the itemId in newItemInfo does not correspond to a valid item in the game.

in:

C++:
local function updateRoulette(newItemInfo)
    local positions = config.roulettePositions
    for i = #positions, 1, -1 do
        local item = Tile(positions[i]):getTopVisibleThing()
        if item and item:getId() ~= Tile(positions[i]):getGround():getId() and not table.contains(config.rouletteOptions.ignoredItems, item:getId()) then
            if i ~= 7 then
                item:moveTo(positions[i + 1])
            else
                item:remove()
            end
        end
    end
    if ItemType(newItemInfo.itemId):hasShowCharges() then
        local item = Game.createItem(newItemInfo.itemId, 1, positions[1])
        item:setAttribute("charges", newItemInfo.count)
    else
        Game.createItem(newItemInfo.itemId, newItemInfo.count, positions[1])
    end
end

change for:

C++:
local function updateRoulette(newItemInfo)
    local positions = config.roulettePositions
    for i = #positions, 1, -1 do
        local item = Tile(positions[i]):getTopVisibleThing()
        if item and item:getId() ~= Tile(positions[i]):getGround():getId() and not table.contains(config.rouletteOptions.ignoredItems, item:getId()) then
            if i ~= 7 then
                item:moveTo(positions[i + 1])
            else
                item:remove()
            end
        end
    end
    if newItemInfo and ItemType(newItemInfo.itemId) then
        if ItemType(newItemInfo.itemId):hasShowCharges() then
            local item = Game.createItem(newItemInfo.itemId, 1, positions[1])
            item:setAttribute("charges", newItemInfo.count)
        else
            Game.createItem(newItemInfo.itemId, newItemInfo.count, positions[1])
        end
    else
        print("Invalid item ID for new roulette reward!")
    end
end
And still having the same errors, later on i tried to do the changes in player.lua and i removed the
"disableMovingItemsToRoulettePositions = EventCallback" in the original Revscript
Lua:
for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end


Just remove the entire line.
Lua:
local disableMovingItemsToRoulettePositions = EventCallback

disableMovingItemsToRoulettePositions.onMoveItem = function(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder)
    for v, k in pairs(config.roulettePositions) do
        if toPosition == k then
            return false
        end
    end
    return true
end

disableMovingItemsToRoulettePositions:register()
With that the roulette still "works", cause when I use the lever it consume the coins and later on the lever block saying that the roulette is in use, but having the same console errors :(

Lua:
Lua Script Error: [Scripts Interface]
D:\Escritorio\Basureron't\Pruebas del canaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:callback
...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:94: attempt to call method 'hasShowCharges' (a nil value)
stack traceback:
        [C]: in function 'hasShowCharges'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:94: in function 'updateRoulette'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:196: in function 'roulette'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:232: in function <...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:210>

Probably the error is in the compatibility with the EventCallback, but no sure, i'll take a look to that meanwhile :)
 
I foget, i use TSF 1.3 I tried both solutions, first i did this changes:

And still having the same errors, later on i tried to do the changes in player.lua and i removed the
"disableMovingItemsToRoulettePositions = EventCallback" in the original Revscript

With that the roulette still "works", cause when I use the lever it consume the coins and later on the lever block saying that the roulette is in use, but having the same console errors :(

Lua:
Lua Script Error: [Scripts Interface]
D:\Escritorio\Basureron't\Pruebas del canaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:callback
...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:94: attempt to call method 'hasShowCharges' (a nil value)
stack traceback:
        [C]: in function 'hasShowCharges'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:94: in function 'updateRoulette'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:196: in function 'roulette'
        ...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:232: in function <...anaot\Canas Ote\Toxic Tibia\data\scripts\newlottery5.lua:210>

Probably the error is in the compatibility with the EventCallback, but no sure, i'll take a look to that meanwhile :)
Bump
 
Back
Top