Ir para conteúdo
  • 0

Advanced Roulette System (TFS 0.3.6) SOCORRO ME AJUDA


Pergunta

Olha Como o Meu tá e Não ta Funcionando Olha Mapa: ONDE EU TO É A POS: x266 y233 z15 

 

<action actionid="4725" script="roulette.lua"/>
<action actionid="4571" script="roulette.lua"/>
<action actionid="4545" script="roulette.lua"/>
<action actionid="4478" script="roulette.lua"/>

 

 

 

 

 

 

Screenshot-2

 

 

 

 

 

 

--[[
================================================================================
=                   ROULETTE SYSTEM FOR TFS                                     =
=                                                                               =
= Author: Neutras                                                               =
= Version: 2.1                                                                  =
= Description: Gacha-style roulette system with dynamic speed mechanics         =
=              and multi-key feature.                                           =
=                                                                               =
= Features:                                                                     =
= - Multi-key support (1-4 keys per spin).                                      =
= - Dynamic speed animation with configurable initial and final speeds.         =
= - Persistent "Winner Slot" effects and animated texts.                        =
= - Configurable rewards with reroll chances.                                   =
= - Logging system to track player rewards.                                     =
=                                                                               =
= Compatible with TFS 0.3.7 (Tibia 8.6).                                        =
================================================================================
--]]

--[[
================================================================================
=                   ROULETTE SYSTEM FOR TFS                                     =
=                                                                               =
= Author: Neutras                                                               =
= Version: 2.1                                                                  =
= Description: Gacha-style roulette system with dynamic speed mechanics         =
=              and multi-key feature.                                           =
=                                                                               =
= Features:                                                                     =
= - Multi-key support (1-4 keys per spin).                                      =
= - Dynamic speed animation with configurable initial and final speeds.         =
= - Persistent "Winner Slot" effects and animated texts.                        =
= - Configurable rewards with reroll chances.                                   =
= - Logging system to track player rewards.                                     =
=                                                                               =
= Compatible with TFS 0.3.7 (Tibia 8.6).                                        =
================================================================================
--]]

-- ================= LOGGING SYSTEM ================= --
local logPath = "data/logs/"
local logFileName = "roulette.log"

-- Logs player rewards to a file.
-- @param cid: Player ID.
-- @param keyName: Name of the key used.
-- @param items: Table of items won.
-- @param keyCount: Number of keys used.
local function logEntry(cid, keyName, items, keyCount)
    local file = io.open(logPath .. logFileName, "a")
    if file then
        local itemStrings = {}
        for _, item in ipairs(items) do
            table.insert(itemStrings, string.format("x%d %s", item.count, getItemNameById(item.id)))
        end
        file:write(string.format("[%s] %s used %d '%s' and won: %s\n",
            os.date("%Y-%m-%d %H:%M:%S"),
            getPlayerName(cid),
            keyCount,
            keyName,
            table.concat(itemStrings, ", ")))
        file:close()
    end
end

-- ================= BASE CONFIGURATION ================= --
-- Levers Action IDs to key item IDs.
local keyByAid = {
    [1354] = 9971, -- Key for reward level 1 (Copper)
    [1355] = 9972, -- Key for reward level 2 (Silver)
    [1356] = 9973  -- Key for reward level 3 (Golden)
}

-- Levers Action IDs to reward levels.
local rewardByAid = {
    [1354] = 1, -- Reward level 1 (Copper)
    [1355] = 2, -- Reward level 2 (Silver)
    [1356] = 3  -- Reward level 3 (Golden)
}

-- Relative positions of the slots in the roulette.
local rouletteSpinOffset = {
    {1, -4}, {2, -4}, {3, -4}, {3, -3}, {4, -3},
    {4, -2}, {4, -1}, {5, -1}, {5, 0},  {5, 1},
    {4, 1},  {4, 2},  {4, 3},  {3, 3},  {3, 4},
    {2, 4},  {1, 4},  {0, 4},  {-1, 4}, {-2, 4},
    {-3, 4}, {-3, 3}, {-4, 3}, {-4, 2}, {-4, 1},
    {-5, 1}, {-5, 0}, {-5, -1},{-4, -1},{-4, -2},
    {-4, -3},{-3, -3},{-3, -4},{-2, -4},{-1, -4},
    {0, -4}
}

