Ir para conteúdo
Close

REFORMULAMOS A SEÇÃO DE CLASSIFICADOS! - Crie grátis os seus anúncios de procura e oferta de serviços e produtos relacionados ao OTServ! - Acesse através do nosso menu ou clique aqui e confira já!

Tadelho

Membro
  • Total de itens

    55
  • Registro em

  • Última visita

Sobre Tadelho

  • Rank
    Ferreiro

Informação de Perfil

  • Genero
    Masculino
  • Eu sou
    Designer

Últimos Visitantes

594 visualizações
  1. Conforme tive uma dúvida outro dia, consegui obter uma solução satisfatória e, sabendo que pode ser a dúvida de mais gente, resolvi compartilhar na forma deste pequeno tutorial. A ideia é muito simples: fazer com que uma spell de área atinga apenas alguns alvos conforme uma característica específica. Isso pode ser bastante útil para diversas ideias, além do script base servir para tantos outros efeitos interessantes. Atenção, fiz os scripts para: TFS 0.4.0 Teremos como base para esse exemplo a magia "divine caldera", o famoso "exevo mas san". Nela teremos o seguinte script: local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA) setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 5, 5, 4, 6) local area = createCombatArea(AREA_CIRCLE3X3) setCombatArea(combat, area) function onCastSpell(cid, var) return doCombat(cid, combat, var) end Desta forma, a magia atingirá todos os alvos em sua área de alcance. Mas queremos mudar isso, queremos que ela atinja alvos específicos, e aqui entram algumas ideias, por exemplo: podemos fazer com que ela acerte apenas players de um determinado level, players de uma determinada vocação, players com um determinado access, ou mesmo uma storage, ou ainda, como no exemplo que darei a seguir, fazer com que a magia acerte apenas alvos com um determinado nome (no caso, serão criaturas e não players). Para isso, utilizaremos uma função, "onTargetCreature(cid, target)" e depois a chamaremos como parâmetro de um "setCombatCallback(combat, key, function_name)". Na função onTargetCreature nós faremos a verificação desejada. Por exemplo, no código a seguir eu quero que a minha spell atinja apenas criaturas com o nome de "rat" ou "cave rat", então ficaria assim: function onTargetCreature(cid, target) local creatures = {"rat", "cave rat"} if isMonster(target) and isInArray(creatures, getCreatureName(target)) then doTargetCombatHealth(cid, target, type, min, max, effect) end end Traduzindo: eu criei uma tabela local com os nomes desejados, verifiquei se o alvo era um monstro e se o nome do monstro constava na minha tabela recém criada. Sendo verdadeiro, acionei a função doTargetCombatHealth(cid, target, type, min, max, effect). -- Lembrando que conforme o tipo da sua magia você vai alterar os parâmetros dessa função para que ela tenha as animações e o dano compatíveis com o seu gosto/objetivo. Outro detalhe é que nesse trecho de código acima é que é feita a verificação que eu desejo. Eu poderia ao invés disso verificar se é um jogador e se a vocação dele tem o id 1 ou 2, por exemplo. Ficaria: function onTargetCreature(cid, target) local vocations = {1, 2} if isPlayer(target) and isInArray(vocations, getPlayerVocation(target)) then doTargetCombatHealth(cid, target, type, min, max, effect) end end Ou verificar um level, para que a magia só funcione em alvos acima do level X, etc. Exemplo: function onTargetCreature(cid, target) local level = 80 if isPlayer(target) and getPlayerLevel(target) >= 80 then doTargetCombatHealth(cid, target, type, min, max, effect) end end Feita a função, faremos aquilo que mencionei: a chamaremos como parâmetro da função "setCombatCallback" para o nosso "combat". Fica assim: setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") Feito isso, pronto! Basta chamarmos a spell normalmente. Exemplo de tudo pronto para uma magia "exevo mas san" que só acerte os ratos e tira de 10 a 20 de vida: local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA) local area = createCombatArea(AREA_CIRCLE3X3) setCombatArea(combat, area) function onTargetCreature(cid, target) local creatures = {"rat", "cave rat"} if isMonster(target) and isInArray(creatures, getCreatureName(target)) then doTargetCombatHealth(cid, target, COMBAT_HOLYDAMAGE, -10, -20, CONST_ME_HOLYAREA) end end setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") function onCastSpell(cid, var) return doCombat(cid, combat, var) end Agora é com a criatividade de vocês! Até a próxima!
  2. @KillerWatts O problema é que eu precisaria saber qual a fórmula de dano que você está utilizando aí no seu servidor... supondo que você esteja utilizando a fórmula original do TFS 0.3.6, ficaria assim: local level = getPlayerLevel(cid) local attack = x -- insira o valor de atk que você quer simular local distance = getPlayerSkill(cid, SKILL_DISTANCE, false) local min = math.ceil(level * 0.2) local max = math.ceil((2 * (attack * (distance + 5.8) / 25 + (level - 1) / 10.)) OBS1: Você só precisa substituir ali no lugar do "x" o atk que você quer simular, por exemplo, "65" (igual uma assassin star), ou "300", enfim, o que você quiser. OBS2: Isso estará simulando golpes sempre no modo "full attack".
  3. Cara, pelo que entendi você não está calculando o dano por uma fórmula, está apenas configurando ali na primeira linha do código os valores para o dano mínimo e o dano máximo: "min, max". Nesse caso, você pode simplesmente alterar isso para a fórmula desejada. Por exemplo: local level = getPlayerLevel(cid) local distance = getPlayerSkill(cid, SKILL_DISTANCE, false) local min = (level * 1 + distance * 2.5) - 15 local max = (level * 2 + distance * 3.2) + 30 Sacou a ideia? Ali é só um exemplo, você colocaria a fórmula que você quer, seja ela qual for.
  4. @EDIT -- EU MESMO CONSEGUI SOLUCIONAR O CASO! VEJA EM: Diga em poucas palavras a base utilizada (Nome do servidor ou nome do website). TFS 0.4.0 Qual erro está surgindo/O que você procura? Fala, pessoal. Gostaria que vocês me dessem ideias de como seria possível fazer uma spell de área que só dê dano nas criaturas com um determinado nome. Vamos tomar como exemplo a magia divine caldera (exevo mas san, no código abaixo), e apenas as criaturas "rat" e "cave rat". Como eu faria para que essa magia só desse dano nos ratos e ignorasse os demais monstros? Eu preciso de alguma forma verificar o nome de todas as criaturas afetadas na área de atuação da magia e executar um doCombat() ou um doAddCreatureHealth() especificamente nelas, mas não estou conseguindo imaginar como fazer isso. Alguém sugere alguma ideia? Vamos começar com um esboço... a magia normal e uma tabela com a lista de criaturas. Você tem o código disponível? Se tiver publique-o aqui: local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA) setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 5, 5, 4, 6) local area = createCombatArea(AREA_CIRCLE3X3) setCombatArea(combat, area) local creatureList = {'rat', 'cave rat'} function onCastSpell(cid, var) return doCombat(cid, combat, var) end Daqui para frente, que ideias vocês sugerem? Como eu faço um getCreatureName() dessas criaturas na área de ação da magia? Outra ideia: seria preciso criar mais uma tabela (por exemplo: "affectedList = {}"), a princípio vazia, e inserir o creature.uid dessas criaturas checadas, certo? Quem puder dar uma força, agradeço!
  5. @leozincorsair Substitui o seguinte: local chance1, chance2, chance3 = math.random(1,100) Por: local chance1 = math.random(1,100) local chance2 = math.random(1,100) local chance3 = math.random(1,100) Testei no TFS 0.4.0 e funcionou.
  6. Fala, pessoal! Algum de vocês tem sprites diferentes de dragões além das do próprio jogo ou sabe onde eu poderia encontrar alguma? Estava querendo fazer alguns novos dragões... andei procurando mas só encontrei essa: Se vocês souberem de alguma que possam compartilhar, eu agradeço!
  7. Sim, eu entendi isso. O problema é que com essa disposição de 50%-30%-10%, em 10% das vezes não acontecerá do jogador ganhar qualquer um dos itens listados. Mesmo que o sorteio dos itens seja independente, ainda há o risco também de nenhum dos itens ser sorteado, então eu assumi que ele simplesmente perderá em 10% das vezes. @leozincorsair Sorteio para ganhar um item ou outro, 1° script. Sorteio independente de cada item, 2° script. -- CONFIGURAÇÕES -- PR = {11413, 11414, 11467} -- ID dos itens que será sorteado. money = {9970, 'Royal Coins'} -- ID do crystal coin e nome. count = 50 -- Quantidade de dinheiro. cast = "[Cassino]" function onUse(cid, item, fromPosition, itemEx, toPosition) local chance = math.random(1,100) local CB = { doSendAnimatedText, doSendMagicEffect, doPlayerAddItem, doPlayerRemoveItem} if not CB[4](cid, money[1], count) then doPlayerSendCancel(cid, "Você precisa de "..count.." "..money[2].." pra apostar.") CB[2](getThingPos(cid), CONST_ME_POFF) else if chance <= 50 then CB[3](cid, PR[1], 2) doBroadcastMessage(""..cast.." Você Obteve um "..getItemNameById(PR[1]).."", 22) elseif chance > 50 and <= 80 then CB[3](cid, PR[2], 1) doBroadcastMessage(""..cast.." Você Obteve um "..getItemNameById(PR[2]).."", 22) elseif chance > 80 and <= 90 then CB[3](cid, PR[3], 1) doBroadcastMessage(""..cast.." Você Obteve um "..getItemNameById(PR[3]).."", 22) elseif chance > 90 then doBroadcastMessage(""..cast.." Você perdeu sua aposta.", 22) return TRUE end return TRUE end -- CONFIGURAÇÕES -- PR = {11413, 11414, 11467} -- ID dos itens que será sorteado. money = {9970, 'Royal Coins'} -- ID do crystal coin e nome. count = 50 -- Quantidade de dinheiro. cast = "[Cassino]" function onUse(cid, item, fromPosition, itemEx, toPosition) local chance1, chance2, chance3 = math.random(1,100) local CB = { doSendAnimatedText, doSendMagicEffect, doPlayerAddItem, doPlayerRemoveItem} if not CB[4](cid, money[1], count) then doPlayerSendCancel(cid, "Você precisa de "..count.." "..money[2].." pra apostar.") CB[2](getThingPos(cid), CONST_ME_POFF) else if chance1 <= 50 then CB[3](cid, PR[1], 2) doBroadcastMessage(""..cast.." Você Obteve um "..getItemNameById(PR[1]).."", 22) end if chance2 <= 30 then CB[3](cid, PR[2], 1) doBroadcastMessage(""..cast.." Você Obteve um "..getItemNameById(PR[2]).."", 22) end if chance3 <= 10 then CB[3](cid, PR[3], 1) doBroadcastMessage(""..cast.." Você Obteve um "..getItemNameById(PR[3]).."", 22) end if chance1 > 50 and chance2 > 30 and chance3 > 10 then doBroadcastMessage(""..cast.." Você perdeu sua aposta.", 22) end return TRUE end return TRUE end
  8. @leozincorsair Só tem um problema: 50 + 30 + 10 = 90%. Os outros 10% serão o quê? O jogador não ganha coisa alguma?
  9. Diga a chance que você quer para cada item. {11413, 11414, 11467}. (Algo como: 11413 = 20%, 11414 = 30% e 11467 = 50%, por exemplo).
  10. @elielder duas coisas a serem consideradas: 1°, você deu reload na configuração e nos monstros após aplicar as alterações? Do contrário, elas não surtirão efeito. 2°, a probabilidade é para cada item individualmente, então digamos que você listou nesse caso 5 itens diferentes com 0,9% de chance de drop para cada. Estatisticamente, a cada 100 criaturas que o jogador matar, ele obterá "4,5" (entre 4 e 5) itens, sendo 1 de cada. Se entre esses 5 itens, como um todo, você quiser que apenas 1 item venha de loot a cada 100 criaturas, você deve colocar neles a chance de 0,2%, que no caso seria chance="200" (0,2% x 5 = 1%).
  11. @Vodkart , exatamente. Só descobri isso porque executei um serversave, até então eu não tinha recebido qualquer mensagem de erro. Consegui resolver, aparentemente! Eu simplesmente adicionei a coluna "world_id" na tabela "global_storage" e agora está funcionando. Fechei e abri o servidor e agora o script original funciona da maneira esperada e novos jogadores não ativam mais o script. O evento ocorre apenas uma vez! Ficou assim: Obrigado a todos que deram atenção ao tópico! O problema não era no script, mas sim no meu database. Obs: eu coloquei o valor padrão do world_id como "0" porque este é valor configurado no meu config.lua. Se alguém que estiver lendo isso utilizar um valor diferente, terá de adaptar.
  12. @Vodkart irei testar logo menos e já respondo. É que este padrão se repetirá muitas vezes com outras actions e conforme a história da quest avança. O valor da tabela mudará muitas vezes por isso eu estava tentando lidar com as storages com as quais sou mais familiarizado e sei que funcionam bem para gerenciar isso. A propósito, eu fiz um teste aqui: tentei executar a função pronta de "doServerSave" logo após mudar o valor da globalstorage para ver se assim salvava, e obtive uma mensagem de erro no console. setGlobalStorageValue(9000, 1) doSaveServer() Isso explicaria o porquê da globalstorage não salvar?
  13. @Vodkart, se você puder, leia a resposta anterior que deixei. Eu preciso registrar o evento do NPC ter aparecido alguma vez para seguir uma quest válida para todos os players. Não estou tendo problemas em duplicar o NPC nem nada. Enquanto o servidor está rodando o script funciona perfeitamente conforme o planejado. O problema é que ao fechar/reiniciar o servidor a globalstorage perde o valor e aí tudo recomeça, o que eu não quero que aconteça. Para solucionar isso eu preciso ou manter o valor da globalstorage, que eu não sei por que diabos some, ou atualizar o valor de uma storage dos players (o que consumiria mais processamento e memória, mas estou disposto a tentar ). Edit: vou deixar de lado o código e explicar com palavras a mecânica esperada. Talvez ajude. -> Se o NPC ainda não apareceu na história do servidor, um jogador pode fazê-lo aparecer ao pisar em um sqm. -> Se o NPC já apareceu alguma vez na história, ele não deve aparecer jamais, em hipótese alguma, mesmo que o servidor seja reiniciado e etc. Para solucionar isso eu imaginei que a globalstorage servisse, ou um registro geral em todos os players.
  14. @lordzetros o problema é que eu quero que seja um evento único ao longo de todo o jogo, entende? Esse NPC inclusive irá sumir depois de outro acontecimento. Preciso que o aparecimento dele fique registrado mesmo depois do servidor ser fechado/reiniciado. Eu pretendia utilizar as storages porque depois as usarei como andamento de uma quest que vale para todo e qualquer jogador. Eu sei que isso será possível da seguinte forma: 1) a globalstorage 9000 recebe o valor 1 e isso fica salvo, mesmo quando o servidor reiniciar (seria o ideal, acredito), ou... 2) todos os players recebem o valor 1 na player_storage 9000.
  15. Base: TFS 0.4.0 Qual erro está surgindo/O que você procura? Resolvi fazer um script para quando o player pisasse em um determinado SQM, surgisse um NPC em certo ponto do mapa. A minha ideia era que o npc surgisse apenas uma vez, então resolvi utilizar uma globalstorage para que assim que o primeiro player acionasse o evento, todos os demais não conseguissem. O script funcionou perfeitamente, e de fato apenas o primeiro player consegue trazer o NPC para o local desejado. O problema é que a global storage não fica salva no valor que eu determinei (no caso, "1") e quando o servidor é fechado/reinicia, os outros jogadores conseguem acionar o evento - o que eu não quero que aconteça. Gostaria de saber se as globalstorage permanecessem salvas, ou o que fazer para que elas fiquem salvas. Notei que no config.lua há a seguinte opção: "saveGlobalStorage = true", mas ela já está configurada como "true", então não creio que seja isso. Acho que não é a opção ideal, mas para solucionar o caso, também seria possível atualizar a storage de todos os players do servidor (ao invés de utilizar a global storage). Se alguém puder me ajudar com o script, eu agradeço. Imagino que ficaria algo como: "for (id do primeiro ao último player do banco de dados) atualizar o value de uma key da tabela player_storage", mas eu não faço ideia de como isso fica em código. Você tem o código disponível? Se tiver publique-o aqui: local pos = {x=875,y=398,z=7} -- Local do NPC function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor) if getGlobalStorageValue(9000) <= 0 then if isPlayer(cid) and getPlayerAccess(cid) < 3 and getPlayerStorageValue(cid, 9000) <= 0 then doCreateNpc("GoblinAssustadoOesteCidade", pos) end setGlobalStorageValue(9000, 1) end return true end

Open Tibia Server

Quer aprender a criar seu próprio servidor de Tibia? Então está no lugar certo, aqui você encontrará milhares de tutorias, scripts, códigos, mapas e utilitários para que você possa fazer o seu próprio servidor de Tibia partindo do zero.

Redes Sociais

Anuncie no Tibia King

Precisa de mais visibilidade em seus projetos? Quer publicidade para o seu servidor? Anuncie no Tibia King e faça sua divulgação, possuímos centenas de acessos simultâneos e milhares diários, com certeza será a sua solução! A publicação do seu anuncio é instantânea!

×