Ir para conteúdo

Mateus Robeerto

Héroi
  • Registro em

  • Última visita

Tudo que Mateus Robeerto postou

  1. Não há necessidade de fazer isso no onLogin e onLogout, pois, caso o jogador relogue ou morra, esse addvent é capaz de identificar o CID do jogador se ele estiver online. Nesse caso, ele passará pela storage para resetá-la, utilizando, por exemplo, setPlayerStorageValue(cid, 4000, 0), que é responsável por esse reset. O método mais apropriado é utilizar getPlayerGUID() em vez disso. Dessa forma, se desejar que o addEvent seja acionado no jogador mesmo após ele ter deslogado ou morrido, será necessário recriar o objeto do jogador de forma convencional, porém utilizando getPlayerGUID(). Além disso, o GUID é um identificador permanente. Assim, ao invés de utilizar isPlayer(cid), é recomendado utilizar getPlayerGUID(). Desta maneira, caso o jogador realize login e logout, e o evento adicional esteja ocorrendo, será possível recriar o objeto do jogador utilizando o GUID e encontrar o jogador novamente. Sem usar esse método 'GUID', o addvent não consegue encontrar o jogador após a morte ou relogar. Isso poderia causar um crash no servidor. function onCastSpell(cid, var) local storage = 55512 -- Storage para controlar a spell local stages = { {time = 20, value = 1}, -- 20 segundos, storage = 1 {time = 30, value = 2}, -- 30 segundos adicionais, storage = 2 {time = 40, value = 3} -- 40 segundos adicionais, storage = 3 } -- Verificar se o jogador já usou a spell if getPlayerStorageValue(cid, storage) > 0 then doPlayerSendCancel(cid, "Você já está sob o efeito da spell.") return false end if not isCreature(cid) then return false end -- Função para alterar a storage e verificar se o jogador está online local function changeStorage(playerGUID, newValue, previousTime) local player = getPlayerByGUID(playerGUID) if player then setPlayerStorageValue(player, storage, newValue) if newValue == -1 then doPlayerSendTextMessage(player, MESSAGE_STATUS_CONSOLE_BLUE, "O efeito da spell terminou.") end end end -- Obter o GUID do jogador local playerGUID = getPlayerGUID(cid) -- Definir a storage inicial setPlayerStorageValue(cid, storage, stages[1].value) -- Agendar as mudanças de storage local accumulatedTime = 0 for i, stage in ipairs(stages) do accumulatedTime = accumulatedTime + stage.time addEvent(changeStorage, accumulatedTime * 1000, playerGUID, stage.value, accumulatedTime) end -- Agendar o reset da storage para o valor -1 após o último estágio accumulatedTime = accumulatedTime + stages[#stages].time addEvent(changeStorage, accumulatedTime * 1000, playerGUID, -1, accumulatedTime) return true end -- Função auxiliar para encontrar o jogador pelo GUID function getPlayerByGUID(guid) for _, pid in ipairs(getPlayersOnline()) do if getPlayerGUID(pid) == guid then return pid end end return nil -- Jogador não encontrado ou offline end
  2. O script anterior estava bugado e mal otimizado, faltando algumas funções. Então, fiz uma correção e agora está funcionando bem! De acordo com sua vocação, você pode comprar skills... Para quem deseja ultrapassar o limite de 350 skills, basta fazer algumas alterações no código-fonte para quebrar o limite e poder ter 350+ habilidades, entende? Espero ter ajudado. testado e funcional ok!! -- Definição das habilidades e suas características local skills = { ["magiclevel"] = {vocations = {1, 5, 2, 6, 11, 12}, voc_msg= "Somente Sorcerers, Druids e Infernalists podem comprar magic level.", lim = 200, lim_msg = "Você não pode ter magic level acima de 200.", price= 3, incre = 1, skill = SKILL_MAGLEVEL}, ["skillclub"] = {vocations = {1, 10}, voc_msg= "Somente Drunous podem comprar skill de club.", lim = 350, lim_msg = "Você não pode ter skill club acima de 350.", price= 1, incre = 1, skill = SKILL_CLUB}, ["skillsword"] = {vocations = {4, 8}, voc_msg= "Somente Knights podem comprar skill de sword.", lim = 350, lim_msg = "Você não pode ter skill sword acima de 350.", price= 1, incre = 1, skill = SKILL_SWORD}, ["skillaxe"] = {vocations = {4, 8}, voc_msg= "Somente Knights podem comprar skill de axe.", lim = 350, lim_msg = "Você não pode ter skill axe acima de 350.", price= 1, incre = 1, skill = SKILL_AXE}, ["skilldistance"] = {vocations = {3, 7}, voc_msg= "Somente Paladins podem comprar skill de distance.", lim = 350, lim_msg = "Você não pode ter skill distance acima de 350.", price= 1, incre = 1, skill = SKILL_DISTANCE}, ["skillshielding"] = {vocations = {3, 7, 4, 8, 9, 10}, voc_msg= "Somente Paladins, Knights e Drunous podem comprar skill de shield.", lim = 350, lim_msg = "Você não pode ter skill shielding acima de 350.", price= 1, incre = 1, skill = SKILL_SHIELD}, ["magiclevel5"] = {vocations = {1, 5, 2, 6, 11, 12}, voc_msg= "Somente Sorcerers, Druids e Infernalists podem comprar magic level.", lim = 200, lim_msg = "Você não pode pode ter magic level acima de 200.", price= 15, incre = 5, skill = SKILL_MAGLEVEL}, ["skillclub10"] = {vocations = {9, 10}, voc_msg= "Somente Drunous podem comprar skill de club.", lim = 350, lim_msg = "Você não pode ter skill club acima de 350.", price= 10, incre = 10, skill = SKILL_CLUB}, ["skillsword10"] = {vocations = {4, 8}, voc_msg= "Somente Knights podem comprar skill de sword.", lim = 350, lim_msg = "Você não pode ter skill sword acima de 350.", price= 10, incre = 10, skill = SKILL_SWORD}, ["skillaxe10"] = {vocations = {4, 8}, voc_msg= "Somente Knights podem comprar skill de axe.", lim = 350, lim_msg = "Você não pode ter skill axe acima de 350.", price= 10, incre = 10, skill = SKILL_AXE}, ["skilldistance10"] = {vocations = {3, 7}, voc_msg= "Somente Paladins podem comprar skill de distance.", lim = 350, lim_msg = "Você não pode ter skill distance acima de 350.", price= 10, incre = 10, skill = SKILL_DISTANCE}, ["skillshielding10"] = {vocations = {3, 7, 4, 8, 9, 10}, voc_msg= "Somente Paladins, Knights e Drunous podem comprar skill de shield.", lim = 350, lim_msg = "Você não pode ter skill shielding acima de 350.", price= 10, incre = 10, skill = SKILL_SHIELD}, } -- Função para obter o nome da habilidade com base no ID local function getPlayerSkillName(skillId) local skillNames = { [SKILL_CLUB] = "Club", [SKILL_SWORD] = "Sword", [SKILL_AXE] = "Axe", [SKILL_DISTANCE] = "Distance", [SKILL_SHIELD] = "Shielding", [SKILL_MAGLEVEL] = "Magic Level" } return skillNames[skillId] or "Unknown" end local function buySkill(player, skillData) local coinID = 9971 -- ID da moeda utilizada para compra local storage = 45611 -- Valor de armazenamento para controle de tempo if player:getItemCount(coinID) < skillData.price then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "Você não possui a quantidade necessária para comprar.") return false end local skillId = skillData.skill local skillName = getPlayerSkillName(skillId) local currentSkill if skillId == SKILL_MAGLEVEL then currentSkill = player:getMagicLevel() else currentSkill = player:getSkillLevel(skillId) end if currentSkill == nil then player:sendCancelMessage("Você não possui essa habilidade.") return false end if skillId == SKILL_MAGLEVEL then local newMagLevel = currentSkill + skillData.incre if newMagLevel > skillData.lim then player:sendCancelMessage(skillData.lim_msg) return false end player:addMagicLevel(skillData.incre) print("Player: " .. player:getName() .. " adquiriu " .. skillData.incre .. " níveis de magic level. Novo magic level: " .. newMagLevel) else player:addSkill(skillId, skillData.incre) print("Player: " .. player:getName() .. " adquiriu " .. skillData.incre .. " níveis em " .. skillName) end if not isInArray(skillData.vocations, player:getVocation():getId()) then player:sendCancelMessage(skillData.voc_msg) return false end player:removeItem(coinID, skillData.price) player:setStorageValue(storage, os.time() + 1) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "Você comprou " .. skillData.incre .. " níveis em " .. skillName .. " por " .. skillData.price .. " moedas.") return true end local buyComprar = TalkAction("!comprar") function buyComprar.onSay(player, words, param) local param = param:lower() local tile = player:getTile() if not tile or not tile:hasFlag(TILESTATE_PROTECTIONZONE) then player:sendCancelMessage("Você precisa estar em área protegida para utilizar este comando.") return false end local storage = 45611 -- Valor de armazenamento para controle de tempo if player:getStorageValue(storage) >= os.time() then player:sendCancelMessage("Por medidas de segurança você só pode utilizar este comando em " .. (player:getStorageValue(storage) - os.time()) .. " segundos.") return false end if param == "" or not skills[param] then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "Comando inválido ou habilidade não encontrada. Use !comprar <habilidade> para comprar.") return false end local skillData = skills[param] local playerVocation = player:getVocation():getId() if not isInArray(skillData.vocations, playerVocation) then player:sendCancelMessage("Sua vocação não pode comprar essa habilidade.") return false end return buySkill(player, skillData) end buyComprar:separator(" ") buyComprar:register()
  3. local config = { teleports = { { teleportPosition = { x = 32399, y = 32202, z = 7 }, teleportDestination = Position(32395, 32194, 7)}, { teleportPosition = { x = 32400, y = 32202, z = 7 }, teleportDestination = Position(32395, 32194, 7)} }, TI_TITANIUM_TOKEN = 28493 } function playerHasTitaniumToken(player) if not player then return false end local inventory = player:getItems() if not inventory then return false end for _, item in ipairs(inventory) do if item:getId() == config.TI_TITANIUM_TOKEN then return true end end return false end local arena = MoveEvent() function arena.onStepIn(creature, item, position, fromPosition) local player = creature:getPlayer() if not player then return true end if playerHasTitaniumToken(player) then local playerPosition = player:getPosition() for _, teleport in ipairs(config.teleports) do local teleportPos = Position(teleport.teleportPosition) if playerPosition == teleportPos then player:teleportTo(teleport.teleportDestination) return true end end else player:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Você precisa do Titanium Token para acessar este teleport.") end return true end for _, teleport in ipairs(config.teleports) do arena:position(Position(teleport.teleportPosition)) end arena:register()
  4. Adicionei o comando "print" para imprimir no console e saber o que aconteceu, etc. Isso vai ajudar bastante. local config = { minSkill = 10, -- Valor mínimo da habilidade para começar a treinar gainChance = 50, -- Chance de ganhar skill, em porcentagem requiredItemID = 2140, -- ID do item necessário para treinar trainInterval = 3000, -- Intervalo de tempo para tentar ganhar skill (em milissegundos) skillsToTrain = { -- Habilidades correspondentes para cada vocação [0] = {1, 2}, -- Vocação sem classe [1] = {1, 2}, -- Knight [2] = {3}, -- Paladin [3] = {4}, -- Sorcerer [4] = {4}, -- Druid [5] = {4}, -- Master Sorcerer [6] = {4} -- Elder Druid } } local skillEvents = {} -- Tabela para armazenar os eventos de treino function isInRange(playerPosition, centerPosition, range) return math.abs(centerPosition.x - playerPosition.x) <= range and math.abs(centerPosition.y - playerPosition.y) <= range and centerPosition.z == playerPosition.z end function onStepIn(cid, item, position, fromPosition) print("Entrou na função onStepIn") if not isPlayer(cid) then print("O personagem não é um jogador") return false end local vocation = getPlayerVocation(cid) print("Vocação do jogador: " .. vocation) if not config.skillsToTrain[vocation] then print("Vocação não encontrada na configuração de treino") return false end for _, skillToTrain in ipairs(config.skillsToTrain[vocation]) do local skillLevel = getPlayerSkillLevel(cid, skillToTrain) print("Nível da habilidade " .. skillToTrain .. ": " .. skillLevel) if skillLevel < config.minSkill then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não tem a habilidade necessária para treinar aqui.") return true end local rightSlotItem = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) if not rightSlotItem or rightSlotItem.itemid ~= config.requiredItemID then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você precisa estar equipado com o item necessário para treinar aqui.") return true end if skillEvents[cid] then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você já está em treinamento.") return true end skillEvents[cid] = addEvent(function() print("Iniciando evento de treinamento") if not isPlayer(cid) then skillEvents[cid] = nil return end local currentPlayerPosition = getCreaturePosition(cid) if not isInRange(currentPlayerPosition, position, 1) then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não está mais na posição correta para treinar.") stopEvent(skillEvents[cid]) skillEvents[cid] = nil return end if math.random(100) <= config.gainChance then doPlayerAddSkillTry(cid, skillToTrain) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você ganhou experiência em " .. getSkillName(skillToTrain) .. ".") else doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não ganhou experiência em " .. getSkillName(skillToTrain) .. ".") end end, config.trainInterval) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Iniciando treinamento em " .. getSkillName(skillToTrain) .. "...") end return true end function onLogout(cid) if skillEvents[cid] then stopEvent(skillEvents[cid]) skillEvents[cid] = nil end return true end
  5. nao testado! local config = { minSkill = 10, -- Valor mínimo da habilidade para começar a treinar gainChance = 50, -- Chance de ganhar skill, em porcentagem requiredItemID = 1234, -- ID do item necessário para treinar trainInterval = 3000, -- Intervalo de tempo para tentar ganhar skill (em milissegundos) skillsToTrain = { -- Habilidades correspondentes para cada vocação [0] = {1, 2}, -- Vocação sem classe [1] = {1, 2}, -- Knight [2] = {3}, -- Paladin [3] = {4}, -- Sorcerer [4] = {4}, -- Druid [5] = {4}, -- Master Sorcerer [6] = {4} -- Elder Druid } } local skillEvents = {} -- Tabela para armazenar os eventos de treino function isInRange(playerPosition, centerPosition, range) return math.abs(centerPosition.x - playerPosition.x) <= range and math.abs(centerPosition.y - playerPosition.y) <= range and centerPosition.z == playerPosition.z end function onStepIn(cid, item, position, fromPosition) if not isPlayer(cid) then return false end local vocation = getPlayerVocation(cid) if not config.skillsToTrain[vocation] then return false end for _, skillToTrain in ipairs(config.skillsToTrain[vocation]) do local skillLevel = getPlayerSkillLevel(cid, skillToTrain) if skillLevel < config.minSkill then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não tem a habilidade necessária para treinar aqui.") return true end local rightSlotItem = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) if not rightSlotItem or rightSlotItem.itemid ~= config.requiredItemID then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você precisa estar equipado com o item necessário para treinar aqui.") return true end if skillEvents[cid] then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você já está em treinamento.") return true end skillEvents[cid] = addEvent(function() if not isPlayer(cid) then skillEvents[cid] = nil return end local currentPlayerPosition = getCreaturePosition(cid) if not isInRange(currentPlayerPosition, position, 1) then doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não está mais na posição correta para treinar.") stopEvent(skillEvents[cid]) skillEvents[cid] = nil return end if math.random(100) <= config.gainChance then doPlayerAddSkillTry(cid, skillToTrain) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você ganhou experiência em " .. getSkillName(skillToTrain) .. ".") else doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Você não ganhou experiência em " .. getSkillName(skillToTrain) .. ".") end end, config.trainInterval) doPlayerSendTextMessage(cid, MESSAGE_EVENT_DEFAULT, "Iniciando treinamento em " .. getSkillName(skillToTrain) .. "...") end return true end function onLogout(cid) if skillEvents[cid] then stopEvent(skillEvents[cid]) skillEvents[cid] = nil end return true end
  6. O Task System para TFS 0.4 8.6 original foi criado pela Vodkart e adaptado para TFS 1.x por Erro 502. Ele possuía alguns códigos muito ruins e erros de otimização. Então, eu peguei ambos, analisei tudo corretamente e corrigi. Agora está funcionando para todos os TFS; não é mais necessário adicioná-lo ao global.lua, basta colocá-lo diretamente na pasta 'lib' e tudo funcionará bem. Aproveite e teste o Task System. Revscripts. Basta adicioná-lo aos dados/scripts. local taskSystemEvent = CreatureEvent("taskSystem") function taskSystemEvent.onKill(creature, target) if creature:isPlayer() and target:isMonster() then local party = creature:getParty() local members = {} if party then members = party:getMembers() table.insert(members, party:getLeader()) else members = {creature} end for _, member in pairs(members) do local creaturePos = member:getPosition() local killedMobPos = target:getPosition() local tile = Tile(creaturePos) if not tile:hasFlag(TILESTATE_PROTECTIONZONE) and killedMobPos:getDistance(creaturePos) < 25 then local taskSystem = _G.taskSystem local dailyTasks = _G.dailyTasks local task = taskSystem[member:getTaskMission()] local daily = dailyTasks[member:getDailyTaskMission()] if task and isInArray(task.monsters_list, target:getName()) then local currentCount = member:getStorageValue(taskSystem_storages[3]) if currentCount < task.count then member:setStorageValue(taskSystem_storages[3], currentCount + 1) member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Defeated: [" .. (currentCount + 1) .. "/" .. task.count .. "] monsters for the task: " .. task.name .. ".") if currentCount + 1 >= task.count then member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Task System] Congratulations! You completed the task: " .. task.name .. ", return to the NPC to claim your reward.") end end end if daily and isInArray(daily.monsters_list, target:getName()) then if os.time() >= 0 then local dailyCount = member:getStorageValue(taskSystem_storages[5]) if dailyCount < daily.count then member:setStorageValue(taskSystem_storages[5], dailyCount + 1) member:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[Daily Task System] Defeated: [" .. (dailyCount + 1) .. "/" .. daily.count .. "] monsters for the daily task: " .. daily.name .. ".") if dailyCount + 1 >= daily.count then member:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, "[Daily Task System] Congratulations! You completed the daily task: " .. daily.name .. ", return to the NPC to claim your reward.") end end else member:sendCancelMessage("Sorry, but you didn't finish the Daily Task in time! Please return to the NPC to start a new Daily Task.") end end end end end return true end taskSystemEvent:register() local creatureEvent = CreatureEvent("taskLogin") function creatureEvent.onLogin(player) player:registerEvent("taskSystem") return true end creatureEvent:register() local talkAction = TalkAction("!task", "/task") function talkAction.onSay(player, words, param) param = param:lower() local taskSystem = _G.taskSystem if isInArray({"counter", "contador"}, param) then player:setStorageValue(taskSystem_storages[8], player:getStorageValue(taskSystem_storages[8]) <= 0 and 1 or 0) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "[Task System] The counter has been " .. (player:getStorageValue(taskSystem_storages[8]) <= 0 and "activated" or "deactivated") .. ".") return true elseif isInArray({"daily", "diaria"}, param) then local dailyTasks = _G.dailyTasks local daily = player:getDailyTaskMission() if not dailyTasks[daily] or player:getStorageValue(taskSystem_storages[7]) <= 0 then player:sendCancelMessage("Sorry, you are not on any Daily Task.") return true elseif player:getStorageValue(taskSystem_storages[6]) - os.time() <= 0 and player:getStorageValue(taskSystem_storages[5]) < dailyTasks[daily].count then player:showTextDialog("Sorry, but you didn't finish the Daily Task in time! Please return to the NPC to start a new Daily Task.") return true end local taskInfo = "[->] CURRENT DAILY TASK INFO [<-]\n\nName: " .. dailyTasks[daily].name .. "\nProgress: [" .. (player:getStorageValue(taskSystem_storages[5]) < 0 and 0 or player:getStorageValue(taskSystem_storages[5])) .. "/" .. dailyTasks[daily].count .. "]\nDeadline: " .. os.date("%d %B %Y %X", player:getStorageValue(taskSystem_storages[6])) .. "\nMonsters to Hunt: " .. getMonsterFromList(dailyTasks[daily].monsters_list) .. "\n\n[->] CURRENT TASK REWARDS [<-]\n\nMoney: " .. (dailyTasks[daily].money > 0 and dailyTasks[daily].money or 0) .. "\nExperience: " .. (dailyTasks[daily].exp > 0 and dailyTasks[daily].exp or 0) .. "\nTask Points: " .. dailyTasks[daily].points .. "\nItems: " .. (#dailyTasks[daily].reward > 0 and getItemsFromList(dailyTasks[daily].reward) or "No reward items") .. "." return player:showTextDialog(1953, taskInfo) end local task = player:getTaskMission() if not taskSystem[task] or player:getStorageValue(taskSystem[task].start) <= 0 then player:sendCancelMessage("You are not on any task.") return true end local taskInfo = "-> CURRENT TASK [" .. task .. "/" .. #taskSystem .. "] <-\n\nTask Name: " .. taskSystem[task].name .. "\nTask Level: " .. taskSystem[task].level .. "\nTask Progress: [" .. (player:getStorageValue(taskSystem_storages[3]) < 0 and 0 or player:getStorageValue(taskSystem_storages[3])) .. "/" .. taskSystem[task].count .. "]\nMonster To Hunt: " .. getMonsterFromList(taskSystem[task].monsters_list) .. ".\nItems for Delivery: " .. (#taskSystem[task].items > 0 and getItemsFromList(taskSystem[task].items) or "None") .. ".\n\n[->] CURRENT TASK REWARDS [<-]\n\nReward Money: " .. (taskSystem[task].money > 0 and taskSystem[task].money or 0) .. "\nReward Experience: " .. (taskSystem[task].exp > 0 and taskSystem[task].exp or 0) .. "\nReward Points: " .. taskSystem[task].points .. "\nReward Items: " .. (#taskSystem[task].reward > 0 and getItemsFromList(taskSystem[task].reward) or "No reward items") .. "." return player:showTextDialog(1953, taskInfo) end talkAction:separator(" ") talkAction:register() local ec = EventCallback ec.onLook = function(self, thing, position, distance, description) if thing:isPlayer() then local playerRank = thing:getRankTask() or "Private" return ("%s Rank task: [%s]"):format(description, playerRank) end return description end ec:register(66) Após isso, adicione-o ao arquivo data/lib/lib.lua e inclua. -- Task system + Daily Task System dofile('data/lib/Task_system.lua') e lib Task_system.lua taskSystem = { [1] = {name = "Rat", start = 176201, monsters_list = {"Rat"}, level = 1, count = 10, points = 2, items = {}, reward = {{2674, 5}}, exp = 100, money = 10}, [2] = {name = "Cave Rats Spotted!", start = 176201, monsters_list = {"Cave Rat"}, level = 3, count = 5, points = 0, items = {}, reward = {{2580, 1}}, exp = 150, money = 15}, [3] = {name = "Trouble in the Old Forest", start = 176201, monsters_list = {"Rat"}, level = 8, count = 10, points = 5, items = {}, reward = {{2160, 30}}, exp = 250, money = 50}, } dailyTasks = { [1] = {name = "Daily Rat" ,monsters_list = {"Rat"}, count = 10, points = 3, reward = {{2674, 5}}, exp = 100, money = 10}, [2] = {name = "Daily Cave Rat" ,monsters_list = {"Cave Rat"}, count = 50, points = 3, reward = {{2173, 1}}, exp = 130, money = 20}, } -- task, points, count, daily task, daily count, daily time , daily start, contador taskSystem_storages = {176601, 176602, 176603, 176604, 176605, 176606, 176607, 176608} function Player:getTaskMission() return self:getStorageValue(taskSystem_storages[1]) < 0 and 1 or self:getStorageValue(taskSystem_storages[1]) end function Player:getDailyTaskMission() return self:getStorageValue(taskSystem_storages[4]) < 0 and 1 or self:getStorageValue(taskSystem_storages[4]) end function Player:getTaskPoints() return self:getStorageValue(taskSystem_storages[2]) < 0 and 0 or self:getStorageValue(taskSystem_storages[2]) end function Player:randomDailyTask() local t = { [{6, 49}] = {1, 3}, [{50, 79}] = {1, 3}, [{80, 129}] = {1, 3}, [{130, math.huge}] = {1, 3} } for a, b in pairs(t) do if self:getLevel() >= a[1] and self:getLevel() <= a[2] then return math.random(b[1], b[2]) end end return 0 end function Player:getRankTask() local ranks = { [{1, 20}] = "Huntsman", [{21, 50}] = "Ranger", [{51, 100}] = "Big Game Hunter", [{101, 200}] = "Trophy Hunter", [{201, math.huge}] = "Elite Hunter" } local defaultRank = "Private" for v, r in pairs(ranks) do if self:getTaskPoints() >= v[1] and self:getTaskPoints() <= v[2] then return r end end return defaultRank end function getItemsFromList(items) local str = '' if #items > 0 then for i = 1, #items do local itemID = items[i][1] local itemName = ItemType(itemID):getName() if itemName then str = str .. items[i][2] .. ' ' .. itemName else str = str .. items[i][2] .. ' ' .. "Item ID: " .. itemID end if i ~= #items then str = str .. ', ' end end end return str end function Player:doRemoveItemsFromList(items) local count = 0 if #items > 0 then for i = 1, #items do if self:getItemCount(items[i][1]) >= items[i][2] then count = count + 1 end end end if count == #items then for i = 1, #items do self:removeItem(items[i][1], items[i][2]) end else return false end return true end function getMonsterFromList(monster) local str = '' if #monster > 0 then for i = 1, #monster do str = str .. monster[i] if i ~= #monster then str = str .. ', ' end end end return str end function Player:giveRewardsTask(items) local backpack = self:addItem(1999, 1) for _, i_i in ipairs(items) do local item, amount = i_i[1], i_i[2] if ItemType(item):isStackable() or amount == 1 then backpack:addItem(item, amount) else for i = 1, amount do backpack:addItem(item, 1) end end end end O último é o NPC... basta adicionar o seu NPC no arquivo dados\npc\scripts\taskdaily.lua. local keywordHandler = KeywordHandler:new() local npcHandler = NpcHandler:new(keywordHandler) NpcSystem.parseParameters(npcHandler) local talkState = {} function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end function onThink() npcHandler:onThink() end function creatureSayCallback(cid, type, msg) if not npcHandler:isFocused(cid) then return false end local player = Player(cid) local talkUser, msg, str, rst = NPCHANDLER_CONVbehavior == CONVERSATION_DEFAULT and 0 or cid, msg:lower(), "", "" local task, daily, hours = player:getTaskMission(), player:getDailyTaskMission(), 24 if isInArray({"task", "tasks", "missao", "mission"}, msg) then if taskSystem[task] then if player:getStorageValue(taskSystem[task].start) <= 0 then if player:getLevel() >= taskSystem[task].level then player:setStorageValue(taskSystem[task].start, 1) npcHandler:say("[Task System] Congratulations, you are now participating in the Task of "..taskSystem[task].name.." and shall kill "..taskSystem[task].count.." from this list: "..getMonsterFromList(taskSystem[task].monsters_list)..". "..(#taskSystem[task].items > 0 and "Oh and please bring me "..getItemsFromList(taskSystem[task].items).." for me." or "").."" , cid) else npcHandler:say("Sorry, but you need to reach level "..taskSystem[task].level.." to be able to participate in the Task of "..taskSystem[task].name.."!", cid) end else npcHandler:say("Sorry, but you are currently on the task "..taskSystem[task].name..". You may {reward} if it's already over.", cid) end else npcHandler:say("Sorry, but for now I don't have any more tasks for you!", cid) end elseif isInArray({"diaria", "daily", "dayli", "diario"}, msg) then if player:getStorageValue(taskSystem_storages[6]) - os.time() > 0 then npcHandler:say("Sorry, you must wait until "..os.date("%d %B %Y %X ", player:getStorageValue(taskSystem_storages[6])).." to start a new daily task!", cid) return true elseif dailyTasks[daily] and player:getStorageValue(taskSystem_storages[5]) >= dailyTasks[daily].count then npcHandler:say("Sorry, do you have task for {reward}!", cid) return true end local r = player:randomDailyTask() if r == 0 then npcHandler:say("Sorry, but you don't have the level to complete any daily tasks.", cid) return true end player:setStorageValue(taskSystem_storages[4], r) player:setStorageValue(taskSystem_storages[6], os.time() + hours * 3600) player:setStorageValue(taskSystem_storages[7], 1) player:setStorageValue(taskSystem_storages[5], 0) local dtask = dailyTasks[r] npcHandler:say("[Daily Task System] Congratulations, you are now participating in the Daily Task of "..dtask.name.." and shall kill "..dtask.count.." monsters from this list: "..getMonsterFromList(dtask.monsters_list).." up until "..os.date("%d %B %Y %X ", player:getStorageValue(taskSystem_storages[6]))..". Good luck!" , cid) elseif isInArray({"receber", "reward", "recompensa", "report", "reportar", "entregar", "entrega"}, msg) then local v, k = taskSystem[task], dailyTasks[daily] if v then -- Original Task if player:getStorageValue(v.start) > 0 then if player:getStorageValue(taskSystem_storages[3]) >= v.count then if #v.items > 0 and not doRemoveItemsFromList(cid, v.items) then npcHandler:say("Sorry, but you also need to deliver the items on this list: "..getItemsFromList(v.items), cid) return true end if v.exp > 0 then player:addExperience(v.exp) str = str.." "..v.exp.." experience" end if v.points > 0 then player:setStorageValue(taskSystem_storages[2], (player:getTaskPoints() + v.points)) str = str.." + "..v.points.." task points" end if v.money > 0 then player:addMoney(v.money) str = str.." "..v.money.." gold coins" end if table.maxn(v.reward) > 0 then player:giveRewardsTask(v.reward) str = str.." "..getItemsFromList(v.reward) end npcHandler:say("Thank you for your help! Rewards: "..(str == "" and "none" or str).." for completing the task of "..v.name, cid) player:setStorageValue(taskSystem_storages[3], 0) player:setStorageValue(taskSystem_storages[1], (task + 1)) else npcHandler:say("Sorry, but you haven't finished your task "..v.name.." yet. I need you to kill more "..(player:getStorageValue(taskSystem_storages[3]) < 0 and v.count or -(player:getStorageValue(taskSystem_storages[3]) - v.count)).." of these terrible monsters!", cid) end else npcHandler:say("I'm sorry, but you have already completed a daily task today, and therefore, you cannot undertake another one. Please return tomorrow, and we can discuss it further. If you're interested, I can offer you another regular task. Simply say 'task' to express your interest.", cid) end end if k then -- Daily Task if player:getStorageValue(taskSystem_storages[7]) > 0 then if player:getStorageValue(taskSystem_storages[5]) >= k.count then if k.exp > 0 then player:addExperience(k.exp) rst = rst.." "..k.exp.." experience" end if k.points > 0 then player:setStorageValue(taskSystem_storages[2], (player:getTaskPoints() + k.points)) rst = rst.." + "..k.points.." task points" end if k.money > 0 then player:addMoney(k.money) rst = rst.." "..k.money.." gold coins" end if table.maxn(k.reward) > 0 then player:giveRewardsTask(k.reward) rst = rst.." "..getItemsFromList(k.reward) end npcHandler:say("Thank you for your help! Rewards: "..(rst == "" and "none" or rst).." for completing the daily task of "..k.name, cid) player:setStorageValue(taskSystem_storages[4], 0) player:setStorageValue(taskSystem_storages[5], 0) player:setStorageValue(taskSystem_storages[7], 0) else npcHandler:say("Sorry, but you haven't finished your daily task "..k.name.." yet. I need you to kill more "..(player:getStorageValue(taskSystem_storages[5]) < 0 and k.count or -(player:getStorageValue(taskSystem_storages[5]) - k.count)).." of these monsters!", cid) end end end elseif msg == "no" then npcHandler:say("Alright then.", cid) talkState[talkUser] = 0 npcHandler:releaseFocus(cid) end return true end npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new()) Em relação ao XML do NPC... você já sabe como fazer, basta adicionar o nome quando quiser e testar, é simples
  7. Você fez o script para TFS 1.x, mas o rapaz pediu especificamente para TFS 0.4. Revise isso.
  8. Revscriptsys é uma nova forma alternativa de registrar scripts para que você não precise fazer isso via XML. Você só precisa colocar seus scripts lua dentro data/scripts/ou em qualquer subpasta dele, se desejar. Os scripts Monster são, no entanto, colocados em um caminho diferente: data/monster/(ou em qualquer subpasta dele, como antes). Este sistema suporta a utilização de diferentes metatabelas no mesmo script (Actions, MoveEvents, GlobalEvents...). Fica na pasta 'data/scripts" Creio que o OtservBR não suporta o 'EventCallback', porque simplesmente colocar na pasta 'data/scripts' já funciona na hora, hahaha. #Edited O problema foi resolvido via Discord. Para quem quer resets o look por DB, aqui está um exemplo. if thing:isCreature() and thing:isPlayer() then local playerGuid = thing:getGuid() local query = db.storeQuery("SELECT `resets` FROM `players` WHERE `id` = " .. playerGuid) if query then local playerResets = result.getDataString(query, "resets") description = string.format("%s\n[ Resets: %s ]", description, playerResets) result.free(query) else print(string.format("[Player ID: %s] Falha na consulta ao banco de dados", playerGuid)) end end Depende da sintaxe Lua e do seu arquivo player.lua. Pegue e veja se está correto, ajuste e teste. Boa sorte!
  9. Seu servidor possui revscripts e EventCallback?
  10. Ok, volte ao script original e substitua com calma... Acho que vai dar certo. function Player:onLook(thing, position, distance) local description = 'You see ' if thing:isPlayer() then local playerGuid = thing:getGuid() local query = db.storeQuery("SELECT `resets` FROM `players` WHERE `id` = " .. playerGuid) if query then local playerDescription = result.getDataString(query, "resets") description = string.format("%s\n[ Resets: %s ]", description, playerDescription) print(string.format("[Player ID: %s] Resets: %s", playerGuid, playerDescription)) else print(string.format("[Player ID: %s] Falha na consulta ao banco de dados", playerGuid)) end elseif thing:isItem() then if thing.actionid == 5640 then description = description .. 'a honeyflower patch.' elseif thing.actionid == 5641 then description = description .. 'a banana palm.' else description = description .. thing:getDescription(distance) end local itemType = thing:getType() if itemType and itemType:getImbuingSlots() > 0 then local imbuingSlots = "Imbuements: (" for i = 1, itemType:getImbuingSlots() do local specialAttr = thing:getSpecialAttribute(i) local time = 0 if thing:getSpecialAttribute(i + 3) then time = getTime(thing:getSpecialAttribute(i + 3)) end if specialAttr then imbuingSlots = imbuingSlots .. specialAttr .. " " .. time if i ~= itemType:getImbuingSlots() then imbuingSlots = imbuingSlots .. ", " else imbuingSlots = imbuingSlots .. ")." end else imbuingSlots = imbuingSlots .. "Empty Slot" if i ~= itemType:getImbuingSlots() then imbuingSlots = imbuingSlots .. ", " else imbuingSlots = imbuingSlots .. ")." end end end description = string.gsub(description, "It weighs", imbuingSlots .. "\nIt weighs") end else description = description .. thing:getDescription(distance) end
  11. Lol... antes, ele mostrava o level certo?
  12. Ok, fácil então... Procure essa linha function Player:onLook(thing, position, distance) É só prosseguir com cuidado, ok? function Player:onLook(thing, position, distance) local description = 'You see ' if thing:isItem() then if thing.actionid == 5640 then description = description .. 'a honeyflower patch.' elseif thing.actionid == 5641 then description = description .. 'a banana palm.' else description = description .. thing:getDescription(distance) end local itemType = thing:getType() if (itemType and itemType:getImbuingSlots() > 0) then local imbuingSlots = "Imbuements: (" for i = 1, itemType:getImbuingSlots() do local specialAttr = thing:getSpecialAttribute(i) local time = 0 if (thing:getSpecialAttribute(i+3)) then time = getTime(thing:getSpecialAttribute(i+3)) end if (specialAttr) then if (i ~= itemType:getImbuingSlots()) then imbuingSlots = imbuingSlots.. "" ..specialAttr.." " ..time..", " else imbuingSlots = imbuingSlots.. "" ..specialAttr.." " ..time..")." end else if (i ~= itemType:getImbuingSlots()) then imbuingSlots = imbuingSlots.. "Empty Slot, " else imbuingSlots = imbuingSlots.. "Empty Slot)." end end end description = string.gsub(description, "It weighs", imbuingSlots.. "\nIt weighs") end --[[-- KD look if thing:isCreature() and thing:isPlayer() then description = string.format("%s\n [PVP Kills: %d] \n [PVP Deaths: %d] \n", description, math.max(0, thing:getStorageValue(167912)), math.max(0, thing:getStorageValue(167913))) end end--]] --[[-- MARRY if LOOK_MARRIAGE_DESCR and thing:isCreature() then if thing:isPlayer() then description = description .. self:getMarriageDescription(thing) end end--]] elseif thing:isPlayer() then local playerGuid = thing:getGuid() local query = db.storeQuery("SELECT `resets` FROM `players` WHERE `id` = " .. playerGuid) if query then local playerDescription = result.getDataString(query, "resets") description = string.format("%s\n[ Resets: %s ]", description, playerDescription) print(string.format("[Player ID: %s] Resets: %s", playerGuid, playerDescription)) else print(string.format("[Player ID: %s] Falha na consulta ao banco de dados", playerGuid)) end else description = description .. thing:getDescription(distance) end -- KD look if thing:isCreature() and thing:isPlayer() then description = string.format("%s\n [PVP Kills: %d] \n [PVP Deaths: %d] \n", description, math.max(0, thing:getStorageValue(167912)), math.max(0, thing:getStorageValue(167913))) end -- MARRY if LOOK_MARRIAGE_DESCR and thing:isCreature() then if thing:isPlayer() then description = description .. self:getMarriageDescription(thing) end end if self:getGroup():getAccess() then if thing:isItem() then description = string.format('%s\nItem ID: %d', description, thing.itemid) local actionId = thing.actionid if actionId ~= 0 then description = string.format('%s, Action ID: %d', description, actionId) end local uniqueId = thing:getAttribute(ITEM_ATTRIBUTE_UNIQUEID) if uniqueId > 0 and uniqueId < 65536 then description = string.format('%s, Unique ID: %d', description, uniqueId) end description = description .. '.' local itemType = thing:getType() local transformEquipId = itemType:getTransformEquipId() local transformDeEquipId = itemType:getTransformDeEquipId() if transformEquipId ~= 0 then description = string.format('%s\nTransforms to: %d (onEquip)', description, transformEquipId) elseif transformDeEquipId ~= 0 then description = string.format('%s\nTransforms to: %d (onDeEquip)', description, transformDeEquipId) end local decayId = itemType:getDecayId() if decayId ~= -1 then description = string.format('%s\nDecays to: %d', description, decayId) end elseif thing:isCreature() then local title = getTitle(thing.uid) if title then description = description .. title .. " of Relembra." end local str = '%s\nHealth: %d / %d' if thing:getMaxMana() > 0 then str = string.format('%s, Mana: %d / %d', str, thing:getMana(), thing:getMaxMana()) end description = string.format(str, description, thing:getHealth(), thing:getMaxHealth()) .. '.' end local position = thing:getPosition() description = string.format( '%s\nPosition: %d, %d, %d', description, position.x, position.y, position.z ) if thing:isCreature() and thing:isPlayer() then description = string.format('%s\nIP: %s.', description, Game.convertIpToString(thing:getIp())) end end self:sendTextMessage(MESSAGE_INFO_DESCR, description) end
  13. Como funciona o sistema de reset do seu servidor? É feito por NPC? Se sim, poderia postar o script dele? Talvez esse NPC tenha um storage, facilitando a implementação do reset look.
  14. Chama no Discord que eu envio o arquivo. 82mateusroberto
  15. @doukxxt Você precisa abrir o arquivo do OTC com o Visual Studio Code para editar, não com o notepadd ou o editor de texto padrão do Windows. O Visual Studio Code ou o Sublime Text são ideais, sem erros
  16. Mateus Robeerto postou uma resposta no tópico em Suporte Tibia OTServer
    Você adicionou corretamente? Desculpe, houve outro arquivo. Esqueci de postar. Então, vá em htdocs/classes/highscores.php e procure por essa linha. const SKILL__LEVEL = 8; é so adicione baixo. const SKILL__RESET = 9;
  17. Mateus Robeerto postou uma resposta no tópico em Suporte Tibia OTServer
    Ótimo, basta substituir todo o seu highscore.php <?php if (!defined('INITIALIZED')) exit; $list = 'experience'; if (isset($_REQUEST['list'])) $list = $_REQUEST['list']; $page = 0; if (isset($_REQUEST['page'])) $page = min(50, $_REQUEST['page']); $vocation = ''; if (isset($_REQUEST['vocation'])) $vocation = $_REQUEST['vocation']; switch ($list) { case "fist": $id = Highscores::SKILL_FIST; $list_name = 'Fist Fighting'; break; case "club": $id = Highscores::SKILL_CLUB; $list_name = 'Club Fighting'; break; case "sword": $id = Highscores::SKILL_SWORD; $list_name = 'Sword Fighting'; break; case "axe": $id = Highscores::SKILL_AXE; $list_name = 'Axe Fighting'; break; case "distance": $id = Highscores::SKILL_DISTANCE; $list_name = 'Distance Fighting'; break; case "shield": $id = Highscores::SKILL_SHIELD; $list_name = 'Shielding'; break; case "fishing": $id = Highscores::SKILL_FISHING; $list_name = 'Fishing'; break; case "magic": $id = Highscores::SKILL__MAGLEVEL; $list_name = 'Magic'; break; case "reset": $id = Highscores::SKILL__RESET; $list_name = 'Resets'; break; default: $id = Highscores::SKILL__LEVEL; $list_name = 'Experience'; break; } $world_name = $config['server']['serverName']; $offset = $page * 100; $skills = new Highscores($id, 100, $page, $vocation); // Iniciar a construção do conteúdo principal $main_content .= '<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%><TR><TD><IMG SRC="'.$layout_name.'/images/blank.gif" WIDTH=10 HEIGHT=1 BORDER=0></TD><TD><CENTER><H2>Ranking for '.htmlspecialchars($list_name).' on '.htmlspecialchars($world_name).'</H2></CENTER><BR>'; $main_content .= '<br><table border="0" cellpadding="4" cellspacing="1" width="100%"> <tr bgcolor="'.$config['site']['vdarkborder'].'"> <td class="whites"><b>Rank</b></td> <td width="75%" class="whites"><b>Name</b></td> <td width="10%" class="whites"><b><center>Level</center></b></td>'; if ($list == "experience") { $main_content .= '<td width="10%" class="whites"><b><center>Experience</center></b></td> <td width="10%" class="whites"><b><center>Resets</center></b></td>'; } $main_content .= '</tr>'; $number_of_rows = 0; foreach ($skills as $skill) { $value = $list == "magic" ? $skill->getMagLevel() : ($list == "experience" ? $skill->getLevel() : $skill->getScore()); $bgcolor = (($number_of_rows++ % 2 == 1) ? $config['site']['darkborder'] : $config['site']['lightborder']); $main_content .= '<tr bgcolor="'.$bgcolor.'"> <td style="text-align:right">'.($offset + $number_of_rows).'. </td> <td><a href="?subtopic=characters&name='.urlencode($skill->getName()).'">'.($skill->getOnline() > 0 ? "<font color=\"green\">".htmlspecialchars($skill->getName())."</font>" : "<font color=\"red\">".htmlspecialchars($skill->getName())."</font>").'</a><br><small>'.$skill->getLevel().' '.htmlspecialchars(Website::getVocationName($skill->getVocation())).'</small></td> <td><center>'.$value.'</center></td>'; if ($list == "experience") { $main_content .= '<td><center>'.$skill->getExperience().'</center></td>'; $main_content .= '<td><center>'.$skill->getResets().'</center></td>'; } $main_content .= '</tr>'; } $main_content .= '</table>'; $main_content .= '<table border="0" cellpadding="4" cellspacing="1" width="100%"> <tr bgcolor="'.$config['site']['vdarkborder'].'"> <td class="whites" colspan="2"><center><b>Choose a skill</b></center></td> </tr> <tr bgcolor="'.$config['site']['lightborder'].'"> <td style="text-align: center;"> <a href="?subtopic=highscores&list=experience" class="size_xs">Experience</a><br> <a href="?subtopic=highscores&list=magic" class="size_xs">Magic</a><br> <a href="?subtopic=highscores&list=shield" class="size_xs">Shielding</a><br> <a href="?subtopic=highscores&list=distance" class="size_xs">Distance</a><br> <a href="?subtopic=highscores&list=club" class="size_xs">Club</a><br> <a href="?subtopic=highscores&list=sword" class="size_xs">Sword</a><br> <a href="?subtopic=highscores&list=axe" class="size_xs">Axe</a><br> <a href="?subtopic=highscores&list=fist" class="size_xs">Fist</a><br> <a href="?subtopic=highscores&list=fishing" class="size_xs">Fishing</a><br> <a href="?subtopic=highscores&list=reset" class="size_xs">Resets</a><br> </td> </tr> </table>'; E depois vá em htdocs/classes/player.php e procure por essa linha. public function loadStorages() { $this->storages = array(); // load all $storages = $this->getDatabaseHandler()->query('SELECT ' . $this->getDatabaseHandler()->fieldName('player_id') . ', ' . $this->getDatabaseHandler()->fieldName('key') . ', ' . $this->getDatabaseHandler()->fieldName('value') . ' FROM ' .$this->getDatabaseHandler()->tableName('player_storage') . ' WHERE ' . $this->getDatabaseHandler()->fieldName('player_id') . ' = ' . $this->getDatabaseHandler()->quote($this->data['id']))->fetchAll(); foreach($storages as $storage) { $this->storages[$storage['key']] = $storage['value']; } } É só adicionar abaixo e salvar. Pronto, o seu ranking com resets está pronto. public function getResets() { $result = $this->getDatabaseHandler()->query('SELECT resets FROM ' . $this->getDatabaseHandler()->tableName('players') . ' WHERE id = ' . $this->getDatabaseHandler()->quote($this->data['id']))->fetch(); if ($result) { return (int)$result['resets']; } else { $this->getDatabaseHandler()->execute('INSERT INTO ' . $this->getDatabaseHandler()->tableName('players') . ' (id, resets) VALUES (' . $this->getDatabaseHandler()->quote($this->data['id']) . ', 0)' . ' ON DUPLICATE KEY UPDATE resets = 0'); return 0; } } Depois, não se esqueça de dar REP e marcar como solução
  18. Mateus Robeerto postou uma resposta no tópico em Mapas de Tibia
    Tenho certeza de que vou usar esta cidade no meu projeto. Ficou ótimo. Já tenho uma boa ideia para a cidade e acesso ao HUNTS, algo diferente, hahaha. Muito obrigado!
  19. Mateus Robeerto postou uma resposta no tópico em Suporte Tibia OTServer
    Como fica a sua database? resets? description? reset? Você não utiliza storage?
  20. local config = { itemids = { [1] = 26383, -- cabeça [4] = 26384, -- armor [5] = 26387, -- direita [6] = 26388, -- esquerda [7] = 26385, -- legs [8] = 26386 -- boots }, storage = 26427, -- Storage para verificar se o jogador já usou outfit = 907, -- Outfit a ser aplicado newVocation = 10, -- ID da nova vocação ao usar bagItemId = 1987, -- ID do container para devolver os itens defaultVocation = 1 -- ID da vocação original para reverter } function onUse(cid, item, frompos, item2, topos) if getPlayerStorageValue(cid, config.storage) ~= 1 then local bag = doPlayerAddItem(cid, config.bagItemId, 1) if not bag then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Não foi possível criar o saco de itens.") return false end for slot, itemId in pairs(config.itemids) do local playerItem = getPlayerSlotItem(cid, slot) if playerItem.itemid > 0 then if doAddContainerItem(bag, playerItem.itemid, playerItem.type or 1) ~= RETURNVALUE_NOERROR then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Não foi possível adicionar itens ao saco.") else doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Seus itens foram devolvidos para o saco de itens.") end doRemoveItem(playerItem.uid) end end doSetCreatureOutfit(cid, {lookType = config.outfit}, -1) doPlayerSetVocation(cid, config.newVocation) setPlayerStorageValue(cid, config.storage, 1) else for slot, itemId in pairs(config.itemids) do local playerItem = getPlayerSlotItem(cid, slot) if playerItem.itemid == itemId then doRemoveItem(playerItem.uid) end end doRemoveCondition(cid, CONDITION_OUTFIT) doPlayerSetVocation(cid, config.defaultVocation) setPlayerStorageValue(cid, config.storage, 0) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Sua outfit e vocação foram revertidas para o original.") end return true end
  21. god/god Baixe o novo arquivo SQL aqui. Troquei minha senha pessoal para 'god/god' agora. Por favor, importe este novo arquivo SQL, ok? Thunder.sql
  22. local POLL_STORAGE = 80000 local OPTIONS_STORAGE = 80001 local PLAYER_STORAGE = 80000 local function unserialize(s) local func = loadstring("return " .. s) if func then return func() else return nil, "unserialize error: string could not be deserialized." end end local function getTotalVotes() local options, err = unserialize(getStorage(OPTIONS_STORAGE)) if not options then error(err) end local amount = 0 for _, option in ipairs(options) do amount = amount + option[2] end return amount end local function getMostVotedOption() local options, err = unserialize(getStorage(OPTIONS_STORAGE)) if not options then error(err) end local value, ret = 0 for _, option in ipairs(options) do if option[2] > value then value = option[2] ret = option[1] end end return ret end function onSay(cid, words, param, channel) param = param or "" if param == "" and not words == "/poll" then return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "The command ".. words .." need parameters.") end local parameters, vote = {} if(words == "/newpoll") then if getStorage(POLL_STORAGE) ~= -1 then return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Sorry, but there is a poll in progress.\nIf you want to start a new poll, type /endpoll.") end parameters = string.explode(param, ",") if #parameters < 3 then return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "The command /newpoll needs a poll and at least two options.") end if parameters[1] then local options = {} for i = 2, #parameters do table.insert(options, {parameters[i], 0}) end if #options < 2 then return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Insert at least two options after the poll") end doSetStorage(POLL_STORAGE, parameters[1]) options = table.serialize(options) doSetStorage(OPTIONS_STORAGE, options) doBroadcastMessage("A new poll is in progress with the title '".. getStorage(POLL_STORAGE) .."?'!\nSee the status with /poll and vote with /vote.") end elseif(words == "/vote") then vote = tonumber(param) or -1 local options, err = unserialize(getStorage(OPTIONS_STORAGE)) if not options then error(err) end if getStorage(POLL_STORAGE) == -1 then return doPlayerSendCancel(cid, "There is not a poll in progress.") end if vote == -1 then return doPlayerSendCancel(cid, "You need to choose a option to vote.") end if getCreatureStorage(cid, PLAYER_STORAGE) == 1 then return doPlayerSendCancel(cid, "You cannot vote two times.") end if vote > #options then return doPlayerSendDefaultCancel(cid, RETURNVALUE_NOTPOSSIBLE) end options[vote][2] = options[vote][2] + 1 doSetStorage(OPTIONS_STORAGE, table.serialize(options)) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You have voted in the option ".. options[vote][1] .." successfully!") doCreatureSetStorage(cid, PLAYER_STORAGE, 1) elseif(words == "/poll") then local options, err = unserialize(getStorage(OPTIONS_STORAGE)) if not options then error(err) end if getStorage(POLL_STORAGE) == -1 then return doPlayerSendCancel(cid, "There is not a poll in progress.") end local text = "ADVANCED poll SYSTEM\n\n".. getStorage(POLL_STORAGE) .."?\n" local count = 1 for _, option in ipairs(options) do text = text .."\n#".. count .." ".. option[1] .." ".. (getTotalVotes() == 0 and 0 or math.floor((option[2]/getTotalVotes()) * 100)) .."%\n" count = count + 1 end doPlayerPopupFYI(cid, text) elseif(words == "/endpoll") then if getStorage(POLL_STORAGE) == -1 then return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "There is not a poll to be ended.") end if not getMostVotedOption() then return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Wait at least one vote to end this poll.") end doBroadcastMessage("The poll '".. getStorage(POLL_STORAGE) .."?' has been finished!\nThe most voted option was ".. getMostVotedOption() ..".") doSetStorage(POLL_STORAGE, -1) doSetStorage(OPTIONS_STORAGE, -1) for _, player in ipairs(getPlayersOnline()) do doCreatureSetStorage(player, PLAYER_STORAGE, -1) end db.executeQuery("UPDATE `player_storage` SET value = -1 WHERE `key` = ".. PLAYER_STORAGE ..";") end return true end
  23. Tente executar o SQL no seu banco de dados. Se não funcionar, você terá que importar outro banco de dados. NUNCA DELETE ESSES TIPOS DE SAMPLE E ADMINISTRADOR DO GESIOR, apenas altere a senha e a conta. Pronto. INSERT INTO `players` (`id`, `name`, `world_id`, `group_id`, `account_id`, `level`, `vocation`, `health`, `healthmax`, `experience`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons`, `maglevel`, `mana`, `manamax`, `manaspent`, `soul`, `town_id`, `posx`, `posy`, `posz`, `conditions`, `cap`, `sex`, `lastlogin`, `lastip`, `save`, `skull`, `skulltime`, `rank_id`, `guildnick`, `lastlogout`, `blessings`, `balance`, `stamina`, `direction`, `loss_experience`, `loss_mana`, `loss_skills`, `loss_containers`, `loss_items`, `premend`, `online`, `marriage`, `promotion`, `deleted`, `description`, `comment`, `create_ip`, `create_date`, `hide_char`) VALUES (1, 'Account Manager', 0, 1, 1, 1, 0, 150, 150, 0, 0, 0, 0, 0, 110, 0, 0, 0, 0, 0, 0, 0, 50, 50, 7, '', 400, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 201660000, 0, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, '', '', 0, 0, 0), (2, 'Rook Sample', 0, 1, 1, 1, 0, 150, 150, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 50, 50, 7, '', 400, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 201660000, 0, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, '', '', 0, 0, 0), (3, 'Sorcerer Sample', 0, 1, 1, 1, 1, 150, 150, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 50, 50, 7, '', 400, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 201660000, 0, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, '', '', 0, 0, 0), (4, 'Druid Sample', 0, 1, 1, 1, 2, 150, 150, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 50, 50, 7, '', 400, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 201660000, 0, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, '', '', 0, 0, 0), (5, 'Paladin Sample', 0, 1, 1, 1, 3, 150, 150, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 50, 50, 7, '', 400, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 201660000, 0, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, '', '', 0, 0, 0), (6, 'Knight Sample', 0, 1, 1, 1, 4, 150, 150, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 50, 50, 7, '', 400, 0, 0, 0, 0, 0, 0, 0, '', 0, 0, 0, 201660000, 0, 100, 100, 100, 100, 100, 0, 0, 0, 0, 0, '', '', 0, 0, 0);

Informação Importante

Confirmação de Termo