Ir para conteúdo
  • Cadastre-se

(Resolvido)Sistema para evento programado com tps [8.60]


Ir para solução Resolvido por Adriano SwaTT,

Posts Recomendados

Bom galera, o sisteminha é um pouquim complexo, mas vamos lá...

 

Gostaria que todo dia 1°, às 12:00, abram 6 TPs no mapa.

Esses tps devem ficar abertos por 12 horas, após esse horários eles desapareçam.

 

Porém, há dois problemas:

Um dos TPs só poderá ser acessado contendo 5 diferentes storages (o player tem que ter os 5).

O player após entrar 1 vez em qualquer um dos TPs, ele só poderá entrar novamente em qualquer um dos tps na próxima vez que o evento iniciar, ou seja, no próximo dia 1.

 

PS.: incluir mensagens informando que o evento inciou e os Tps abriram, quando os tps fecharem, que o player não pode entrar novamente no tp (caso já tenha entrado)

 

Desde já agreço!

Editado por lolksky (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
  • Solução

Boa noite.

Criei e testei o script, as funções básicas que precisa consegui executar com sucesso.

 

1. Ele cria os teleportes, cada um com uma ActionID diferente para que você possa criar um script para cada teleporte e assim configurar os requisitos para poder entrar.

2. Ele cria os teleportes no horário programado no GlobalEvents.xml, e a data fica configurada dentro do próprio script.

3. Ele remove os teleportes depois do tempo programado.

4. Ele bloqueia players que já acessaram um dos teleportes, já configurado para liberar a cada evento.

 

Vamos em GlobalEvents.xml e adicionar a tag abaixo:

<globalevent name="Teleports" time="12:00" event="script" value="teleports_progs.lua"/>

 

Agora na pasta scripts da referida, criaremos o arquivo "teleports_progs.lua" e adicionaremos o script abaixo:

--------- Script by: Adriano Swatt' ------
local dia = '1' -- qual dia do mês
local horas = 12 -- hora do evento & horas para remover os tps
local tp_id = 5023 -- ID do Teleport (Pode ser outro item, se desejar)
local gstrg_control = 12129 -- Não precisa mexer (Global Storage de Controle de Acesso)
local tp_pos = {{x=000, y=000, z=0}, {x=000, y=000, z=0}, {x=000, y=000, z=0}, {x=000, y=000, z=0}, {x=000, y=000, z=0}, {x=000, y=000, z=0}} -- Coordenada Onde Nascerá os TPs
local tp_acts = {11111, 22222, 33333, 44444, 55555, 66666} -- ActionID para Cada TP (Terá que registrar em movements.xml as memas que colocar aqui)
----------- FIM DAS CONFIGURAÇÕES ---------

function onTimer()
local checkday = os.date("%d")
    if checkday == dia then
        for x = 1, #tp_pos do
        doItemSetAttribute(doCreateItem(tp_id, 1, tp_pos[x]), "aid", tp_acts[x])
        end -- FOR
        addEvent(RemoveTps, horas * 60 * 60 * 1000)
        doBroadcastMessage("Hoje é dia "..checkday.." e são exatamente "..horas..":00 horas, os teleportes de bonus foram abertos e permanecerão por "..horas.." horas.")
        if getGlobalStorageValue(gstrg_control) <= 0 then
            setGlobalStorageValue(gstrg_control, 1)
        else
            setGlobalStorageValue(gstrg_control, (getGlobalStorageValue(gstrg_control) + 1))
        end
        return true
    else
        doBroadcastMessage("Lembrem-se: Todo dia "..checkday.." às "..horas.." horas terá o evento dos teleportes.")
    end
return true
end

function RemoveTps()
    for y = 1, #tp_pos do
    doRemoveItem(getTileItemById(tp_pos[y], tp_id).uid, 1)
    end -- FOR
    doBroadcastMessage("Os teleportes foram removidos, o evento abrirá novamente no próximo dia "..dia.." exatamente às "..horas..":00 horas.")
return true
end

 

Agora em Movements.xml adicionaremos a tag, como abaixo: (Substitua os números de acordo com que configurou o script anterior/acima)

<movevent type="StepIn" actionid="11111;22222;33333;44444;55555;66666" event="script" value="Teleports_Progs.lua"/>

 

E em scripts, criaremos o arquivo "Teleports_Progs.lua" e adicionaremos o código abaixo:

-------- Script by: Adriano Swatt' -------
local gstrg_control = 12129 -- Não precisa mexer (Global Storage de Controle de Acesso)
local tp_exe = 11111 -- ID da ActionID do Teleport Exclusivo (Necessita 5 storages)
local stors = {11111, 22222, 33333, 44444, 55555} -- Storages o player precisa para o teleport exclusivo
local tp_acts = {
    [11111] = {{x=000, y=000, z=0}}, -- ActionID de cada teleport e coordenada pra onde o player irá (Tem que ser a mesma do outro script)
    [22222] = {{x=000, y=000, z=0}}, -- teleport 2
    [33333] = {{x=000, y=000, z=0}}, -- teleport 3
    [44444] = {{x=000, y=000, z=0}}, -- teleport 4
    [55555] = {{x=000, y=000, z=0}}, -- teleport 5
    [66666] = {{x=000, y=000, z=0}}  -- teleport 6
}
local msgs = {
"Você não tem todas as quests necessárias.", -- Mensagem quando não tiver todas storages
"Você já entrou em um dos teleportes bônus hoje.", -- Mensagem quando já tiver acessado um dos teleportes
"Parabéns, você entrou no teleporte bônus." -- Mensagem ao entrar em algum teleporte
} -- Mensagens
----------- FIM DAS CONFIGURAÇÕES ---------

function onStepIn(cid, item, position, fromPosition)
local tp_check = tp_acts[item.actionid]
local gstrg = getGlobalStorageValue(gstrg_control)
local getSto = getPlayerStorageValue

    if item.actionid ~= tp_exe then
        if tp_check then
            if getSto(cid, gstrg_control) < (gstrg) then
                doPlayerSendCancel(cid, msgs[3])
                doTeleportThing(cid, tp_check[1])
                setPlayerStorageValue(cid, gstrg_control, (getGlobalStorageValue(gstrg_control)))
            else
                doPlayerSendCancel(cid, msgs[2])
                doTeleportThing(cid, fromPosition)
            end
        end
    else
        if getSto(cid, gstrg_control) < (gstrg) then
            if getSto(cid, stors[1]) >= 1 and getSto(cid, stors[2]) >= 1 and getSto(cid, stors[3]) >= 1 and getSto(cid, stors[4]) >= 1 and getSto(cid, stors[5]) >= 1 then
                doPlayerSendCancel(cid, msgs[3])
                doTeleportThing(cid, tp_check[1])
                setPlayerStorageValue(cid, gstrg_control, (getGlobalStorageValue(gstrg_control)))
            else
                doPlayerSendCancel(cid, msgs[1])
                doTeleportThing(cid, fromPosition)
            end
        else
            doPlayerSendCancel(cid, msgs[2])
            doTeleportThing(cid, fromPosition)
        end
    end
    return true
end
 

 

Testei e funcionou perfeitamente.

 

Boa sorte.

Caso ocorra algum erro, ou até mesmo para agradecer, dê um FeedBack. ;)

 

