Ir para conteúdo

Yan Oliveira

Moderador
  • Total de itens

    2187
  • Registro em

  • Última visita

  • Dias Ganhos

    57

Histórico de Reputação

  1. Upvote
    Yan Oliveira recebeu reputação de wevertonvrb em erro na potion   
    Eu refiz o seu código, pois a estrutura dele não estava legal. Não fazia sentido você setar a storage com tempo do os.time() sem nenhum acréscimo além dele, pois seria a mesma coisa que nada. E também não é bom fazer uma função dentro do onUse, é sempre bom fazer fora, como boas práticas.
     
    Substitua seu código por:
    ---------------------------- FUNÇÃO DE HEALAR ----------------------------- local function doRegeneration(cid, health, effect, count) if count > 0 then doCreatureAddHealth(cid, math.floor(health)) doSendMagicEffect(getCreaturePosition(cid), effect) addEvent(doRegeneration, 1000, cid, health, effect, count - 1) end end --------------------------------------------------------------------------- local storage = 11148 -- STORAGE PARA ARMAZENAR UM TEMPO DE COOLDOWN PARA USAR A POTION NOVAMENTE ------------------------------ CÓDIGO -------------------------------------- function onUse(cid, item, fromPos, itemEx, toPos) local tempo = 30 -- TEMPO EM SEGUNDOS QUE A POTION VAI HEALAR (ESSE MESMO TEMPO É ADICIONADO A STORAGE PARA FAZER UM EXHAUST E O PLAYER NÃO USAR MAIS DE UMA POTION DE UMA VEZ) local health = 15 -- TANTO DE VIDA QUE O PLAYER VAI RECUPERAR local effect = CONST_ME_MAGIC_GREEN -- EFEITO QUE VAI SAIR NO PLAYER QUANDO USAR A POTION if getCreatureHealth(cid) == getCreatureMaxHealth(cid) then -- VERIFICA SE O PLAYER JÁ ESTÁ COM A VIDA TOTALMENTE CHEIA return doPlayerSendCancel(cid, "Your health already is full.") end if not isPlayer(cid) then -- VERIFICA SE O PLAYER ESTÁ USANDO A POTION EM OUTRA CRIATURA doPlayerSendCancel(cid, "You only can use the potion in you.") return false end -- CONDIÇÃO PARA VER SE A POTION AINDA ESTÁ SENDO USADA NO PLAYER, PARA NÃO USAR MAIS DE UMA CORRENDO RISCO DE GASTAR POTION ATOA -- if getPlayerStorageValue(cid, storage) <= os.time() then doRegeneration(cid, health, effect, tempo) doChangeTypeItem(item.uid, item.type - 1) setPlayerStorageValue(cid, storage, os.time() + tempo) return true else doPlayerSendCancel(cid, "You are still being recovering.") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You are still being recovering.") return true end end Deixei tudo comentado para você entender, e também adicionei algumas verificações, como se o player já estiver com a vida totalmente cheia e se ele está tentando usar a potion em outra criatura. Também fiz para setar a storage com o tempo (definido na storage tempo) para setar mais o tempo do os.time() (momento que o player usa a potion), é bom isso porque não corre risco do player usar a potion duas vezes ou mais seguidas sem querer e também não gastar potion atoa, caso a primeira já encha a vida totalmente.
     
    Também mudei o tempo do addEvent para 1 segundo, pois estava 2 segundos e meio.
     
    Testa e me fala se der algum erro.
  2. Upvote
    Yan Oliveira recebeu reputação de BrunooMaciell em (Pedido) Funçao Premium   
    local pos = {x=1411, y=1287, z=5} local need_lv = 300 function onUse(cid, item, frompos, item2, topos) if isPremium(cid) then if getPlayerLevel(cid) >= need_lv then doTeleportThing(cid, pos) doSendMagicEffect(pos, CONST_ME_TELEPORT) return true else return doPlayerSendCancel(cid, "Você precisa ser level "..need_lv.." para passar por esta porta.") end else doPlayerSendCancel(cid, "Você precisa ser level "..need_lv.." para passar por esta porta.") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Você precisa ser premium account para passar por esta porta.") doTeleportThing(cid, frompos) return true end end  
  3. Upvote
    Yan Oliveira recebeu reputação de LeoPetryScript em {AJUDA} Adicionar pontos por storage a todos player na area x   
    Não está correto seu script e essa linha não faz sentido
    local tp = name[getCreatureName(cid)]  
    Vamos lá! Substitua seu código por esse:
    local monster_name = "Ferumbras" -- NOME DO MONSTRO (TEM QUE SER IGUAL O NOME QUE ESTÁ NO ARQUIVO XML) local storage = 29111 -- STORAGE local storage_points_increment = 15 -- VALOR QUE SERÁ INCREMENTADO NA STORAGE (PONTOS) -- COORDENADAS DA ÁREA -- local position_area = { start_position = {x= 1092, y= 1073, z= 6}, end_position = {x= 1093, y= 1075, z= 6} } local message = true -- SE FOR EXIBIR MENSAGEM PARA OS PLAYERS QUE GANHAREM PONTOS SE ESTIVER DENTRO DA ÁREA DEIXE TRUE, CASO NÃO QUEIRA, MUDE PARA FALSE ------------------------------------------------- CÓDIGO ------------------------------------------------- function onDeath(cid) local check_position = {} for i = position_area.start_position.x, position_area.end_position.x do for j = position_area.start_position.y, position_area.end_position.y do for k = position_area.start_position.z, position_area.end_position.z do check_position[#check_position + 1] = {x= i, y= j, z= k, stackpos = 253} end end end if (isMonster(cid)) and (getCreatureName(cid) == monster_name) then for i = 1, #check_position do local player = getTileThingByPos(check_position[i]) if isInArea(check_position[i], position_area.start_position, position_area.end_position) then if isPlayer(player.uid) then setPlayerStorageValue(player.uid, storage, storage + storage_points_increment) doSendAnimatedText(getThingPos(player.uid), storage_points_increment.. " points", math.random(1, 255), player.uid) if message then doPlayerSendTextMessage(player.uid, MESSAGE_STATUS_CONSOLE_BLUE, "You gained " ..storage_points_increment.. " points for killing " ..monster_name.. ".") end return true end end end else return true end end Lembrando que o nome do monstro na variável monster_name tem que ser igual a nomenclatura do monstro no arquivo xml, se não vai dar erro. E deixei para exibir mensagem para o player, caso não queira, mude a variável message para false.
     
    Teste e veja se dá algum erro.
  4. Upvote
    Yan Oliveira recebeu reputação de BrunooMaciell em (Duvida) Account Manager   
    Eu dei uma refatorada nesse seu último código, testa e vê se funciona normal agora o looktype do account manager:
     
    local config = { loginMessage = getConfigValue('loginMessage'), useFragHandler = getBooleanFromString(getConfigValue('useFragHandler')) } --alterado v2.6 tabelas soh em lib/configuration.lua; local looktype_accountmanager = 352 -- LOOKTYPE DO ACCOUNT MANAGER local storage_online_points = 5984548 -- STORAGE QUE ARMAZENA PONTOS ONLINE function onLogin(cid) registerCreatureEvent(cid, "hmup") registerCreatureEvent(cid, "PlayerAttack") registerCreatureEvent(cid, "dropStone") registerCreatureEvent(cid, "OnAdvanced") registerCreatureEvent(cid, "vipexp") registerCreatureEvent(cid, "ShowPokedex") registerCreatureEvent(cid, "ClosePokedex") registerCreatureEvent(cid, "WatchTv") registerCreatureEvent(cid, "DropShiny") registerCreatureEvent(cid, "StopWatchingTv") registerCreatureEvent(cid, "WalkTv") registerCreatureEvent(cid, "RecordTv") registerCreatureEvent(cid, "Death") registerCreatureEvent(cid, "PlayerLogout") registerCreatureEvent(cid, "WildAttack") registerCreatureEvent(cid, "Idle") registerCreatureEvent(cid, "PokemonIdle") registerCreatureEvent(cid, "EffectOnAdvance") registerCreatureEvent(cid, "reward") registerCreatureEvent(cid, "GeneralConfiguration") registerCreatureEvent(cid, "ExtendedOpcode") registerCreatureEvent(cid, "ReportBug") registerCreatureEvent(cid, "LookSystem") registerCreatureEvent(cid, "T1") registerCreatureEvent(cid, "T2") registerCreatureEvent(cid, "ll1") registerCreatureEvent(cid, "task_count") registerCreatureEvent(cid, "effectdeath") registerCreatureEvent(cid, "dota") registerCreatureEvent(cid, "atk") registerCreatureEvent(cid, "balance") registerCreatureEvent(cid, "BlockHit") registerCreatureEvent(cid, "Ataque") registerCreatureEvent(cid, "NlooT") registerCreatureEvent(cid, "KillTask") registerCreatureEvent(cid, "KillTaske") registerCreatureEvent(cid, "KillTask3") registerCreatureEvent(cid, "KillTask4") registerCreatureEvent(cid, "PlayerDeath") registerCreatureEvent(cid, "PetKill") registerCreatureEvent(cid, "onlinebonus") registerCreatureEvent(cid, "AtLoot") registerCreatureEvent(cid, "Monster Hunterl") registerCreatureEvent(cid, "Monster Hunter") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, 'Bem Vindo Ao Pokemon Venetta Server') doRegainSpeed(cid) doUpdatePokemonsBar(cid) doPlayerSetLossPercent(cid, PLAYERLOSS_EXPERIENCE, 25) doCreatureSetDropLoot(cid, false) if getCreatureName(cid) ~= "Account Manager" then -- O "ACCOUNT MANAGER" É EXCEÇÃO. doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "(Online Points) Voce Possui " ..getPlayerStorageValue(cid, storage_online_points).. " Online Points Armazenados Em Seu Personagem. Digite !opshop A Qualquer Momento Para Saber Quantos Online Points Voce Possui.") end ----------------------------------------------------------- ACCOUNT MANAGER ----------------------------------------------------------- local accountManager = getPlayerAccountManager(cid) if(accountManager == MANAGER_NONE) then local lastLogin = getPlayerLastLoginSaved(cid) local str = config.loginMessage if(lastLogin > 0) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_DEFAULT, str) str = "Your last visit was on " .. os.date("%a %b %d %X %Y", lastLogin) .. "." end doPlayerSendTextMessage(cid, MESSAGE_STATUS_DEFAULT, str) elseif(accountManager == MANAGER_NAMELOCK) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Ola, parece que voce teve seu nome bloqueado (nameblock), escolha outro nome.") elseif(accountManager == MANAGER_ACCOUNT) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Hello, type 'account' to manage your account and if you want to start over then type 'cancel'.") else doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Hello, type 'account' to create an account or type 'recover' to recover an account.") end if getCreatureName(cid) == "Account Manager" then local outfit = {} if accountManagerRandomPokemonOutfit then outfit = {lookType = getPokemonXMLOutfit(oldpokedex[math.random(151)][1])} else outfit = {lookType = looktype_accountmanager} -- OUTFIT QUE O ACCOUNT MANAGER TEM SE NÃO FOR OUTFIT DE POKÉMON RANDOM end doSetCreatureOutfit(cid, outfit, -1) return true end --------------------------------------------------------------------------------------------------------------------------------------- if getPlayerStorageValue(cid, 17000) >= 1 then setPlayerStorageValue(cid, 17000, 0) doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)), false) sendMsgToPlayer(cid, 20, "Voce Deslogou No Fly E Foi Teleportado Para O CP Por Questoes De Seguranca.") return true end setPlayerStorageValue(cid, 17001, 0) --ride setPlayerStorageValue(cid, 92003, 0) --water robotic setPlayerStorageValue(cid, 92002, 0) --fire robotic setPlayerStorageValue(cid, 92001, 0) --water robotic setPlayerStorageValue(cid, 32001, 0) --bike if getPlayerStorageValue(cid, storage_online_points) < 0 then setPlayerStorageValue(cid, storage_online_points, 0) return true end -- SE AS QUANTIDADES DE FUSION HELDS POINTS FOREM MENOR QUE 0, SETA AS QUANTIDADES DE FUSION HELDS POINTS PARA 0 if getPlayerStorageValue(cid, 1234601) < 0 then setPlayerStorageValue(cid, 1234601, 0) return true end if getPlayerStorageValue(cid, 1234602) < 0 then setPlayerStorageValue(cid, 1234602, 0) return true end if getPlayerStorageValue(cid, 1234603) < 0 then setPlayerStorageValue(cid, 1234603, 0) return true end if getPlayerStorageValue(cid, 1234604) < 0 then setPlayerStorageValue(cid, 1234604, 0) return true end if getPlayerStorageValue(cid, 1234605) < 0 then setPlayerStorageValue(cid, 1234605, 0) return true end if getPlayerStorageValue(cid, 1234606) < 0 then setPlayerStorageValue(cid, 1234606, 0) return true end if getPlayerStorageValue(cid, 1234607) < 0 then setPlayerStorageValue(cid, 1234607, 0) return true end if(not isPlayerGhost(cid)) then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_TELEPORT) end local outfit = {} if getPlayerVocation(cid) == 0 then doPlayerSetMaxCapacity(cid, 7) doPlayerSetVocation(cid, 1) setCreatureMaxMana(cid, 6) doPlayerAddSoul(cid, -getPlayerSoul(cid)) setPlayerStorageValue(cid, 19898, 0) if getCreatureOutfit(cid).lookType == 510 then outfit = {lookType = 510, lookHead = math.random(0, 132), lookBody = math.random(0, 132), lookLegs = math.random(0, 132), lookFeet = math.random(0, 132)} elseif getCreatureOutfit(cid).lookType == 511 then outfit = {lookType = 511, lookHead = math.random(0, 132), lookBody = math.random(0, 132), lookLegs = math.random(0, 132), lookFeet = math.random(0, 132)} end doCreatureChangeOutfit(cid, outfit) end if getPlayerStorageValue(cid, 99284) == 1 then setPlayerStorageValue(cid, 99284, -1) end if getPlayerStorageValue(cid, 6598754) >= 1 or getPlayerStorageValue(cid, 6598755) >= 1 then setPlayerStorageValue(cid, 6598754, -1) setPlayerStorageValue(cid, 6598755, -1) doRemoveCondition(cid, CONDITION_OUTFIT) --alterado v2.9 \/ doTeleportThing(cid, posBackPVP, false) doCreatureAddHealth(cid, getCreatureMaxHealth(cid)) end doChangeSpeed(cid, -(getCreatureSpeed(cid))) --///////////////////////////////////////////////////////////////////////////-- -- local storages = {17000, 63215, 17001, 13008, 5700} -- for s = 1, #storages do -- if not tonumber(getPlayerStorageValue(cid, storages)) then -- if s == 3 then -- setPlayerStorageValue(cid, storages, 1) -- elseif s == 4 then -- setPlayerStorageValue(cid, storages, -1) -- else -- if isBeingUsed(getPlayerSlotItem(cid, 8).itemid) then -- setPlayerStorageValue(cid, storages, 1) --alterado v2.6 -- else -- setPlayerStorageValue(cid, storages, -1) -- end -- end -- doPlayerSendTextMessage(cid, 27, "Sorry, but a problem occurred on the server, but now it's alright") -- end -- end --/////////////////////////////////////////////////////////////////////////-- if getPlayerStorageValue(cid, 17000) >= 1 then -- fly local item = getPlayerSlotItem(cid, 8) local poke = getItemAttribute(item.uid, "poke") doChangeSpeed(cid, getPlayerStorageValue(cid, 54844)) doRemoveCondition(cid, CONDITION_OUTFIT) local addonfly = getPlayerSlotItem(cid, 8).uid local addofly = getItemAttribute(addonfly,"addonfly") if not addofly then doSetItemAttribute(addonfly,"addonfly",0) doSetCreatureOutfit(cid, {lookType = flys[poke][1] + 351}, -1) end if addofly > 0 then doSetCreatureOutfit(cid, {lookType = addofly}, -1) end local apos = getFlyingMarkedPos(cid) apos.stackpos = 0 if getTileThingByPos(apos).itemid <= 2 then doCombatAreaHealth(cid, FIREDAMAGE, getFlyingMarkedPos(cid), 0, 0, 0, CONST_ME_NONE) doCreateItem(460, 1, getFlyingMarkedPos(cid)) end doTeleportThing(cid, apos, false) if getItemAttribute(item.uid, "boost") and getItemAttribute(item.uid, "boost") >= 50 and getPlayerStorageValue(cid, 42368) >= 1 then sendAuraEffect(cid, auraSyst[getItemAttribute(item.uid, "aura")]) --alterado v2.8 end local posicao = getTownTemplePosition(getPlayerTown(cid)) markFlyingPos(cid, posicao) elseif getPlayerStorageValue(cid, 63215) >= 1 then -- surf local item = getPlayerSlotItem(cid, 8) local poke = getItemAttribute(item.uid, "poke") local addonsurf = getPlayerSlotItem(cid, 8).uid local addosurf = getItemAttribute(addonsurf,"addonsurf") if not addosurf then doSetItemAttribute(addonsurf,"addonsurf",0) doSetCreatureOutfit(cid, {lookType = surfs[poke].lookType + 351}, -1) end if addosurf > 0 then doSetCreatureOutfit(cid, {lookType = addosurf}, -1) end doChangeSpeed(cid, getPlayerStorageValue(cid, 54844)) if getItemAttribute(item.uid, "boost") and getItemAttribute(item.uid, "boost") >= 50 and getPlayerStorageValue(cid, 42368) >= 1 then sendAuraEffect(cid, auraSyst[getItemAttribute(item.uid, "aura")]) --alterado v2.8 end elseif getPlayerStorageValue(cid, 17001) >= 1 then -- ride local item = getPlayerSlotItem(cid, 8) local poke = getItemAttribute(item.uid, "poke") if rides[poke] then doChangeSpeed(cid, getPlayerStorageValue(cid, 54844)) doRemoveCondition(cid, CONDITION_OUTFIT) local addonride = getPlayerSlotItem(cid, 8).uid local addoride = getItemAttribute(addonride,"addonride") if not addofly then doSetItemAttribute(addonride,"addonride",0) doSetCreatureOutfit(cid, {lookType = rides[poke][1] + 351}, -1) end if addoride > 0 then doSetCreatureOutfit(cid, {lookType = addoride}, -1) end if getItemAttribute(item.uid, "boost") and getItemAttribute(item.uid, "boost") >= 50 and getPlayerStorageValue(cid, 42368) >= 1 then sendAuraEffect(cid, auraSyst[getItemAttribute(item.uid, "aura")]) --alterado v2.8 end else end local posicao2 = getTownTemplePosition(getPlayerTown(cid)) markFlyingPos(cid, posicao2) elseif getPlayerStorageValue(cid, 13008) >= 1 then -- dive if not isInArray({5405, 5406, 5407, 5408, 5409, 5410}, getTileInfo(getThingPos(cid)).itemid) then setPlayerStorageValue(cid, 13008, 0) doRemoveCondition(cid, CONDITION_OUTFIT) return true end if getPlayerSex(cid) == 1 then doSetCreatureOutfit(cid, {lookType = 1034, lookHead = getCreatureOutfit(cid).lookHead, lookBody = getCreatureOutfit(cid).lookBody, lookLegs = getCreatureOutfit(cid).lookLegs, lookFeet = getCreatureOutfit(cid).lookFeet}, -1) else doSetCreatureOutfit(cid, {lookType = 1035, lookHead = getCreatureOutfit(cid).lookHead, lookBody = getCreatureOutfit(cid).lookBody, lookLegs = getCreatureOutfit(cid).lookLegs, lookFeet = getCreatureOutfit(cid).lookFeet}, -1) end doChangeSpeed(cid, 800) elseif getPlayerStorageValue(cid, 5700) > 0 then --bike doChangeSpeed(cid, -getCreatureSpeed(cid)) doChangeSpeed(cid, getPlayerStorageValue(cid, 5700)) --alterado v2.8 if getPlayerSex(cid) == 1 then doSetCreatureOutfit(cid, {lookType = 1394}, -1) else doSetCreatureOutfit(cid, {lookType = 1393}, -1) end elseif getPlayerStorageValue(cid, 75846) >= 1 then --alterado v2.9 \/ doTeleportThing(cid, getTownTemplePosition(getPlayerTown(cid)), false) setPlayerStorageValue(cid, 75846, -1) sendMsgToPlayer(cid, 20, "You have been moved to your town!") else doRegainSpeed(cid) --alterado v2.6 end if getPlayerStorageValue(cid, 22545) >= 1 then --golden arena setPlayerStorageValue(cid, 22545, -1) --alterado v2.4 doTeleportThing(cid, getClosestFreeTile(cid, posBackGolden), false) setPlayerRecordWaves(cid) --alterado v2.7 end -- local CP = {x=1056, y=1049, z=7} -- if getPlayerStorageValue(cid, 17000) >= 1 then -- setPlayerStorageValue(cid, 17000, 0) -- doTeleportThing(cid, CP) -- end return true end Mesmo esquema do outro script que fiz, deixei mais fácil até, só mudar o ID do looktype na variável looktype_accountmanager no começo do arquivo. Também criei uma variável para a storage dos pontos online que exibe para o player quando loga.
     
    Testa e vê se continua voltando aquela outfit de ADM.
  5. Thanks
    Yan Oliveira recebeu reputação de fearwar em Quest Log em Janela   
    Olá amigos do Xtibia, venho trazer um tutorial simples, mas interessante, que exibe uma caixa de diálogo com texto contendo todas as quests do seu servidor.
     
    Atenção: Testado somente em TFS 0.3/0.4
     
    Vamos lá!
     
    Vá em Data/Talkactions/Scripts e crie um arquivo.lua chamado quest_log.lua e adicione o script:
     
    ---------------- QUEST LOG BY YAN18 ----------------- -- NOME DA QUEST NO ÍNDICE, O NÍVEL E STORAGE NO VALOR -- local quests = { ["Cerulean City"] = {level = 30, storage = 32500}, ["Fire Stone"] = {level = 50, storage = 32501}, ["Boost Machine"] = {level = 100, storage = 32502} } function onSay(cid, words, param) local quest_completada = "- Quests completadas: \n\n" local quest_incompleta = "\n- Quests não completadas: \n\n" for i, _ in pairs (quests) do if (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) < 1) then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" elseif (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) >= 1) then quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end if quest_completada == "- Quests completadas: \n\n" then quest_completada = quest_completada .. " Nenhuma quest foi completada ainda. \n\n" elseif quest_incompleta == "\n- Quests não completadas: \n\n" then quest_incompleta = quest_incompleta .. " Todas as quests foram completadas." end local quest = quest_completada .. quest_incompleta return doShowTextDialog(cid, 1811, quest) end  
    Agora abra o talkactions.xml que fica em Data/Talkactions/talkctions.xml e adicione a tag:
    <talkaction words="!quest" event="script" value="quest_log.lua"/> Deixei o comando !quest ali em words na tag xml, mas você pode colocar outro comando de sua preferência.
     
    Explicação: Adicione todas as quests do servidor na tabela quests, colocando o nome dela como índice, o level e storage (preste bem atenção para colocar a storage correta) como valores. Em caso de dúvidas, só seguir o exemplo que fiz. Também fiz verificação para ver se todas as quests do jogo (que você colocar na tabela) foram feitas ou não, e também fiz verificação de nível do jogador por quest, ou seja, os jogadores só verão as quests que eles tem nível para fazer. De resto não tem muito o que mexer, só se quiser reduzir ou aumentar a quantidade de espaço entre as linhas, mas ai é da preferência de cada um. Caso queira retirar a verificação de nível do jogador (pare verem todas as quests) só mudar isso:
     
    for i, _ in pairs (quests) do if (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) < 1) then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" elseif (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) > 1) quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end Para isso:
    for i, _ in pairs (quests) do if getPlayerStorageValue(cid, quests[i].storage) < 1 then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" else quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end  
    Se fizer tudo corretamente, é para aparecer essa janela com as informações e nível da(s) quest(s):
     

     
    Essa janela é criada na função doShowTextDialog, e o segundo parâmetro dela é um item que aparece como ícone, geralmente deixam 0 (e recomendo deixar 0 como padrão), mas tem base que o id do item 0 aparece como algum item do jogo (as vezes montanhas ou outros itens de ambiente), então deixei um blackboard, até para ficar mais coerente hehe. Você também pode criar um item para representar essa janela, mas vai da preferência e criatividade de cada um. 
     
    Se você tiver source, pode até criar uma janela com título de "Quests" para ficar mais bonito a interface, mas vai de cada um.
     
    OBS: Em alguns servidores pode ser que dê crash na distro por conta do item passado no segundo parâmetro da função doShowTextDialog(cid, id_item, texto), precisa ficar atento nisso.
     
     
    Qualquer dúvida só perguntar!
     
    Abraços e fiquem com Deus!
  6. Upvote
    Yan Oliveira recebeu reputação de Darwiinxp em Super SD VIP   
    @Darwiinxp o @brazvct está falando para você fazer isso:
    local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TARGETCASTERORTOPMOST, true) setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SUDDENDEATH) setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -1, -32, -1, -48, 5, 5, 8, 13) function onCastSpell(cid, var) if getPlayerStorageValue(cid, 13540) > 0 then return doCombat(cid, combat, var) else doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Você precisa ser vip para usar esse ataque.") doPlayerSendCancel(cid, "Você precisa ser vip para usar esse ataque.") return true end end  
  7. Amei
    Yan Oliveira deu reputação a M i s s em [Resolvido] Item aparece em local aleatorio   
    @Yan18 agora funcionou sem erros, vc é incrivel  ❤️  obgd
  8. Upvote
    Yan Oliveira recebeu reputação de mister17 em Script addon dando erro   
    Pelo visto, seu servidor não tem a função getPlayerLanguage.
  9. Upvote
    Yan Oliveira recebeu reputação de Darwiinxp em [Resolvido] Item ñao da attributtes   
    No caso de bags (ou backpacks), para aparecer os atributos no look é necessário ter essa tag:
    <attribute key="showattributes" value="1"/> Deixar como última tag do item.
     
    Se mesmo assim não aparecer, então é na source, pois, tem source que são configuradas para mostrarem atributos no look apenas em Armors e Weapons.
     
  10. Amei
    Yan Oliveira recebeu reputação de LeoTK em Poção que cura com base na vida máxima   
    Exato, mas esqueci de mencionar uma coisa. Caso queira aleatório assim, vai ter que mover a tabela das potions para dentro da função onUse, pois, se deixar fora, a primeira vez que usar a potion vai pegar um valor aleatório (de acordo com cada item e o valor gerado aleatório para ele), porém nas próximas vezes vai ficar sempre aquele valor, pois como as pastas são carregadas em memória, então fora do onUse ele armazena aquele valor em memória e nunca é alterado. Por exemplo, vamos supor que você tem 2 potion na tabela e a de uma o random deu 35 e a outra 38, se deixar a tabela fora da função onUse vai ficar sempre curando 35 uma e a outra 38 até reiniciar o servidor ou atualizar a pasta Actions.
     
    Então o certo é mover a tabela dentro da função onUse, para que a cada uso, gere um novo valor:
    --------------- POTION QUE CURA BASEADO NA PORCENTAGEM DA VIDA MÁXIMA BY YAN18 --------------- ----- FUNÇÃO PARA CURAR O PLAYER ----- function doHealPlayer(cid, porcentagem_hp, effect, message_heal) local porcentagem = math.abs(porcentagem_hp / 100) -- PEGA O VALOR INTEIRO PASSADO DO PARÂMETRO DESEJADO COMO A PORCENTAGEM E DIVIDE POR 100 PARAR GERAR A PORCENTAGEM local life_recovered = math.floor(getCreatureMaxHealth(cid) * porcentagem) -- QUANTIDADE DE HP QUE VAI RECUPERAR doSendMagicEffect(getThingPos(cid), effect) doCreatureAddHealth(cid, life_recovered) -- CONDICIONAL PARA EXIBIR MENSAGEM EM CIMA DO PLAYER AO CURAR -- if message_heal then doCreatureSay(cid, "Life recovered...") end doPlayerSendCancel(cid, "Life recovered...") -- MENSAGEM BRANCE EM CIMA DO CONSOLE doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You recovered " ..life_recovered.. " of your maximum life.") end ---------------------------------------- CÓDIGO ---------------------------------------- function onUse(cid, item, fromPosition, itemEx, toPosition) --------- TABELA COM O ID, PORCENTAGEM E EFEITO DAS POTIONS --------- local potions = { [12344] = {porcentagem = math.floor(math.random(30, 40)), effect = 14}, -- ID, PORCENTAGEM E EFEITO DA POTION [12345] = {porcentagem = math.floor(math.random(30, 40)), effect = 14}, -- ID, PORCENTAGEM E EFEITO DA POTION [12346] = {porcentagem = math.floor(math.random(30, 40)), effect = 12}, -- ID, PORCENTAGEM E EFEITO DA POTION [12347] = {porcentagem = math.floor(math.random(30, 40)), effect = 13}, -- ID, PORCENTAGEM E EFEITO DA POTION [12348] = {porcentagem = math.floor(math.random(30, 40)), effect = 13}, -- ID, PORCENTAGEM E EFEITO DA POTION } local verificar_batalha = true -- VARIÁVEL QUE VERIFICA SE ESTÁ EM BATALHA PARA USAR A POTION if not isCreature(cid) or not getCreatureMaster(cid) then return doPlayerSendCancel(cid, "You only can use this potion in you.") end if getCreatureHealth(cid) == getCreatureMaxHealth(cid) then return doPlayerSendCancel(cid, "You are already with full health.") end -- VERIFICA SE ESTÁ EM BATALHA -- if verificar_batalha then if getCreatureCondition(cid, CONDITION_INFIGHT) then doPlayerSendCancel(cid, "You can't use this potion during a battle.") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You can't use this potion during a battle.") return true end end doRemoveItem(item.uid, 1) doHealPlayer(cid, potions[item.itemid].porcentagem, potions[item.itemid].effect, true) return true end  
  11. Upvote
    Yan Oliveira recebeu reputação de BrunooMaciell em (BUG) NPC Hunter   
    O erro está nessa linha:
    if #getCreatureSummfighting = falseons(_target) > 0 then Não tem sentido algum a expressão no if. Mude para :
    if #getCreatureSummons(_target) > 0 then  
    Estou me baseando no seu outro próprio post: 
     
    Então a função vai ficar:
    function selfAttackCreature() if #getCreatureSummons(getNpcCid()) > 0 and not isCreature(getCreatureTarget(getCreatureSummons(getNpcCid())[1])) then local list = getSpectators(getCreaturePosition(getNpcCid()), 7, 7, false) for i=0, table.getn(list) do local _target = list if(_target ~= 0) then if isPlayer(_target) and not getTileInfo(getThingPos(_target)).protection then if #getCreatureSummons(_target) > 0 then doMonsterSetTarget(getCreatureSummons(getNpcCid())[1], getCreatureSummons(_target)[1]) setPlayerStorageValue(getCreatureSummons(getNpcCid())[1], 99856201, getNpcCid()) else fighting = false end target = _target break end end end end end Só substituir no Some Functions.lua onde coloquei para você, ou apenas trocar a linha acima.
     
    A linha alterada foi o que o Nociam te respondeu no seu outro post, ai tem que testar para ver se funciona. Mas, como ele recomendou nesse post recente:
    Deve ter funcionado.
     
    Teste e avise se der problema.
  12. Thanks
    Yan Oliveira recebeu reputação de LeoTK em Poção que cura com base na vida máxima   
    Qual é a versão de TFS?
     
    Eu fiz um script baseado na versão de TFS 0.3.6/0.4
     
    -- LUA --
     
    Se você já tem o arquivo do script criado ignore o restante dessa linha e vá para o código, caso não tenha, vá em Data/Actions/Scripts e crie o arquivo potions.lua e adiciona o script:
    --------------- POTION QUE CURA BASEADO NA PORCENTAGEM DA VIDA MÁXIMA BY YAN18 --------------- ----- FUNÇÃO PARA CURAR O PLAYER ----- function doHealPlayer(cid, porcentagem_hp, effect, message_heal) local porcentagem = math.abs(porcentagem_hp / 100) -- PEGA O VALOR INTEIRO PASSADO DO PARÂMETRO DESEJADO COMO A PORCENTAGEM E DIVIDE POR 100 PARAR GERAR A PORCENTAGEM local life_recovered = math.floor(getCreatureMaxHealth(cid) * porcentagem) -- QUANTIDADE DE HP QUE VAI RECUPERAR doSendMagicEffect(getThingPos(cid), effect) doCreatureAddHealth(cid, life_recovered) -- CONDICIONAL PARA EXIBIR MENSAGEM EM CIMA DO PLAYER AO CURAR -- if message_heal then doCreatureSay(cid, "Life recovered...") end doPlayerSendCancel(cid, "Life recovered...") -- MENSAGEM BRANCE EM CIMA DO CONSOLE doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You recovered " ..life_recovered.. " of your maximum life.") end --------- TABELA COM O ID, PORCENTAGEM E EFEITO DAS POTIONS --------- local potions = { [12344] = {porcentagem = 40, effect = 14}, -- ID, PORCENTAGEM E EFEITO DA POTION [12345] = {porcentagem = 40, effect = 14}, -- ID, PORCENTAGEM E EFEITO DA POTION [12346] = {porcentagem = 40, effect = 12}, -- ID, PORCENTAGEM E EFEITO DA POTION [12347] = {porcentagem = 40, effect = 13}, -- ID, PORCENTAGEM E EFEITO DA POTION [12348] = {porcentagem = 40, effect = 13}, -- ID, PORCENTAGEM E EFEITO DA POTION } ---------------------------------------- CÓDIGO ---------------------------------------- function onUse(cid, item, fromPosition, itemEx, toPosition) local verificar_batalha = true -- VARIÁVEL QUE VERIFICA SE ESTÁ EM BATALHA PARA USAR A POTION if not isCreature(cid) or not getCreatureMaster(cid) then return doPlayerSendCancel(cid, "You only can use this potion in you.") end if getCreatureHealth(cid) == getCreatureMaxHealth(cid) then return doPlayerSendCancel(cid, "You are already with full health.") end -- VERIFICA SE ESTÁ EM BATALHA -- if verificar_batalha then if getCreatureCondition(cid, CONDITION_INFIGHT) then doPlayerSendCancel(cid, "You can't use this potion during a battle.") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "You can't use this potion during a battle.") return true end end doRemoveItem(item.uid, 1) doHealPlayer(cid, potions[item.itemid].porcentagem, potions[item.itemid].effect, true) return true end * Explicação sobre o script: Eu criei uma função que recupera vida do player de acordo com a vida máxima, ela contém quatro parâmetros, que é: criatura, porcentagem baseado na vida máxima, efeito da potion e se exibe mensagem que está curando (esse último argumento é mais estética e não muda e interfere em nada na cura), mas, caso não queira essas mensagens (em cima do player e em cima do console), lá no fim do script dentro da função onUse, mude o último parâmetro da função doHealPlayer de true para false, ficando:
    doHealPlayer(cid, potions[item.itemid].porcentagem, potions[item.itemid].effect, false)  
    Em cima da função onUse tem a tabela com as potions, então no índice ([] colchetes) coloque o id da potion e na tabela dentro do id tem o valor da porcentagem e efeito da potion. No valor da porcentagem passe a quantidade direto (10, 20, 30 por exemplo) pois eu já estou criando a porcentagem dentro da função (valor dividido por 100 para criar a porcentagem), deixei bem simples para você.  Então com a tabela você consegue inserir mais de uma potion, caso só queira usar 1, pode apagar a tabela e passar o id e efeito da potion direto na função doHealPlayer no segundo e terceiro parâmetro:
    doHealPlayer(cid, 14523, 25, true) Fiz um exemplo acima, também pode deixar só 1 potion na tabela, não tem problema! É até melhor para não correr risco de acabar pagando o que não deve, mas, nesse caso apague os elementos restantes da tabela deixando só um.
     
    E por fim, fiz uma verificação para verificar se o player está em batalha, e se estiver, não usa a potion. Caso queira mudar isso, só mudar o valor da variável verificar_batalha de true para false:
    local verificar_batalha = false  
    -- XML --
     
    Terminado a explicação sobre o script, agora é a parte do xml. Caso, já tenha a tag da potion criada, pode ignorar essa parte, mas lembrando que precisa colocar os mesmos ID das potions da tag xml na tabela do script.lua caso optou em manter a tabela. Mas, se não criou a tag xml, vamos lá! Abra o actions.xml e adicione a tag:
    <action itemid="12344-12348" event="script" value="potions.lua"/> Lembrando que se você está usando mais de 1 potion e os id delas não são em sequência, precisa tirar o hífen (-) da tag xml e colocar ponto e vírgula (;) para separar os id, pois com hífen é quando é mais de 1 id que são em sequência.
     
    Testa e me fala se deu algum problema. Qualquer dúvida só falar.
  13. Upvote
    Yan Oliveira recebeu reputação de Batat em Icone (Houses)   
    Olá, a ball só fica com o ícone na bag porque o sistema de ícone trabalha quando pega Pokémon do slot (bag), ou seja, ele pega pokeball com Pokémon dentro da mochila e transforma em ícone ball. Essa maneira é trabalhada por questão de segurança in-game, pois se algum player dividir house, ou jogar a ball no chão (caso empreste para alguém ou queira mostrar) fica ocultado o pokémon que é, claro que se der look vai saber, mas é mais seguro do que a pessoa olhar e saber diretamente o pokémon que está no chão.
     
    Mas qual base você usa? Geralmente o arquivo de ícone fica em Data/Lib.
  14. Amei
    Yan Oliveira recebeu reputação de Jhony Araujo em BOSS NÃO ABRE CORPO   
    Com qual char está matando, com char ADM?
  15. Thanks
    Yan Oliveira recebeu reputação de NyckAlmeida em Erro ao iniciar o server "Spell is using a reserved name"   
    É uma opção, adicionar outro nome junto com espaço.
  16. Thanks
    Yan Oliveira recebeu reputação de NyckAlmeida em Erro ao iniciar o server "Spell is using a reserved name"   
    Isso não é erro de duplicata, mas sim que a spell está usando um nome reservado, precisa mudar a nomenclatura.
  17. Upvote
    Yan Oliveira recebeu reputação de BrunooMaciell em (Pedido) Sistema   
    Não, ai é só criação de variáveis estáticas, você tem que colocar onde eu falei, em baixo da function onUse. Mas nos script da moto police e rcoket eu já fiz essa verificação.
  18. Upvote
    Yan Oliveira recebeu reputação de BrunooMaciell em (Pedido) Sistema   
    Já adicionei a verificação de premium nas duas conforme te falei no post que coloquei os scripts.
  19. Upvote
    Yan Oliveira recebeu reputação de BrunooMaciell em (Pedido) Sistema   
    Moto Police:
    local strgs = {17000, 17001} -- Coloque a Storage de Controle dos Sistemas Que Deseja Bloquear. local config = { outfitMale = 5510, -- Outfit male outfitFemale = 5509, -- Outfit female storageValue = 323339, -- Storage Para a bike } local storage_police = 52000 -- STORAGE PARA O PLAYER QUE É POLICE function onUse(cid, item, itemEx, fromPosition, toPosition) if getPlayerStorageValue(cid, storage_police) < 1 then doPlayerSendCancel(cid, "Você precisa ser Police para usar essa moto.") return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Você precisa ser Police para usar essa moto.") end if isPremium(cid) then ctrl = 0 for x = 1, #strgs do if getPlayerStorageValue(cid, strgs[x]) > 0 then ctrl = ctrl + 1 end end if ctrl < 1 then if isPlayer(cid) and getCreatureOutfit(cid).lookType == 814 then return false end if getPlayerStorageValue(cid, 92001) >= 1 then doPlayerSendCancel(cid, "Você não pode usar bike e robo ao mesmo tempo.") return false end if getPlayerStorageValue(cid, 92002) >= 1 then doPlayerSendCancel(cid, "Você não pode usar bike e robo ao mesmo tempo.") return false end if getPlayerStorageValue(cid, 92003) >= 1 then doPlayerSendCancel(cid, "Você não pode usar bike e robo ao mesmo tempo.") return false end if getPlayerStorageValue(cid, 92004) >= 1 then doPlayerSendCancel(cid, "Você não pode usar bike e robo ao mesmo tempo.") return false end if getPlayerStorageValue(cid, 92005) >= 1 then doPlayerSendCancel(cid, "Você não pode usar bike e robo ao mesmo tempo.") return false end if getPlayerStorageValue(cid, 19000) == 1 then doPlayerSendCancel(cid, "Você não pode usar bike e correr ao mesmo tempo.") return false end if getPlayerStorageValue(cid, config.storageValue) <= 0 then local a = {lookType = config.outfitMale, lookHead = getCreatureOutfit(cid).lookHead, lookBody = getCreatureOutfit(cid).lookBody, lookLegs = getCreatureOutfit(cid).lookLegs, lookFeet = getCreatureOutfit(cid).lookFeet} local b = {lookType = config.outfitFemale, lookHead = getCreatureOutfit(cid).lookHead, lookBody = getCreatureOutfit(cid).lookBody, lookLegs = getCreatureOutfit(cid).lookLegs, lookFeet = getCreatureOutfit(cid).lookFeet} setPlayerStorageValue(cid, 32001, ""..getPlayerStamina(cid).."") doChangeSpeed(cid, 1500) setPlayerStorageValue(cid, config.storageValue, 1) if getPlayerSex(cid) == 0 then doSetCreatureOutfit(cid, b, -1) else doSetCreatureOutfit(cid, a, -1) end else setPlayerStorageValue(cid, config.storageValue, 0) doRemoveCondition(cid, CONDITION_OUTFIT) doRegainSpeed(cid) end else doPlayerSendCancel(cid, "Você não pode usar bike enquanto está no Fly/Hide.") end else doPlayerSendCancel(cid, "Você precisa ser Premium para usar essa moto.") return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Você precisa ser Premium para usar essa moto.") end return true end  
    Moto Rocket:
    local strgs = {17000, 17001} -- Coloque a Storage de Controle dos Sistemas Que Deseja Bloquear. local config = { velocidadeDaSuaBike = 1500, -- A volocidade da bike (1-9) outfitMale = 5517, -- Outfit male outfitFemale = 5516, -- Outfit female storageValue = 32053, -- Storage Para a bike } local storage_rocket = 52001 -- STORAGE PARA O PLAYER QUE FOR ROCKET function onUse(cid, item, itemEx, fromPosition, toPosition) if getPlayerStorageValue(cid, storage_rocket) < 1 then doPlayerSendCancel(cid, "Você precisa ser Rocket para usar essa moto.") return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Você precisa ser Rocket para usar essa moto.") end if isPremium(cid) then ctrl = 0 for x = 1, #strgs do if getPlayerStorageValue(cid, strgs[x]) > 0 then ctrl = ctrl + 1 end end if ctrl < 1 then if isPlayer(cid) and getCreatureOutfit(cid).lookType == 814 then return false end if getPlayerStorageValue(cid, config.storageValue) <= 0 then local a = {lookType = config.outfitMale, lookHead = getCreatureOutfit(cid).lookHead, lookBody = getCreatureOutfit(cid).lookBody, lookLegs = getCreatureOutfit(cid).lookLegs, lookFeet = getCreatureOutfit(cid).lookFeet} local b = {lookType = config.outfitFemale, lookHead = getCreatureOutfit(cid).lookHead, lookBody = getCreatureOutfit(cid).lookBody, lookLegs = getCreatureOutfit(cid).lookLegs, lookFeet = getCreatureOutfit(cid).lookFeet} setPlayerStorageValue(cid, 32001, ""..getPlayerStamina(cid).."") doChangeSpeed(cid, -getCreatureSpeed(cid)) doChangeSpeed(cid, config.velocidadeDaSuaBike) setPlayerStorageValue(cid, config.storageValue, 1) if getPlayerSex(cid) == 0 then doSetCreatureOutfit(cid, b, -1) else doSetCreatureOutfit(cid, a, -1) end else setPlayerStorageValue(cid, config.storageValue, 0) doRemoveCondition(cid, CONDITION_OUTFIT) doRegainSpeed(cid) end else doPlayerSendCancel(cid, "Você não pode usar a moto enquanto está no Fly/Ride.") end else doPlayerSendCancel(cid, "Você precisa ser Premium para usar essa moto.") return doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Você precisa ser Premium para usar essa moto.") end return true end Fiz verificação se é Police ou Rocket e se é premium. Na variável storage_police e storage_rocket só colocar a storage de cada, e lembrando que deixei para ver se são com o valor de storage 1, então se for 0 o valor da storage, precisa mudar na verificação.
     
    Mas testa e fala se der algum problema.
  20. Upvote
    Yan Oliveira recebeu reputação de rolpoes em Quest Log em Janela   
    Olá amigos do Xtibia, venho trazer um tutorial simples, mas interessante, que exibe uma caixa de diálogo com texto contendo todas as quests do seu servidor.
     
    Atenção: Testado somente em TFS 0.3/0.4
     
    Vamos lá!
     
    Vá em Data/Talkactions/Scripts e crie um arquivo.lua chamado quest_log.lua e adicione o script:
     
    ---------------- QUEST LOG BY YAN18 ----------------- -- NOME DA QUEST NO ÍNDICE, O NÍVEL E STORAGE NO VALOR -- local quests = { ["Cerulean City"] = {level = 30, storage = 32500}, ["Fire Stone"] = {level = 50, storage = 32501}, ["Boost Machine"] = {level = 100, storage = 32502} } function onSay(cid, words, param) local quest_completada = "- Quests completadas: \n\n" local quest_incompleta = "\n- Quests não completadas: \n\n" for i, _ in pairs (quests) do if (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) < 1) then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" elseif (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) >= 1) then quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end if quest_completada == "- Quests completadas: \n\n" then quest_completada = quest_completada .. " Nenhuma quest foi completada ainda. \n\n" elseif quest_incompleta == "\n- Quests não completadas: \n\n" then quest_incompleta = quest_incompleta .. " Todas as quests foram completadas." end local quest = quest_completada .. quest_incompleta return doShowTextDialog(cid, 1811, quest) end  
    Agora abra o talkactions.xml que fica em Data/Talkactions/talkctions.xml e adicione a tag:
    <talkaction words="!quest" event="script" value="quest_log.lua"/> Deixei o comando !quest ali em words na tag xml, mas você pode colocar outro comando de sua preferência.
     
    Explicação: Adicione todas as quests do servidor na tabela quests, colocando o nome dela como índice, o level e storage (preste bem atenção para colocar a storage correta) como valores. Em caso de dúvidas, só seguir o exemplo que fiz. Também fiz verificação para ver se todas as quests do jogo (que você colocar na tabela) foram feitas ou não, e também fiz verificação de nível do jogador por quest, ou seja, os jogadores só verão as quests que eles tem nível para fazer. De resto não tem muito o que mexer, só se quiser reduzir ou aumentar a quantidade de espaço entre as linhas, mas ai é da preferência de cada um. Caso queira retirar a verificação de nível do jogador (pare verem todas as quests) só mudar isso:
     
    for i, _ in pairs (quests) do if (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) < 1) then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" elseif (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) > 1) quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end Para isso:
    for i, _ in pairs (quests) do if getPlayerStorageValue(cid, quests[i].storage) < 1 then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" else quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end  
    Se fizer tudo corretamente, é para aparecer essa janela com as informações e nível da(s) quest(s):
     

     
    Essa janela é criada na função doShowTextDialog, e o segundo parâmetro dela é um item que aparece como ícone, geralmente deixam 0 (e recomendo deixar 0 como padrão), mas tem base que o id do item 0 aparece como algum item do jogo (as vezes montanhas ou outros itens de ambiente), então deixei um blackboard, até para ficar mais coerente hehe. Você também pode criar um item para representar essa janela, mas vai da preferência e criatividade de cada um. 
     
    Se você tiver source, pode até criar uma janela com título de "Quests" para ficar mais bonito a interface, mas vai de cada um.
     
    OBS: Em alguns servidores pode ser que dê crash na distro por conta do item passado no segundo parâmetro da função doShowTextDialog(cid, id_item, texto), precisa ficar atento nisso.
     
     
    Qualquer dúvida só perguntar!
     
    Abraços e fiquem com Deus!
  21. Amei
    Yan Oliveira recebeu reputação de GamerGoiano em Iniciar Servidor Automático Após Shutdown   
    Distro Restarter by Yan18
     
    Olá caros amigos do Xtibia, hoje irei ensinar como reiniciar a distro do server automaticamente após um shutdown (no sistema operacional Windows). Decidi fazer esse tutorial após ver muitos pedidos sobre isso, não sei se já existe algum tutorial sobre isso aqui no fórum, mas decidi criar junto com um script que exibe uma mensagem para o server todo alertando que o servidor será reiniciado após X minutos.
     
    Para isso, irei trabalhar com um arquivo .bat do Windows, para que ele sempre execute a distro quando não estiver sendo executada. 
     
    ATENÇÃO: Leia isso antes de seguir o tutorial! Esse método só vai funcionar se a sua distro for em interface GUI! Se for por prompt (linha de comando) não irá funcionar porque a distro já será executada em prompt.
     
    Começo do Tutorial
     
     
    - Evento Shutdown
     
    Para começar, vamos criar um evento global para dar shutdown e exibir uma mensagem de aviso para todos os jogadores que o servidor será reiniciado, para ficar mais sofisticado e bonito o processo. E eles estarem ciente, assim dá tempo de todos irem para um local seguro!
     
    Agora vá em Data/Globalevents/Scripts e crie o arquivo shutdown.lua e insira o código dentro:
     
    TFS 0.3/0.4
    function avisoShutdown(minutos) local minutos_shutdown = 1 -- VARIÁVEL PARA DAR UM TEMPO (EM MINUTOS) PARA SALVAR O SERVIDOR E DEPOIS DAR SHUTDOWN EM SEGUIDA if minutos > 0 then doBroadcastMessage("O servidor será reiniciado em " ..minutos) addEvent(avisoShutdown, 60000, cid, minutos - 1) else doSaveServer() addEvent(doShutdown, minutos_shutdown * 60000) return true end end function onTime() avisoShutdown(5) -- MINUTOS MANDAR MENSAGEM DE AVISO PARA SALVAR E DAR SHUTDOWN end  
    TFS 1.0 / 1.+
    function avisoShutdown(minutos) local minutos_shutdown = 1 -- VARIÁVEL PARA DAR UM TEMPO (EM MINUTOS) PARA SALVAR O SERVIDOR E DEPOIS DAR SHUTDOWN EM SEGUIDA if minutos > 0 then if minutos > 1 then broadcastMessage("O servidor será reiniciado em " ..minutos.. " minutos.") else broadcastMessage("O servidor será reiniciado em " ..minutos.. " minuto.") end addEvent(avisoShutdown, 60000, minutos - 1) else saveServer() addEvent(Game.setGameState(GAME_STATE_SHUTDOWN), minutos_shutdown * 60000) return true end end function onTime(interval) avisoShutdown(5) -- MINUTOS MANDAR MENSAGEM DE AVISO PARA SALVAR E DAR SHUTDOWN end Explicação: O script vai fazer um contagem regressiva de minutos (pelo valor definido no parâmetro passado na função avisoShutdown) e depois ele irá ter um delay pelo valor da variável minutos_shutdown. Parece confuso duas variáveis de minutos né? Mas a variável minutos_shutdown é um "delay" para dar tempo de salvar e depois efetuar o shutdown, pois tem servidor que o mapa é grande, tem muitos jogadores e itens, então pode demorar um pouco, ai é só mudar o valor na variável. Está o valor 1 por padrão. E na função chamada pelo evento onTime você coloca os minutos para o player ver os minutos restantes para o servidor ser reiniciado.
     
    Agora, abra o arquivo globalevents.xml e adicione a tag:
    <globalevent name="shutdown_server" time="12:00" event="script" value="shutdown.lua"/> Em time coloque o horário que deseja executar o evento para fazer o shutdown.
     
    Agora acabamos a parte do evento e vamos para a parte do reiniciador!
     
    - PROMPT (Arquivo .Bat)
     
    Agora iremos criar o arquivo bat para reiniciar a distro. Vá no bloco de notas ou no notepad++ (de sua preferência) e insira o seguinte script dentro:
    title Reinicializador da Distro echo --------- MENSAGEM QUANDO INICIAR A DISTRO ------------ echo. echo Status: INICIANDO O SERVIDOR... echo. :begin TFS.exe echo --------- MENSAGEM QUANDO DESLIGAR OU REINICIAR A DISTRO COM O ARQUIVO BAT ABERTO ------------ echo. echo Aviso: O SERVIDOR FOI DESLIGADO OU SERÁ REINICIADO. echo. echo Status: O SERVIDOR ESTÁ SENDO REINICIADO! echo. goto begin :goto begin Salve esse script (de preferência com um nome sem espaço) com a extensão .bat. Eu recomendo Restarter, mas fica por sua preferência!
     
    OBS: Salve o arquivo com a codificação UTF-8, por padrão já vem, mas caso não venha é só colocar!

     
     
    Explicação:
    @echo off O "echo off" Oculta informações e o código executado pelo sistema, e o "@echo" oculta a interface durante a execução do programa. É possível juntar os dois modos, assim como fiz acima.
    title Nessa parte você coloca o título do arquivo bat em seguida da palavra reservada title, que fica na parte superior da interface. Só seguir o exemplo anterior da criação do arquivo. 
    OBS: No título você pode colocar espaço a vontade.
    echo Aqui é onde vai aparecer as mensagens na interface, pode colocar qualquer caractere desejado, pode usar pontos, acentos (acentos acontecerá algo de errado que será explica mas para o fim do tutorial.) e o que desejar. E para dar uma quebra de linha, é só colocar ponto depois do echo: echo. 
    begin É onde começa a executar o procedimento (executar a distro). Mas ai você pergunta: "Mas e as linhas anteriores com mensagens?". Mas a resposta é que as linhas anteriores não executam o programa, e sim inserem mensagem assim que executamos o arquivo bat (ressaltando que quando abrimos o arquivo bat ele inicia a distro, porém só vai reiniciar a distro sempre que der shutdown ou crashar enquanto o arquivo bat estiver aberto).
    TFS.exe Em baixo do ":begin" vai ter TFS.exe, e nessa linha é onde coloca o nome do executável (distro).
    OBS: Evite colocar nome da distro com espaço, ele funciona, mas para evitar problemas, deixe junto!
    goto begin E por fim temos o goto begin, a palavra reservada goto faz um pulo para o que colocar na frente dela, ou seja, depois que executar tudo que está acima dela, vai ir para o que declara na frente, no nosso caso, o begin (irá fazer um loop de reiniciar sempre que a distro estiver desligada no nosso caso enquanto o arquivo bat estiver rodando).
     
    Beleza Yan, acabamos?
     
    Ainda não acabamos! Tenha calma, se você chegou até aqui, vai aguentar até o fim!
     
    Agora iremos executar o arquivo bat (lembrando que se quer usar o auto restarter, não pode abrir a distro antes do arquivo bat, se não vai dar erro de distro já aberta, porque o arquivo irá abrir novamente).
     
    Mas antes de rodar, não se esqueça de colocar o arquivo bat no mesmo diretório (pasta) da distro, tem que ficar junto senão não vai funcionar.
     
    Feito isso, execute o arquivo bat, se der tudo certo e seguiu os passos corretamente, irá aparecer assim seguindo nossa criação:

     
    E a distro irá iniciar logo em seguida.
     
    Agora vamos testar um shutdown na distro (lembre-se de deixar o prompt do arquivo bat aberto!):
     

     
    Agora você vai falar, "Funcionou!! Acabamos?", sim de fato funcionou, porém, se repara as mensagens com acento estão "bugadas". Isso se deve ao fato de que por padrão não lê acento (Windows foi criado na língua inglesa). Então, para funcionar precisaremos ir na primeira linha do código do arquivo bat e colocar:
    chcp 65001 off Pois essa linha permite acentuação (lembrando de permanecer a codificação UTF-8 ainda).
     
    Então o script ficará assim:
    chcp 65001 @echo off echo. title Reinicializador da Distro echo --------- MENSAGEM QUANDO INICIAR A DISTRO ------------ echo. echo Status: INICIANDO O SERVIDOR... echo. :begin TFS.exe echo --------- MENSAGEM QUANDO DESLIGAR OU REINICIAR A DISTRO COM O ARQUIVO BAT ABERTO ------------ echo. echo Aviso: O SERVIDOR FOI DESLIGADO OU SERÁ REINICIADO. echo. echo Status: O SERVIDOR ESTÁ SENDO REINICIADO! echo. goto begin :goto begin  
    Ficando então o script do arquivo bat:

     
    Agora temos o caminho do diretório do executável e uma mensagem do sistema alegando que foi ativado esse comando. Se fizer tudo certo é para aparecer assim!
     
    E agora vamos testar o shutdown:

     
    Como podemos ver executou corretamente e leu os caracteres com acento.
     
    Agora vem a pergunta: "Acabou?", e a resposta é... Sim, acabou! Lembrando que você pode encerrar a distro manualmente (fechando) que o arquivo bat irá reiniciar, não precisa depender só do evento shutdown, mas não esqueça de deixar o restarter aberto.
     
    Obrigado por ter chegado até aqui e espero que te ajude o tutorial. Qualquer dúvida só perguntar.
     
    Logo estarei preparando um tutorial desses para Linux!
     
    Abraços e fiquem com Deus!
  22. Thanks
    Yan Oliveira recebeu reputação de zllcapiroto em Quest Log em Janela   
    Olá amigos do Xtibia, venho trazer um tutorial simples, mas interessante, que exibe uma caixa de diálogo com texto contendo todas as quests do seu servidor.
     
    Atenção: Testado somente em TFS 0.3/0.4
     
    Vamos lá!
     
    Vá em Data/Talkactions/Scripts e crie um arquivo.lua chamado quest_log.lua e adicione o script:
     
    ---------------- QUEST LOG BY YAN18 ----------------- -- NOME DA QUEST NO ÍNDICE, O NÍVEL E STORAGE NO VALOR -- local quests = { ["Cerulean City"] = {level = 30, storage = 32500}, ["Fire Stone"] = {level = 50, storage = 32501}, ["Boost Machine"] = {level = 100, storage = 32502} } function onSay(cid, words, param) local quest_completada = "- Quests completadas: \n\n" local quest_incompleta = "\n- Quests não completadas: \n\n" for i, _ in pairs (quests) do if (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) < 1) then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" elseif (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) >= 1) then quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end if quest_completada == "- Quests completadas: \n\n" then quest_completada = quest_completada .. " Nenhuma quest foi completada ainda. \n\n" elseif quest_incompleta == "\n- Quests não completadas: \n\n" then quest_incompleta = quest_incompleta .. " Todas as quests foram completadas." end local quest = quest_completada .. quest_incompleta return doShowTextDialog(cid, 1811, quest) end  
    Agora abra o talkactions.xml que fica em Data/Talkactions/talkctions.xml e adicione a tag:
    <talkaction words="!quest" event="script" value="quest_log.lua"/> Deixei o comando !quest ali em words na tag xml, mas você pode colocar outro comando de sua preferência.
     
    Explicação: Adicione todas as quests do servidor na tabela quests, colocando o nome dela como índice, o level e storage (preste bem atenção para colocar a storage correta) como valores. Em caso de dúvidas, só seguir o exemplo que fiz. Também fiz verificação para ver se todas as quests do jogo (que você colocar na tabela) foram feitas ou não, e também fiz verificação de nível do jogador por quest, ou seja, os jogadores só verão as quests que eles tem nível para fazer. De resto não tem muito o que mexer, só se quiser reduzir ou aumentar a quantidade de espaço entre as linhas, mas ai é da preferência de cada um. Caso queira retirar a verificação de nível do jogador (pare verem todas as quests) só mudar isso:
     
    for i, _ in pairs (quests) do if (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) < 1) then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" elseif (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) > 1) quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end Para isso:
    for i, _ in pairs (quests) do if getPlayerStorageValue(cid, quests[i].storage) < 1 then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" else quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end  
    Se fizer tudo corretamente, é para aparecer essa janela com as informações e nível da(s) quest(s):
     

     
    Essa janela é criada na função doShowTextDialog, e o segundo parâmetro dela é um item que aparece como ícone, geralmente deixam 0 (e recomendo deixar 0 como padrão), mas tem base que o id do item 0 aparece como algum item do jogo (as vezes montanhas ou outros itens de ambiente), então deixei um blackboard, até para ficar mais coerente hehe. Você também pode criar um item para representar essa janela, mas vai da preferência e criatividade de cada um. 
     
    Se você tiver source, pode até criar uma janela com título de "Quests" para ficar mais bonito a interface, mas vai de cada um.
     
    OBS: Em alguns servidores pode ser que dê crash na distro por conta do item passado no segundo parâmetro da função doShowTextDialog(cid, id_item, texto), precisa ficar atento nisso.
     
     
    Qualquer dúvida só perguntar!
     
    Abraços e fiquem com Deus!
  23. Amei
    Yan Oliveira recebeu reputação de GamerGoiano em Quest Log em Janela   
    Olá amigos do Xtibia, venho trazer um tutorial simples, mas interessante, que exibe uma caixa de diálogo com texto contendo todas as quests do seu servidor.
     
    Atenção: Testado somente em TFS 0.3/0.4
     
    Vamos lá!
     
    Vá em Data/Talkactions/Scripts e crie um arquivo.lua chamado quest_log.lua e adicione o script:
     
    ---------------- QUEST LOG BY YAN18 ----------------- -- NOME DA QUEST NO ÍNDICE, O NÍVEL E STORAGE NO VALOR -- local quests = { ["Cerulean City"] = {level = 30, storage = 32500}, ["Fire Stone"] = {level = 50, storage = 32501}, ["Boost Machine"] = {level = 100, storage = 32502} } function onSay(cid, words, param) local quest_completada = "- Quests completadas: \n\n" local quest_incompleta = "\n- Quests não completadas: \n\n" for i, _ in pairs (quests) do if (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) < 1) then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" elseif (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) >= 1) then quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end if quest_completada == "- Quests completadas: \n\n" then quest_completada = quest_completada .. " Nenhuma quest foi completada ainda. \n\n" elseif quest_incompleta == "\n- Quests não completadas: \n\n" then quest_incompleta = quest_incompleta .. " Todas as quests foram completadas." end local quest = quest_completada .. quest_incompleta return doShowTextDialog(cid, 1811, quest) end  
    Agora abra o talkactions.xml que fica em Data/Talkactions/talkctions.xml e adicione a tag:
    <talkaction words="!quest" event="script" value="quest_log.lua"/> Deixei o comando !quest ali em words na tag xml, mas você pode colocar outro comando de sua preferência.
     
    Explicação: Adicione todas as quests do servidor na tabela quests, colocando o nome dela como índice, o level e storage (preste bem atenção para colocar a storage correta) como valores. Em caso de dúvidas, só seguir o exemplo que fiz. Também fiz verificação para ver se todas as quests do jogo (que você colocar na tabela) foram feitas ou não, e também fiz verificação de nível do jogador por quest, ou seja, os jogadores só verão as quests que eles tem nível para fazer. De resto não tem muito o que mexer, só se quiser reduzir ou aumentar a quantidade de espaço entre as linhas, mas ai é da preferência de cada um. Caso queira retirar a verificação de nível do jogador (pare verem todas as quests) só mudar isso:
     
    for i, _ in pairs (quests) do if (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) < 1) then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" elseif (getPlayerLevel(cid) >= quests[i].level) and (getPlayerStorageValue(cid, quests[i].storage) > 1) quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end Para isso:
    for i, _ in pairs (quests) do if getPlayerStorageValue(cid, quests[i].storage) < 1 then quest_incompleta = quest_incompleta .. "* " ..i.. " - Nível: " ..quests[i].level.. " \n" else quest_completada = quest_completada .."* " ..i.. " - Nível: " ..quests[i].level.. " \n" end end  
    Se fizer tudo corretamente, é para aparecer essa janela com as informações e nível da(s) quest(s):
     

     
    Essa janela é criada na função doShowTextDialog, e o segundo parâmetro dela é um item que aparece como ícone, geralmente deixam 0 (e recomendo deixar 0 como padrão), mas tem base que o id do item 0 aparece como algum item do jogo (as vezes montanhas ou outros itens de ambiente), então deixei um blackboard, até para ficar mais coerente hehe. Você também pode criar um item para representar essa janela, mas vai da preferência e criatividade de cada um. 
     
    Se você tiver source, pode até criar uma janela com título de "Quests" para ficar mais bonito a interface, mas vai de cada um.
     
    OBS: Em alguns servidores pode ser que dê crash na distro por conta do item passado no segundo parâmetro da função doShowTextDialog(cid, id_item, texto), precisa ficar atento nisso.
     
     
    Qualquer dúvida só perguntar!
     
    Abraços e fiquem com Deus!
  24. Upvote
    Yan Oliveira recebeu reputação de Kackzok em Iniciar Servidor Automático Após Shutdown   
    Distro Restarter by Yan18
     
    Olá caros amigos do Xtibia, hoje irei ensinar como reiniciar a distro do server automaticamente após um shutdown (no sistema operacional Windows). Decidi fazer esse tutorial após ver muitos pedidos sobre isso, não sei se já existe algum tutorial sobre isso aqui no fórum, mas decidi criar junto com um script que exibe uma mensagem para o server todo alertando que o servidor será reiniciado após X minutos.
     
    Para isso, irei trabalhar com um arquivo .bat do Windows, para que ele sempre execute a distro quando não estiver sendo executada. 
     
    ATENÇÃO: Leia isso antes de seguir o tutorial! Esse método só vai funcionar se a sua distro for em interface GUI! Se for por prompt (linha de comando) não irá funcionar porque a distro já será executada em prompt.
     
    Começo do Tutorial
     
     
    - Evento Shutdown
     
    Para começar, vamos criar um evento global para dar shutdown e exibir uma mensagem de aviso para todos os jogadores que o servidor será reiniciado, para ficar mais sofisticado e bonito o processo. E eles estarem ciente, assim dá tempo de todos irem para um local seguro!
     
    Agora vá em Data/Globalevents/Scripts e crie o arquivo shutdown.lua e insira o código dentro:
     
    TFS 0.3/0.4
    function avisoShutdown(minutos) local minutos_shutdown = 1 -- VARIÁVEL PARA DAR UM TEMPO (EM MINUTOS) PARA SALVAR O SERVIDOR E DEPOIS DAR SHUTDOWN EM SEGUIDA if minutos > 0 then doBroadcastMessage("O servidor será reiniciado em " ..minutos) addEvent(avisoShutdown, 60000, cid, minutos - 1) else doSaveServer() addEvent(doShutdown, minutos_shutdown * 60000) return true end end function onTime() avisoShutdown(5) -- MINUTOS MANDAR MENSAGEM DE AVISO PARA SALVAR E DAR SHUTDOWN end  
    TFS 1.0 / 1.+
    function avisoShutdown(minutos) local minutos_shutdown = 1 -- VARIÁVEL PARA DAR UM TEMPO (EM MINUTOS) PARA SALVAR O SERVIDOR E DEPOIS DAR SHUTDOWN EM SEGUIDA if minutos > 0 then if minutos > 1 then broadcastMessage("O servidor será reiniciado em " ..minutos.. " minutos.") else broadcastMessage("O servidor será reiniciado em " ..minutos.. " minuto.") end addEvent(avisoShutdown, 60000, minutos - 1) else saveServer() addEvent(Game.setGameState(GAME_STATE_SHUTDOWN), minutos_shutdown * 60000) return true end end function onTime(interval) avisoShutdown(5) -- MINUTOS MANDAR MENSAGEM DE AVISO PARA SALVAR E DAR SHUTDOWN end Explicação: O script vai fazer um contagem regressiva de minutos (pelo valor definido no parâmetro passado na função avisoShutdown) e depois ele irá ter um delay pelo valor da variável minutos_shutdown. Parece confuso duas variáveis de minutos né? Mas a variável minutos_shutdown é um "delay" para dar tempo de salvar e depois efetuar o shutdown, pois tem servidor que o mapa é grande, tem muitos jogadores e itens, então pode demorar um pouco, ai é só mudar o valor na variável. Está o valor 1 por padrão. E na função chamada pelo evento onTime você coloca os minutos para o player ver os minutos restantes para o servidor ser reiniciado.
     
    Agora, abra o arquivo globalevents.xml e adicione a tag:
    <globalevent name="shutdown_server" time="12:00" event="script" value="shutdown.lua"/> Em time coloque o horário que deseja executar o evento para fazer o shutdown.
     
    Agora acabamos a parte do evento e vamos para a parte do reiniciador!
     
    - PROMPT (Arquivo .Bat)
     
    Agora iremos criar o arquivo bat para reiniciar a distro. Vá no bloco de notas ou no notepad++ (de sua preferência) e insira o seguinte script dentro:
    title Reinicializador da Distro echo --------- MENSAGEM QUANDO INICIAR A DISTRO ------------ echo. echo Status: INICIANDO O SERVIDOR... echo. :begin TFS.exe echo --------- MENSAGEM QUANDO DESLIGAR OU REINICIAR A DISTRO COM O ARQUIVO BAT ABERTO ------------ echo. echo Aviso: O SERVIDOR FOI DESLIGADO OU SERÁ REINICIADO. echo. echo Status: O SERVIDOR ESTÁ SENDO REINICIADO! echo. goto begin :goto begin Salve esse script (de preferência com um nome sem espaço) com a extensão .bat. Eu recomendo Restarter, mas fica por sua preferência!
     
    OBS: Salve o arquivo com a codificação UTF-8, por padrão já vem, mas caso não venha é só colocar!

     
     
    Explicação:
    @echo off O "echo off" Oculta informações e o código executado pelo sistema, e o "@echo" oculta a interface durante a execução do programa. É possível juntar os dois modos, assim como fiz acima.
    title Nessa parte você coloca o título do arquivo bat em seguida da palavra reservada title, que fica na parte superior da interface. Só seguir o exemplo anterior da criação do arquivo. 
    OBS: No título você pode colocar espaço a vontade.
    echo Aqui é onde vai aparecer as mensagens na interface, pode colocar qualquer caractere desejado, pode usar pontos, acentos (acentos acontecerá algo de errado que será explica mas para o fim do tutorial.) e o que desejar. E para dar uma quebra de linha, é só colocar ponto depois do echo: echo. 
    begin É onde começa a executar o procedimento (executar a distro). Mas ai você pergunta: "Mas e as linhas anteriores com mensagens?". Mas a resposta é que as linhas anteriores não executam o programa, e sim inserem mensagem assim que executamos o arquivo bat (ressaltando que quando abrimos o arquivo bat ele inicia a distro, porém só vai reiniciar a distro sempre que der shutdown ou crashar enquanto o arquivo bat estiver aberto).
    TFS.exe Em baixo do ":begin" vai ter TFS.exe, e nessa linha é onde coloca o nome do executável (distro).
    OBS: Evite colocar nome da distro com espaço, ele funciona, mas para evitar problemas, deixe junto!
    goto begin E por fim temos o goto begin, a palavra reservada goto faz um pulo para o que colocar na frente dela, ou seja, depois que executar tudo que está acima dela, vai ir para o que declara na frente, no nosso caso, o begin (irá fazer um loop de reiniciar sempre que a distro estiver desligada no nosso caso enquanto o arquivo bat estiver rodando).
     
    Beleza Yan, acabamos?
     
    Ainda não acabamos! Tenha calma, se você chegou até aqui, vai aguentar até o fim!
     
    Agora iremos executar o arquivo bat (lembrando que se quer usar o auto restarter, não pode abrir a distro antes do arquivo bat, se não vai dar erro de distro já aberta, porque o arquivo irá abrir novamente).
     
    Mas antes de rodar, não se esqueça de colocar o arquivo bat no mesmo diretório (pasta) da distro, tem que ficar junto senão não vai funcionar.
     
    Feito isso, execute o arquivo bat, se der tudo certo e seguiu os passos corretamente, irá aparecer assim seguindo nossa criação:

     
    E a distro irá iniciar logo em seguida.
     
    Agora vamos testar um shutdown na distro (lembre-se de deixar o prompt do arquivo bat aberto!):
     

     
    Agora você vai falar, "Funcionou!! Acabamos?", sim de fato funcionou, porém, se repara as mensagens com acento estão "bugadas". Isso se deve ao fato de que por padrão não lê acento (Windows foi criado na língua inglesa). Então, para funcionar precisaremos ir na primeira linha do código do arquivo bat e colocar:
    chcp 65001 off Pois essa linha permite acentuação (lembrando de permanecer a codificação UTF-8 ainda).
     
    Então o script ficará assim:
    chcp 65001 @echo off echo. title Reinicializador da Distro echo --------- MENSAGEM QUANDO INICIAR A DISTRO ------------ echo. echo Status: INICIANDO O SERVIDOR... echo. :begin TFS.exe echo --------- MENSAGEM QUANDO DESLIGAR OU REINICIAR A DISTRO COM O ARQUIVO BAT ABERTO ------------ echo. echo Aviso: O SERVIDOR FOI DESLIGADO OU SERÁ REINICIADO. echo. echo Status: O SERVIDOR ESTÁ SENDO REINICIADO! echo. goto begin :goto begin  
    Ficando então o script do arquivo bat:

     
    Agora temos o caminho do diretório do executável e uma mensagem do sistema alegando que foi ativado esse comando. Se fizer tudo certo é para aparecer assim!
     
    E agora vamos testar o shutdown:

     
    Como podemos ver executou corretamente e leu os caracteres com acento.
     
    Agora vem a pergunta: "Acabou?", e a resposta é... Sim, acabou! Lembrando que você pode encerrar a distro manualmente (fechando) que o arquivo bat irá reiniciar, não precisa depender só do evento shutdown, mas não esqueça de deixar o restarter aberto.
     
    Obrigado por ter chegado até aqui e espero que te ajude o tutorial. Qualquer dúvida só perguntar.
     
    Logo estarei preparando um tutorial desses para Linux!
     
    Abraços e fiquem com Deus!
  25. Upvote
    Yan Oliveira recebeu reputação de ADSFGDFHFGHFGJH em Iniciar Servidor Automático Após Shutdown   
    Distro Restarter by Yan18
     
    Olá caros amigos do Xtibia, hoje irei ensinar como reiniciar a distro do server automaticamente após um shutdown (no sistema operacional Windows). Decidi fazer esse tutorial após ver muitos pedidos sobre isso, não sei se já existe algum tutorial sobre isso aqui no fórum, mas decidi criar junto com um script que exibe uma mensagem para o server todo alertando que o servidor será reiniciado após X minutos.
     
    Para isso, irei trabalhar com um arquivo .bat do Windows, para que ele sempre execute a distro quando não estiver sendo executada. 
     
    ATENÇÃO: Leia isso antes de seguir o tutorial! Esse método só vai funcionar se a sua distro for em interface GUI! Se for por prompt (linha de comando) não irá funcionar porque a distro já será executada em prompt.
     
    Começo do Tutorial
     
     
    - Evento Shutdown
     
    Para começar, vamos criar um evento global para dar shutdown e exibir uma mensagem de aviso para todos os jogadores que o servidor será reiniciado, para ficar mais sofisticado e bonito o processo. E eles estarem ciente, assim dá tempo de todos irem para um local seguro!
     
    Agora vá em Data/Globalevents/Scripts e crie o arquivo shutdown.lua e insira o código dentro:
     
    TFS 0.3/0.4
    function avisoShutdown(minutos) local minutos_shutdown = 1 -- VARIÁVEL PARA DAR UM TEMPO (EM MINUTOS) PARA SALVAR O SERVIDOR E DEPOIS DAR SHUTDOWN EM SEGUIDA if minutos > 0 then doBroadcastMessage("O servidor será reiniciado em " ..minutos) addEvent(avisoShutdown, 60000, cid, minutos - 1) else doSaveServer() addEvent(doShutdown, minutos_shutdown * 60000) return true end end function onTime() avisoShutdown(5) -- MINUTOS MANDAR MENSAGEM DE AVISO PARA SALVAR E DAR SHUTDOWN end  
    TFS 1.0 / 1.+
    function avisoShutdown(minutos) local minutos_shutdown = 1 -- VARIÁVEL PARA DAR UM TEMPO (EM MINUTOS) PARA SALVAR O SERVIDOR E DEPOIS DAR SHUTDOWN EM SEGUIDA if minutos > 0 then if minutos > 1 then broadcastMessage("O servidor será reiniciado em " ..minutos.. " minutos.") else broadcastMessage("O servidor será reiniciado em " ..minutos.. " minuto.") end addEvent(avisoShutdown, 60000, minutos - 1) else saveServer() addEvent(Game.setGameState(GAME_STATE_SHUTDOWN), minutos_shutdown * 60000) return true end end function onTime(interval) avisoShutdown(5) -- MINUTOS MANDAR MENSAGEM DE AVISO PARA SALVAR E DAR SHUTDOWN end Explicação: O script vai fazer um contagem regressiva de minutos (pelo valor definido no parâmetro passado na função avisoShutdown) e depois ele irá ter um delay pelo valor da variável minutos_shutdown. Parece confuso duas variáveis de minutos né? Mas a variável minutos_shutdown é um "delay" para dar tempo de salvar e depois efetuar o shutdown, pois tem servidor que o mapa é grande, tem muitos jogadores e itens, então pode demorar um pouco, ai é só mudar o valor na variável. Está o valor 1 por padrão. E na função chamada pelo evento onTime você coloca os minutos para o player ver os minutos restantes para o servidor ser reiniciado.
     
    Agora, abra o arquivo globalevents.xml e adicione a tag:
    <globalevent name="shutdown_server" time="12:00" event="script" value="shutdown.lua"/> Em time coloque o horário que deseja executar o evento para fazer o shutdown.
     
    Agora acabamos a parte do evento e vamos para a parte do reiniciador!
     
    - PROMPT (Arquivo .Bat)
     
    Agora iremos criar o arquivo bat para reiniciar a distro. Vá no bloco de notas ou no notepad++ (de sua preferência) e insira o seguinte script dentro:
    title Reinicializador da Distro echo --------- MENSAGEM QUANDO INICIAR A DISTRO ------------ echo. echo Status: INICIANDO O SERVIDOR... echo. :begin TFS.exe echo --------- MENSAGEM QUANDO DESLIGAR OU REINICIAR A DISTRO COM O ARQUIVO BAT ABERTO ------------ echo. echo Aviso: O SERVIDOR FOI DESLIGADO OU SERÁ REINICIADO. echo. echo Status: O SERVIDOR ESTÁ SENDO REINICIADO! echo. goto begin :goto begin Salve esse script (de preferência com um nome sem espaço) com a extensão .bat. Eu recomendo Restarter, mas fica por sua preferência!
     
    OBS: Salve o arquivo com a codificação UTF-8, por padrão já vem, mas caso não venha é só colocar!

     
     
    Explicação:
    @echo off O "echo off" Oculta informações e o código executado pelo sistema, e o "@echo" oculta a interface durante a execução do programa. É possível juntar os dois modos, assim como fiz acima.
    title Nessa parte você coloca o título do arquivo bat em seguida da palavra reservada title, que fica na parte superior da interface. Só seguir o exemplo anterior da criação do arquivo. 
    OBS: No título você pode colocar espaço a vontade.
    echo Aqui é onde vai aparecer as mensagens na interface, pode colocar qualquer caractere desejado, pode usar pontos, acentos (acentos acontecerá algo de errado que será explica mas para o fim do tutorial.) e o que desejar. E para dar uma quebra de linha, é só colocar ponto depois do echo: echo. 
    begin É onde começa a executar o procedimento (executar a distro). Mas ai você pergunta: "Mas e as linhas anteriores com mensagens?". Mas a resposta é que as linhas anteriores não executam o programa, e sim inserem mensagem assim que executamos o arquivo bat (ressaltando que quando abrimos o arquivo bat ele inicia a distro, porém só vai reiniciar a distro sempre que der shutdown ou crashar enquanto o arquivo bat estiver aberto).
    TFS.exe Em baixo do ":begin" vai ter TFS.exe, e nessa linha é onde coloca o nome do executável (distro).
    OBS: Evite colocar nome da distro com espaço, ele funciona, mas para evitar problemas, deixe junto!
    goto begin E por fim temos o goto begin, a palavra reservada goto faz um pulo para o que colocar na frente dela, ou seja, depois que executar tudo que está acima dela, vai ir para o que declara na frente, no nosso caso, o begin (irá fazer um loop de reiniciar sempre que a distro estiver desligada no nosso caso enquanto o arquivo bat estiver rodando).
     
    Beleza Yan, acabamos?
     
    Ainda não acabamos! Tenha calma, se você chegou até aqui, vai aguentar até o fim!
     
    Agora iremos executar o arquivo bat (lembrando que se quer usar o auto restarter, não pode abrir a distro antes do arquivo bat, se não vai dar erro de distro já aberta, porque o arquivo irá abrir novamente).
     
    Mas antes de rodar, não se esqueça de colocar o arquivo bat no mesmo diretório (pasta) da distro, tem que ficar junto senão não vai funcionar.
     
    Feito isso, execute o arquivo bat, se der tudo certo e seguiu os passos corretamente, irá aparecer assim seguindo nossa criação:

     
    E a distro irá iniciar logo em seguida.
     
    Agora vamos testar um shutdown na distro (lembre-se de deixar o prompt do arquivo bat aberto!):
     

     
    Agora você vai falar, "Funcionou!! Acabamos?", sim de fato funcionou, porém, se repara as mensagens com acento estão "bugadas". Isso se deve ao fato de que por padrão não lê acento (Windows foi criado na língua inglesa). Então, para funcionar precisaremos ir na primeira linha do código do arquivo bat e colocar:
    chcp 65001 off Pois essa linha permite acentuação (lembrando de permanecer a codificação UTF-8 ainda).
     
    Então o script ficará assim:
    chcp 65001 @echo off echo. title Reinicializador da Distro echo --------- MENSAGEM QUANDO INICIAR A DISTRO ------------ echo. echo Status: INICIANDO O SERVIDOR... echo. :begin TFS.exe echo --------- MENSAGEM QUANDO DESLIGAR OU REINICIAR A DISTRO COM O ARQUIVO BAT ABERTO ------------ echo. echo Aviso: O SERVIDOR FOI DESLIGADO OU SERÁ REINICIADO. echo. echo Status: O SERVIDOR ESTÁ SENDO REINICIADO! echo. goto begin :goto begin  
    Ficando então o script do arquivo bat:

     
    Agora temos o caminho do diretório do executável e uma mensagem do sistema alegando que foi ativado esse comando. Se fizer tudo certo é para aparecer assim!
     
    E agora vamos testar o shutdown:

     
    Como podemos ver executou corretamente e leu os caracteres com acento.
     
    Agora vem a pergunta: "Acabou?", e a resposta é... Sim, acabou! Lembrando que você pode encerrar a distro manualmente (fechando) que o arquivo bat irá reiniciar, não precisa depender só do evento shutdown, mas não esqueça de deixar o restarter aberto.
     
    Obrigado por ter chegado até aqui e espero que te ajude o tutorial. Qualquer dúvida só perguntar.
     
    Logo estarei preparando um tutorial desses para Linux!
     
    Abraços e fiquem com Deus!
  • Quem Está Navegando   0 membros estão online

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