-- ================= MAIN CONFIGURATION ================= --
local config = {
    rouletteCD = 30,           -- Global cooldown in seconds.
    globalStoCd = 22600,       -- Storage ID for cooldown.
    globalStoKeyCount = 22601, -- Storage ID for key count.
    maxLoops = 100,            -- Maximum iterations per spin.
    initialSpeed = 50,         -- Initial speed in milliseconds.
    finalSpeed = 400,          -- Final speed in milliseconds.
    effectLever = 35,          -- Effect when activating the lever.
    effectRewardPlayer = 28,   -- Effect on the player when winning.
    effectReward = 28,         -- Effect on the winning slot.

    -- Reward table by level.
    -- Formula: Real Probability = (Item Chance / Total Chances) * (1 - (Reroll % / 100))
    items = {
        [1] = { 
        {id = 4871, chance = 100, count = 1},
    },
    [2] = {
        {id = 4872, chance = 100, count = 1},
    },
    [3] = {
        {id = 4870, chance = 100, count = 1},
    },
    [4] = {
        {id = 5899, chance = 100, count = 1},
    },
    [5] = {
        {id = 2349, chance = 100, count = 1},
    },
    [6] = {
        {id = 9003, chance = 100, count = 1},
    },
    [7] = {
        {id = 2300, chance = 100, count = 1},
    },
    [8] = {
        {id = 2309, chance = 100, count = 1},
    },
    [9] = {
        {id = 2272, chance = 100, count = 1},
    },
    [10] = {
        {id = 2306, chance = 100, count = 1},
    },
    [11] = {
        {id = 2447, chance = 100, count = 1},
    },
    [12] = {  
        {id = 7739, chance = 100, count = 1},
    },
    [13] = {
        {id = 7737, chance = 100, count = 1},
    },
    [14] = {          
        {id = 5805, chance = 100, count = 1},
    },
    [15] = {      
        {id = 2446, chance = 100, count = 1}
       }
    }    
}

-- ================= PROBABILITY CACHING ================= --
-- Precalculates cumulative probabilities for each reward level.
local cumulativeChanceCache = {}
for rewardId, items in pairs(config.items) do
    local total = 0
    local cumulative = {}
    for _, item in ipairs(items) do
        total = total + item.chance
        table.insert(cumulative, {item = item, threshold = total})
    end
    cumulativeChanceCache[rewardId] = {total = total, items = cumulative}
end

-- ================= UTILITY FUNCTIONS ================= --
-- Calculates the speed of the roulette animation based on progress.
-- @param progress: Current progress (0 to 1).
-- @return: Speed in milliseconds.
local function calculateSpeed(progress)
    return config.initialSpeed + (config.finalSpeed - config.initialSpeed) * progress^3
end