Abraços.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Cara, eu cometi um erro e passei uma informação errônea.

 

onde se lê: "2°  O player após entrar 1 vez em qualquer um dos TPs, ele só poderá entrar novamente em qualquer um dos tps na próxima vez que o evento iniciar, ou seja, no próximo dia 1."

Seria na verdade: " O player após entrar 1 vez no TP que precisa dos storages, ele só poderá entrar novamente em qualquer um dos tps na próxima vez que o evento iniciar, ou seja, no próximo dia 1."

 

Teria como corrigir isso?  Peço-lhe desculpas, foi falta de atenção minha.  :D

Link para o post
Compartilhar em outros sites

Tente substituir o movements por este:

-------- Script by: Adriano Swatt' -------
local gstrg_control = 12129 -- Não precisa mexer (Global Storage de Controle de Acesso)
local tp_exe = 11111 -- ID da ActionID do Teleport Exclusivo (Necessita 5 storages)
local stors = {11111, 22222, 33333, 44444, 55555} -- Storages o player precisa para o teleport exclusivo
local tp_acts = {
    [11111] = {{x=000, y=000, z=0}}, -- ActionID de cada teleport e coordenada pra onde o player irá (Tem que ser a mesma do outro script)
    [22222] = {{x=000, y=000, z=0}}, -- teleport 2
    [33333] = {{x=000, y=000, z=0}}, -- teleport 3
    [44444] = {{x=000, y=000, z=0}}, -- teleport 4
    [55555] = {{x=000, y=000, z=0}}, -- teleport 5
    [66666] = {{x=000, y=000, z=0}}  -- teleport 6
}
local msgs = {
"Você não tem todas as quests necessárias.", -- Mensagem quando não tiver todas storages
"Você já entrou em um dos teleportes bônus hoje.", -- Mensagem quando já tiver acessado um dos teleportes
"Parabéns, você entrou no teleporte bônus." -- Mensagem ao entrar em algum teleporte
} -- Mensagens
----------- FIM DAS CONFIGURAÇÕES ---------

function onStepIn(cid, item, position, fromPosition)
local tp_check = tp_acts[item.actionid]
local gstrg = getGlobalStorageValue(gstrg_control)
local getSto = getPlayerStorageValue

    if item.actionid ~= tp_exe then
        if tp_check then
            doPlayerSendCancel(cid, msgs[3])
            doTeleportThing(cid, tp_check[1])
        end
    else
        if getSto(cid, gstrg_control) < (gstrg) then
            if getSto(cid, stors[1]) >= 1 and getSto(cid, stors[2]) >= 1 and getSto(cid, stors[3]) >= 1 and getSto(cid, stors[4]) >= 1 and getSto(cid, stors[5]) >= 1 then
                doPlayerSendCancel(cid, msgs[3])
                doTeleportThing(cid, tp_check[1])
                setPlayerStorageValue(cid, gstrg_control, (getGlobalStorageValue(gstrg_control)))
            else
                doPlayerSendCancel(cid, msgs[1])
                doTeleportThing(cid, fromPosition)
            end
        else
            doPlayerSendCancel(cid, msgs[2])
            doTeleportThing(cid, fromPosition)
        end
    end
    return true
end

 

Boa sorte.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Não é para substituir o arquivo LUA do globalevents, e sim o do movements. "Teleports_Progs.lua".

É o segundo script.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Mas é da pasta movements e não globalevents.

O da globalevents tem que ficar o primeiro que te mandei.

 

Veja o que postou:

Evento onTime not found (data/globalevents/scripts/teleports_progs.lua)

 

Está colocando errado, abra a pasta movements e pegue o script que te mandei.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

 

Muda:

function onTimer()
para:
function onTime()
E vê se o erro continua.

 

Boa noite,

Zipter98, o erro está acusando porque ele substituiu o arquivo errado, como pode ver no erro, ele substituiu o arquivo do globalevents, e colocou um do movements, onde não existe a função onTimer().

Por isso o erro.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Há servidores, como o seu, que existe a função onTimer. Já, em outros servidores, esta função não existe ou adota o nome de onTime. Se você cria um arquivo com o callback onTimer num servidor que o correto seria onTime, vai acusar este erro que o autor postou. 

Editado por zipter98 (veja o histórico de edições)

não respondo pms solicitando suporte em programação/scripting