-- Selects a random item from the reward table, considering reroll chances.
-- @param rewardId: Reward level ID.
-- @return: Selected item.
local function chooseRouletteItem(rewardId)
    local cache = cumulativeChanceCache[rewardId]
    local roll = math.random(cache.total)
    for _, entry in ipairs(cache.items) do
        if roll <= entry.threshold then
            if entry.item.porc_cambio and math.random(100) <= entry.item.porc_cambio then
                return chooseRouletteItem(rewardId)
            end
            return entry.item
        end
    end
    return cache.items[#cache.items].item
end

-- Rotates the slots in the roulette.
-- @param slots: Table of slots.
local function rotateSlots(slots)
    local last = slots[36]
    for i = 36, 2, -1 do slots[i] = slots[i-1] end
    slots[1] = last
end

-- Updates the visual display of the roulette.
-- @param cpos: Center position of the roulette.
-- @param slots: Table of slots.
-- @param isFillingPhase: Whether the slots are being filled for the first time.
local function updateRouletteDisplay(cpos, slots, isFillingPhase)
    for i = 1, 36 do
        local pos = {
            x = cpos.x + rouletteSpinOffset[i][1],
            y = cpos.y + rouletteSpinOffset[i][2],
            z = cpos.z
        }
        doCleanTile(pos)
        if slots[i] then
            doCreateItem(slots[i].id, slots[i].count, pos)
            -- Show puff effect only during the initial filling phase.
            if isFillingPhase then
                doSendMagicEffect(pos, 14)
            end
        end
    end
end

-- ================= WINNER SLOTS AND EFFECTS ================= --
-- Shows "Winner Slot" animated text on winning slots.
-- @param cpos: Center position of the roulette.
-- @param keyCount: Number of keys used.
local function showWinnerSlots(cpos, keyCount)
    local winningSlots = {}
    if keyCount == 1 then
        winningSlots = {36}
    elseif keyCount == 2 then
        winningSlots = {36, 18}
    elseif keyCount == 3 then
        winningSlots = {36, 18, 9}
    elseif keyCount == 4 then
        winningSlots = {36, 18, 9, 27}
    else
        winningSlots = {36} -- Default to one winning slot if keyCount is invalid.
    end

    for _, slot in ipairs(winningSlots) do
        local pos = {
            x = cpos.x + rouletteSpinOffset[slot][1],
            y = cpos.y + rouletteSpinOffset[slot][2],
            z = cpos.z
        }
        doSendAnimatedText(pos, "Winner", TEXTCOLOR_YELLOW)
    end
end

-- Shows the number of keys in use.
-- @param cpos: Center position of the roulette.
local function showKeyCount(cpos)
    local keyCount = getGlobalStorageValue(config.globalStoKeyCount)
    keyCount = (keyCount < 1 or keyCount > 4) and 1 or keyCount
    local pos = {x = 266, y = 233, z = 15}
    doSendAnimatedText(pos, string.format("Keys: %d", keyCount), TEXTCOLOR_LIGHTBLUE)
end

-- ================= MAIN ROULETTE LOGIC ================= --
-- Main animation function, recursively called to simulate the roulette spin.
-- @param cid: Player ID.
-- @param cpos: Center position of the roulette.
-- @param rewardId: ID of the reward level.
-- @param nloop: Current iteration number.
-- @param slots: Table of slots (items).
-- @param keyName: Name of the key used.
-- @param keyCount: Number of keys used.
local function shuffle(cid, cpos, rewardId, nloop, slots, keyName, keyCount)
    if nloop > config.maxLoops then
        if isPlayer(cid) then
            -- Determine winning slots based on the number of keys used.
            local winningSlots = {}
            if keyCount == 1 then
                winningSlots = {36}
            elseif keyCount == 2 then
                winningSlots = {36, 18}
            elseif keyCount == 3 then
                winningSlots = {36, 18, 9}
            elseif keyCount == 4 then
                winningSlots = {36, 18, 9, 27}
            else
                winningSlots = {36} -- Default to one winning slot if keyCount is invalid.
            end

            -- Get the winning items and their positions.
            local wonItems = {}
            local winPositions = {}
            for _, slot in ipairs(winningSlots) do
                if slots[slot] then
                    table.insert(wonItems, slots[slot])
                    local pos = {
                        x = cpos.x + rouletteSpinOffset[slot][1],
                        y = cpos.y + rouletteSpinOffset[slot][2],
                        z = cpos.z
                    }
                    table.insert(winPositions, pos)
                end
            end

            -- Award the items and display visual effects.
            if #wonItems > 0 then
                for _, pos in ipairs(winPositions) do
                    doSendAnimatedText(pos, "Winner Slot", TEXTCOLOR_YELLOW)
                    doSendMagicEffect(pos, config.effectReward)
                end
                for _, item in ipairs(wonItems) do
                    doPlayerAddItem(cid, item.id, item.count)
                end
                doSendMagicEffect(getCreaturePosition(cid), config.effectRewardPlayer)
                
                 -- Display a message to the player with all the rewards.
                local itemList = {}
                for _, item in ipairs(wonItems) do
                    table.insert(itemList, string.format("x%d %s", item.count, getItemNameById(item.id)))
                end
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "[ROULETTE] You won: " .. table.concat(itemList, ", "))
                
                -- Log the player's rewards.
                logEntry(cid, keyName, wonItems, keyCount)
            else
                doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "[ROULETTE] No items won.")
            end
            setGlobalStorageValue(config.globalStoCd, 0)
        end
        return
    end

    -- Initial filling phase of the roulette slots.
    if nloop <= 36 then
        slots[nloop] = chooseRouletteItem(rewardId)
        updateRouletteDisplay(cpos, slots, true)
    else
        -- Rotate the slots and update the display.
        rotateSlots(slots)
        updateRouletteDisplay(cpos, slots, false)
        
        -- Show effects on the winning slots every 5 iterations.
        if nloop % 5 == 0 then
            local winningSlots = {}
            if keyCount == 1 then
                winningSlots = {36}
            elseif keyCount == 2 then
                winningSlots = {36, 18}
            elseif keyCount == 3 then
                winningSlots = {36, 18, 9}
            elseif keyCount == 4 then
                winningSlots = {36, 18, 9, 27}
            else
                winningSlots = {36} -- Default to one winning slot if keyCount is invalid.
            end

            for _, slot in ipairs(winningSlots) do
                local pos = {
                    x = cpos.x + rouletteSpinOffset[slot][1],
                    y = cpos.y + rouletteSpinOffset[slot][2],
                    z = cpos.z
                }
                doSendMagicEffect(pos, config.effectReward)
            end
        end
    end

    -- Schedule the next iteration with dynamic speed.
    local progress = nloop / config.maxLoops
    addEvent(shuffle, calculateSpeed(progress), cid, cpos, rewardId, nloop + 1, slots, keyName, keyCount)