Link para o post
Compartilhar em outros sites

Eu fiz o que o zipter disse e sumiu o erro.

Porém, quanto ao funcionamento, os TPS abrem e talz, mas qdo eu passo sobre eles, nao teleporta. É como se andasse sobre ele normalmente.

 

@UP

 

tinha um errim aqui no AID.

Vou testar novamente corrigido.

 

 

Está ocorrendo o seguinte: mesmo com os storages, quando eu passo no TP q precisa dos storages, diz que eu não os tenho.

Editado por lolksky (veja o histórico de edições)
Link para o post
Compartilhar em outros sites

Há servidores, como o seu, que existe a função onTimer. Já, em outros servidores, esta função não existe ou adota o nome de onTime. Se você cria um arquivo com o callback onTimer num servidor que o correto seria onTime, vai acusar este erro que o autor postou. 

Sei disso, porém, acho que ele testou o script e pediu pra eu corrigir o script dos teleports.

Caso realmente não esteja cometendo o erro de por o arquivo movements em globalevents, realmente mudando a função onTime() resolverá.

 

#TOPICO:

Você adicionou as actionsID em movements.xml e registrou o script movements corretamente?

Editado por Adriano SwaTT (veja o histórico de edições)

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Que bom que ajudou.

Só vou pedir para clicar em "Melhor Resposta" pro tópico ficar como Solucionado.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Se for outro script, sugiro que crie um tópico específico.

 

Estamos no aguardo.

Gosta do meu trabalho?

Curta e siga a página do meu projeto de 2016 e 2017 (Lab Z Games) que trará vários servidores OTServs.

 

Atenciosamente,
Adriano Swatt'

 

Para ver meus tutoriais acesse meu perfil.

 

cbCyOSZ.png