end

-- ================= PERIODIC EFFECTS AND TEXTS ================= --
-- Shows effects and texts periodically.
-- @param cpos: Center position of the roulette.
local function showEffectsAndTexts(cpos)
    local keyCount = getGlobalStorageValue(config.globalStoKeyCount)
    keyCount = (keyCount < 1 or keyCount > 4) and 1 or keyCount -- Ensure keyCount is within range.

    -- Show "Winner Slot" on the winning slots.
    showWinnerSlots(cpos, keyCount)

    -- Show the number of keys in use.
    showKeyCount(cpos)

    -- Schedule the next execution.
    addEvent(showEffectsAndTexts, 1500, cpos)
end

-- ================= EFFECT SCRIPT INITIALIZATION ================= --
-- Start the periodic effects and texts when the script is loaded.
local cpos = {x = 266, y = 233, z = 15} -- Center position of the roulette.
addEvent(function()
    showEffectsAndTexts(cpos)
end, 5000) -- 5 seconds delay since server start.

-- ================= MAIN OBJECT USE FUNCTION ================= --
-- Called when the roulette object is used.
function onUse(cid, item, frompos, item2, topos)
    -- Handle the key change lever.
    if item.aid == 1360 then
        local current = getGlobalStorageValue(config.globalStoKeyCount)
        current = (current < 1 or current > 4) and 1 or (current % 4) + 1
        setGlobalStorageValue(config.globalStoKeyCount, current)
        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, string.format("Now using %d keys per spin.", current))
        doSendMagicEffect(getThingPos(item.uid), CONST_ME_MAGIC_GREEN)
        return true
    end

    -- Handle the roulette levers.
    if not keyByAid[item.aid] then return false end

    local key = keyByAid[item.aid]
    local keyName = getItemNameById(key)
    local requiredKeys = getGlobalStorageValue(config.globalStoKeyCount)
    requiredKeys = (requiredKeys < 1 or requiredKeys > 4) and 1 or requiredKeys

    if getPlayerAccess(cid) < 5 and getPlayerItemCount(cid, key) < requiredKeys then
        doPlayerSendCancel(cid, string.format("You need %d %s to play!", requiredKeys, keyName))
        doSendMagicEffect(topos, 14)
        return true
    end

    local rewardId = rewardByAid[item.aid] or 1 -- Get the reward level based on the lever. Default to 1 if not found.
    local pos = {x = 266, y = 233, z = 15} -- Center position of the roulette.

    if getGlobalStorageValue(config.globalStoCd) > os.time() and getPlayerAccess(cid) < 5 then
        local remaining = getGlobalStorageValue(config.globalStoCd) - os.time()
        doPlayerSendCancel(cid, "Wait " .. remaining .. " seconds to play again.")
        return true
    end

    setGlobalStorageValue(config.globalStoCd, os.time() + config.rouletteCD) -- Set the cooldown.
    doTransformItem(item.uid, item.itemid == 9825 and 9826 or 9825) -- Change the lever's appearance.

    -- Clear the tiles around the roulette and add magic effects.
    for i = 1, 36 do
        local rpos = {
            x = pos.x + rouletteSpinOffset[i][1],
            y = pos.y + rouletteSpinOffset[i][2],
            z = pos.z
        }
        doCleanTile(rpos)
        doSendMagicEffect(rpos, config.effectReward)
    end

    if key > 0 then doPlayerRemoveItem(cid, key, requiredKeys) end -- Remove the keys from the player's inventory.
    doSendMagicEffect(pos, config.effectLever) -- Play the lever activation effect.

    math.randomseed(os.time() + getPlayerGUID(cid)) -- Seed the random number generator.
    addEvent(shuffle, config.initialSpeed, cid, pos, rewardId, 1, {}, keyName, requiredKeys) -- Start the roulette animation.
    return true
end
Link para o comentário
https://xtibia.com/forum/topic/259988-advanced-roulette-system-tfs-036-socorro-me-ajuda/
Compartilhar em outros sites

0 respostass a esta questão

Posts Recomendados

Até agora não há respostas para essa pergunta

  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...