Link para o post
Compartilhar em outros sites

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

  • Conteúdo Similar

    • Por Neutraz
      Advanced Roulette System (TFS 0.3.6)
       
      Hi everyone! This is my first contribution to the Tibia community, and I hope you find it very useful. It's a gacha-style roulette system with dynamic speed mechanics and multi-key functionality.
       
      What's it about?
      This script adds a roulette (Tested on: Tibia 8.6 -- TFS 0.3.6) where players can use keys to spin the roulette and win rewards. The system includes:
      Multi-key support: using 1 to 4 keys per spin, increasing the chances of winning. Dynamic speed: The roulette gradually accelerates during the spin to make it more exciting. Configurable rewards: You can define which items can be won and with what probability. You can even add "reroll" value to increase the difficulty! Visual effects: Includes simple effects and text animations to make the experience more engaging. Activity log: Keeps a record of which players won which items.  
      Demo Video (x1.5 Speed)
      Roulette2.mp4
       
       
      Installation
      Copy the `Roulette.lua` file to the `data/actions/scripts` folder of your TFS server. --[[ ================================================================================ = 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 = 1, chance = 80, count = 5}, }, [2] = { {id = 2, chance = 70, count = 1, porc_cambio = 30}, }, [3] = { {id = 3, chance = 25, count = 1, porc_cambio = 70} } } } -- ================= 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 Slot", 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 = 1013, y = 995, z = 7} 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 = 1012, y = 994, z = 7} -- 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 = 1012, y = 994, z = 7} -- 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  
      Add the following lines within the `<actions>` tag in your `data/actions/actions.xml` file: <action actionid="XXX;YYYY;ZZZZ;AAAA" event="script" value="Roulette.lua"/> Replace `XXXX`, `YYYY`, and `ZZZZ` with the unique IDs of the levers that will activate the roulette (make sure they are not in use!).
      The ID `AAAA` is for the lever that changes the number of keys to use.
       
      Open the `Roulette.lua` file and adjust the `config.items` table with the items you want players to be able to win. Remember to balance the probabilities.  
       
      Code Explanation
      The script is divided into several sections to facilitate understanding:
      LOGGING SYSTEM: Handles logging the rewards obtained by players. BASE CONFIGURATION: Defines object IDs and reward levels. MAIN CONFIGURATION: Contains the main options of the system, such as the wait time between spins, the speed of the roulette, and the rewards. PROBABILITY CACHING: Optimizes the calculation of probabilities so that the system runs smoothly. UTILITY FUNCTIONS: Helper functions to calculate speed, choose items randomly, and update the roulette display. WINNER SLOTS AND EFFECTS: Displays the "Winner Slot" text and other visual effects in the winning spaces. MAIN ROULETTE LOGIC: The main function that controls the roulette animation and the delivery of rewards. PERIODIC EFFECTS AND TEXTS: Displays effects and texts periodically. SCRIPT INITIALIZATION: Initializes the effect system when the script is loaded. MAIN OBJECT USE FUNCTION: The function that is executed when a player interacts with a lever.

      I hope this roulette system is a great addition to your server! If you have any questions or suggestions, please feel free to leave a comment. Thank you for your support!  
       
    • Por luanluciano93
      Olá pessoal, estou desenvolvendo esse sistema vip para TFS 1.x, se precisarem de alguma função nova é só comentar, criei para usar em um servidor meu e resolvi postar, bom proveito a todos.
       
      É só ir no arquivo data/lib/core/player.lua e adicionar esse código no começo do script:
      -- ALTER TABLE `accounts` ADD `vip_time` BIGINT(20) NOT NULL DEFAULT 0; -- player:getVipTime() function Player.getVipTime(self) local resultId = db.storeQuery("SELECT `vip_time` FROM `accounts` WHERE `id` = '".. self:getAccountId() .."';") local time = resultId ~= false and result.getNumber(resultId, "vip_time") or 0 result.free(resultId) return time end -- player:isVip() function Player.isVip(self) return self:getVipTime() > os.time() and true or false end -- player:addVipDays(days) function Player.addVipDays(self, days) return(self:isVip() and tonumber((days * 86400))) and db.query("UPDATE `accounts` SET `vip_time` = '".. (self:getVipTime() + (days * 86400)) .."' WHERE `id` ='".. self:getAccountId() .."' LIMIT 1 ;") or db.query("UPDATE `accounts` SET `vip_time` = '".. (os.time() + (days * 86400)) .."' WHERE `id` ='".. self:getAccountId() .."' LIMIT 1 ;") end -- player:removeVipDays(days) function Player.removeVipDays(self, days) return(self:isVip() and tonumber((days * 86400))) and db.query("UPDATE `accounts` SET `vip_time` = '".. (self:getVipTime() - (days * 86400)) .."' WHERE `id` ='".. self:getAccountId() .."' LIMIT 1 ;") or db.query("UPDATE `accounts` SET `vip_time` = '".. (os.time() - (days * 86400)) .."' WHERE `id` ='".. self:getAccountId() .."' LIMIT 1 ;") end -- player:setVipDays(days) function Player.setVipDays(self, days) return db.query("UPDATE `accounts` SET `vip_time` = '".. (os.time() - (days * 86400)) .."' WHERE `id` ='".. self:getAccountId() .."' LIMIT 1 ;") end -- player:removeVip() function Player.removeVip(self) db.query("UPDATE `accounts` SET `vip_time` = '0' WHERE `id` ='".. self:getAccountId() .."' LIMIT 1 ;") end -- player:sendVipDaysMessage() function Player.sendVipDaysMessage(self) if self:isVip() then local vipTime = self:getVipTime() - os.time() local vipDays = 1 + (math.floor(vipTime / 86400)) return self:getVipTime() ~= false and self:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'You have '.. vipDays .. ' vip day(s) in your account.') end end -- player:checkVipLogin() function Player.checkVipLogin(self) if self:getVipTime() > 0 and not self:isVip() then return self:removeVip() and self:teleportTo(self:getTown():getTemplePosition()) end end  
       
      As funções são:
      • player:getVipTime() - Retorna o valor da tabela vip_time (igual esta na database).
      • player:isVip() - Retorna se o player é vip ou não.
      • player:addVipDays(days) - Usa-se em algum script para para adicionar dias de vip ao player (parâmetro de entrada "days").
      • player:removeVipDays(days) - Usa-se em algum script para para remover dias de vip do player (parâmetro de entrada "days").
      • player:setVipDays(days) - Usa-se em algum script para para mudar os dias de vip do player (parâmetro de entrada "days").
      • player:removeVip() - Usa-se em algum script para para remover todo tempo de vip do player.
      • player:sendVipDaysMessage() - Retorna uma mensagem no player mostrando os dias de vip que ainda restam ao player.
      • player:checkVipLogin() - Checa se a vip do player acabou, se sim teleporta ele para o templo.
       

      Qualquer dúvida ou erro/bug poste aqui.
    • Por Killua
      Como funciona?
      A cada monstro que vc mata, seus itens equipados ganham 1 de exp. Quando seus itens chegarem às quantidades de exp definidas, eles upam e ficam com o nome assim: Demon Helmet + 1. Helmets, armors, legs, e boots recebem 1 de arm a cada vez que upam. Armas recebem 1 de ataque e escudos 1 de defesa.
       
      Para o monstro contar, ele deve dar um mínimo de exp (definido no script). O número de exp a que me refiro é aquele um presente no arquivo .xml.
       
      Para instalar, crie Killua Items Upgrade.lua em data/creaturescripts/scripts e coloque:
        Em data/creaturescripts/creaturescripts.xml coloque essas duas tags:
      <event type="kill" name="Item level" event="script" value="Killua Items Upgrade.lua"/> <event type="login" name="Item levell" event="script" value="Killua Items Upgrade.lua"/> Configurando: Na tabela table_of_slots, coloque em quais slots os itens upam.
      min_exp é a experiência mínima que o monstro deve ter para contar exp para o item. Se vc colocar 500, somente os monstros que tem exp igual ou superior a 500 no arquivo.xml vão valer.
      exp_levels são os valores de exp que os itens devem atingir para upar. No meu caso, quando o item alcançar 50 de exp, ele upa para o level 1. Quando alcançar 50 de exp, upa para o level 2 e assim por diante.
    • Por Xagah
      Olá, bom dia a todos.
       
      Como tenho visto muitíssimos pedidos neste sentido, lhes apresento o LMS - Last Man Standing com BroadCast




       
    • Por Leohige
      Evento Loteria 
       
       
      Esse evento loteria é diferente dos demais que existem hoje nos servidores, é baseado em cima de um evento que ocorre no CraftLandia (um servidor de Minecraft).
      Quando o evento for iniciado o jogador poderá pagar um valor (configurável) para tentar acertar o número premiado (que vai de 1 até o número configurado). O evento tem um tempo de duração (configurável) e o primeiro jogador a acertar qual é o número premiado levará um premio em dinheiro (configurável) e o evento será encerrado.
       
      Demonstrações:
       
       
       
       
      Comandos:
       
       
      Configuração:
       
       
      Caso queira implementar este evento em seu servidor, crie os arquivos abaixo.
       
      data/lib/lottery/event.lua (as configurações ficam neste arquivo)
       
       
      data/globalevents/scripts/lottery.lua
       
       
      data/globalevents/globalevents.xml
       
      você pode por com um intervalo de tempo
       
       
      ou horário fixo
       
       
      data/talkactions/scripts/lottery.lua
       
       
      data/talkactions/talkactions.xml
       
       
      Tradução para PT-BR!
       
      Caso deseje traduzir o evento, substitua o Lottery.messages inteiro em data/lib/lottery/event.lua por este
       
       
      Qualquer problema, sugestão, bug ou dúvida utilize este tópico!!!
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo