-
Total de itens
859 -
Registro em
-
Última visita
-
Dias Ganhos
22
Tudo que Skulls postou
-
[Tutorial] Formulas e Callbacks das spells – Entendendo Melhor
tópico respondeu ao Skulls de Skulls em Tutoriais de Scripting
@@felzan Compartilhava da mesma decepção, mas após esse breve aprodundamento essa semana vejo nelas um leque infinito de opções bacanas. @@Daniel Acabei de tirar elas debaixo da minha cama e coloquei na minha estante.. kkk O tutorial demorou mais do que o previsto pq nao tem recurso se rascunho, browser travou e perdi tudo. Dessa vez fiz no word antes kkkk Me perdoe por postar em spriting,eu sempre entro nela lendo rapido e achando que é scripting. Move pra mim, por favor. Obrigado pelos feedbacks. Abraços -
Ah, eu to no celular. Vou olhar direito amanha e te falo. Com bike agr ta 950 e sem 650?
-
[Tutorial] Formulas e Callbacks das spells – Entendendo Melhor
um tópico no fórum postou Skulls Tutoriais de Scripting
Boa tarde pessoal, tudo bem? Hoje resolvi fazer um tutorial sobre dois recursos muito simples e úteis na hora de criar magias diferentes, inovadoras e divertidas. Motivação Eu nunca soube fazer spells direito, achava chato e monótono, portanto nunca procurei saber mais. Essa semana, acabei fazendo um evento que a recompensa era uma magia, então quis fazer algo diferente e bonito, que fugisse um pouco do padrão (dê uma olhada em: http://www.xtibia.com/forum/topic/238734-luna-event-bonus-spell-inspirado-no-sot-01/#entry1680858). Só que, na minha busca por aprender mais sobre as spells, eu vi que é um tanto nebuloso a parte de dano e de callbacks. Os tutoriais os utilizam nos scripts demonstrativos mas falam pouco a respeito. Li muito, descobri algumas coisas no empirismo e outras nas sources do TFS e me senti motivado a reunir tudo que encontrei em um tutorial. Importante: Este não é um tutorial que vai ensinar a criar uma spell, existem milhares com esse objetivo aqui no fórum e na internet em geral. O foco aqui é estudar dois recursos que podem tornar o processo criativo de spells muito mais interessante, divertido e único, abrindo possibilidades diferentes do que simplesmente uma magia que solta um efeito e dá dano. Bom, chega de mimimi e vamos ao que interessa. Conceitos Vamos começar definindo nossos dois objetos de estudo. Fórmulas, como o próprio nome já define, são expressões matemáticas usadas para representar algum valor. No nosso caso, as fórmulas de dano das magias são expressões matemáticas que sintetizam e representam o dano da nossa magia. Callbacks são, traduzindo ao pé da letra, funções que ligam de volta. Definindo melhor, são funções que disparam ações quando determinado evento/acontecimento ocorre. Isso é, elas nos dão um retorno a um evento ou chamad. Exemplos: addEvent, é um callback muito útil que dispara com o tempo chamando uma função; onDeath é um callback que dispara quando determinada criatura morre. Uma vez entendido teoricamente o que vamos estudar, mãos a obra. Entendendo Fórmulas O controle das fórmulas de dano das spells é feito pela função setCombatFormula, cuja chamada default é mostrada abaixo: setCombatFormula(combat, formulaType, min_a, min_b, max_a, max_b, min_lvl, max_lvl, min_mlvl, max_mlvl, min_dmg, max_dmg) Combat é o objeto combate em questão, normalmente ele é instanciado no inicio dos arquivos de spells como local combat = createCombatObject(). É esse objeto que controla, a partir de seus parâmetros, toda a dinâmica das spells: efeitos, dano, área, etc. Min_a e Max_a são múltiplicadores das fórmulas de dano máximo e mínimo Min_b e Max_b são números base das fórmulas de dano máximo e mínimo Min_lvl e Max_lvl são ponderadores do level na fórmula de dano máximo e mínimo baseado em ML, dividem o lvl do player. Min_mlvl e Max_mlvl são ponderadores do magic level na fórmula de dano máximo e mínimo baseado em ML, multiplicam o ml do player. Min_dmg e Max_dmg são os limites do dano máximo e mínimo, o menor dano possível é min_dmg e o maior dano possível é max_dmg. formulaType são os diferentes tipos de fórmulas que podem ser usados, isso é, formas diferentes de como os parâmetros de dano que foram passado serão utilizados. Existem três tipos relevantes de fórmulas, existe um quarto chamado undefined ou 0. Porém nele todos os parâmetros são zero. São eles: COMBAT_FORMULA_LEVELMAGIC ou 1 Essa é a fórmula mais completa das três, utiliza de todos os parâmetros para definir o dano máximo e mínimo. Basicamente, a fórmula de dano é Dano mínimo = ((player_level / min_lvl + player_mlvl) * min_mlvl) * min_a + min_b) Dano máximo = ((player_level / max_lvl + player_mlvl * max_mlvl) * max_a + max_b) Se dano mínimo > min_dmg, então dano mínimo = min_dmg Se dano máximo > max_dmg, então dano máximo = max_dmg Considerações importantes, o valor final de dano máximo e dano mínimo deve ser negativo, o mesmo vale para os valores de min_dmg e max_dmg. Portanto, para evitar confusão vai uma dica simples: Sempre coloque min_a, min_b, max_a, max_b, min_dmg e max_dmg negativos e o restante positivo. COMBAT_FORMULA_SKILL ou 2 Mais simples que o anterior, só utiliza em seu cálculo os parâmetros min_b, max_a e max_b. Leva em consideração, como veremos, level, arma e skill (referente à arma que ele estiver empunhando) do player. Min_dmg não serve para esse caso, mas max_dmg ainda vale como no anterior. Dano mínimo = min_b Dano máximo = Dano_Calculado * max_a + max_b Se dano máximo > max_dmg, então dano máximo = max_dmg Aqui Dano_Calculado é o calculo do seu dano com a sua arma, levando em conta seu level e skills. Novamente, o valor final dos danos deve ser negativo. Aqui, use todes os valores negativos e não terá problemas. COMBAT_FORMULA_DAMAGE ou 3 A mais simples das três, leva em consideração somente min_b, que será o dano mínimo e max_b, que será o dano máximo. Para não ter problemas, use valores negativos. A respeito das fórmulas é isso. São as três fórmulas pré-definidas e seus funcionamentos. Callbacks Nosso estudo sobre callbacks vai se basear na função setCombatCallback que faz o controle dos callbacks dos objetos de combate. A seguir, a declaração da função setCombatCallback: setCombatCallback(combat, callbackType, “nome da funcao”) Vamos explicar primeiro o que essa função faz. Ela adiciona ao objeto combat especificado uma função como retorno a um determinado tipo de evento. Cada tipo de callback é referente a um evento e espera da função que você passou como parâmetro alguns parâmetros. Por exemplo, queremos adicionar um callback do tipo X com a função de retorno functionX, sabendo que callbacks do tipo x esperam funções que recebam x1, x2 e x3 como parâmetro. Então temos que definir a função functionX e criar a chamada do callback: function functionX(x1, x2, x3) code end setCombatCallback(combat, X, “functionX”) Acredito que tenham entendido um pouco do funcionamento, agora vou explicar cada tipo de callback. Temos quatro tipos, mostrados a seguir: CALLBACK_PARAM_LEVELMAGICVALUE ou 1 Esse callback é definido para disparar quando o dano é aplicado. Não consegui descobrir exatamente em que momento ele é chamado, mas, quando definido, toda vez que sua magia causa dano ele vai disparar a função para a qual foi programado. Ele é utilizado para reprogramar a forma como o dano vai ser calculado. A grande sacada aqui é que você pode definir as formulas de dano como você bem entender (levando em conta level e ml) e melhor se encaixar ao seu propósito. Esse callback espera funções que recebam os parâmetros: cid, level, maglevel e um retorno com os valores máximos e mínimos de dano. Uma definição para esse callback seria: function functionX(cid, level, maglevel) min = -maglevel*1.1 + level max = -maglevel*2.2 + level*1.1 return min, max end setCombatCallback(combat, CALLBACK_PARAM_LEVELMAGICVALUE, “functionX”) CALLBACK_PARAM_SKILLVALUE ou 2 Similar ao anterior, porém danos com base em skills, esse callback é definido para disparar quando o dano é aplicado. Não consegui descobrir exatamente em que momento ele é chamado, mas, quando definido, toda vez que sua magia causa dano ele vai disparar a função para a qual foi programado. Ele é utilizado para reprogramar a forma como o dano vai ser calculado. A grande sacada aqui é que você pode definir as formulas de dano como você bem entender (levando em conta skills, level, ataque da arma e modo de ataque) e melhor se encaixar ao seu propósito. Esse callback espera funções que recebam os parâmetros: formulaBySkill(cid, level, skill, attack, p, factor) e um retorno com os valores máximos e mínimos de dano. Uma definição para esse callback seria: function functionX (cid, level, skill, attack, factor) min = -(1.2 * (attack * (skill + 5.8) / 25 + (level - 1) / 10) / factor) max = -(2 * (attack * (skill + 5.8) / 25 + (level - 1) / 10) / factor) return min, max end setCombatCallback(combat, CALLBACK_PARAM_SKILLVALUE, “functionX”) Observação importante: no servidor que eu tenho aqui, por algum motivo sobrenatural desconhecido, tem um parâmetro nulo extra entre attack e factor. Então, se você tentar usar isso no seu servidor e der erro “factor attempt to call nil value” ou algo do tipo use isso: function functionX (cid, level, skill, attack, vazio, factor) Nos sources que eu olhei esse parâmetro não existe, não achei nada a respeito dele e ele é sempre 0. Se alguém souber o que ele significa, se ele significar algo, comente ai. CALLBACK_PARAM_TARGETTILE ou 3 Esse callback é definido para disparar quando a magia atinge cada um dos tiles definidos em sua área. Ele pode ter uma diversidade de aplicações, que envolvem customizar efeitos e ações da magia de acordo com o tile que ela atinge. Vai depender da sua criatividade, mas há um leque infinito de coisas que podem ser feitas. Exemplo: Se uma área de neve for atingida por uma magia de fogo, ela descongela e vira um tile de terra ou pedra; se em um dos tiles que a magia acertar houver um item, esse item vai para a bp do player; em determinado tipo de terreno a magia dá um dano extra; e por ai vai. Esse callback espera funções que recebam os parâmetros: cid e tile. Uma definição para esse callback seria: function onTargetTile(cid, tile) addEvent(doSendMagicEffect, x*350, tile, config.effects.hit) End setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile") CALLBACK_PARAM_TARGETCREATURE ou 4 Esse callback é parecido com o anterior. Ele é definido para disparar quando a magia atinge um criatura dentro da área de atuação dela. Ele pode ter uma diversidade de aplicações, que envolvem customizar efeitos e ações da magia de acordo com o tipo de criatura (diferentes monstros, se é player ou não, etc) que ela atinge. Vai depender da sua criatividade, mas há um leque infinito de coisas que podem ser feitas. Exemplo: Se um fire elemental for atingido por uma magia de fogo a vida dele aumenta ou um novo fire elemental surge; se o alvo da magia for um player há um dano adicional; se um monstro for atingido por essa magia ele é convencido e passa ate ajudar; e por ai vai Em uma magia como a que eu fiz para o evento luna, por exemplo, que dá vários hits ao longo de uma execução dela, cada hit dispara esse callback. Uma aplicação seria, então, a cada hit há uma chance de congelar e imobilizar o player. Esse callback espera funções que recebam os parâmetros: cid e target. Uma definição para esse callback seria: function onTargetCreature(cid, target) local chance = math.random(1, 18) if getGlobalStorageValue(5545) == -1 and isPlayer(target) and chance == 1 then registerCreatureEvent(target, "NoAtt") registerCreatureEvent(target, "NoSpell") registerCreatureEvent(target, "NoTgt") setGlobalStorageValue(config.storages.event, 1) addEvent(setGlobalStorageValue, 3000, 5545, -1) end chance = math.random(1, 15) if chance == 1 then doSendMagicEffect(getCreaturePosition(target), config.effects.hit) doCreatureSetNoMove(target, true) doSetItemOutfit(target, config.frozen_humans[math.random(1, #config.frozen_humans)], 1500) addEvent(backToMovement, 1800, target) end end setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") Bom gente, foi isso o que consegui coletar, entender e aprender sobre as fórmulas de dano e callbacks das magias. Qualquer coisa que queiram acrescentar ou corrigir, fiquem a vontade para comentar. Espero que gostem. Abraços, -
E o login? Editado, cara claro que não vai funcionar. Cometi um errrinho. Tenta esse: function onAdvance(cid, skill, oldLevel, newLevel) if getPlayerStorageValue(cid, 32001) == 1 and skill == 8 then addEvent(doChangeSpeed, 500, cid, 300) end return true end Se você tiver que criar, coloca essa tag em creaturesscripts.xml: <event type="advance" name="bike" event="script" value="bike.lua"/> Agora, abra login.lua e coloque esse if em algum lugar dentro da função onLogin: if getPlayerStorageValue(cid, 32001) == 1 then doChangeSpeed(cid, 300) end
-
Testa isso: Vai em creaturesscripts. Dentro scripts, verifique se existe um arquivo chamado advance.lua. Se existir, coloque dentro da função onAdvance o if do código abaixo. Se não existir, crie um arquivo chamado bike.lue e cole esse código dentro: function onAdvance(cid, skill, oldLevel, newLevel) if getPlayerStorageValue(cid, 32001) == 0 and skill == 8 then addEvent(doChangeSpeed, 500, cid, 300) end return true end Se você tiver que criar, coloca essa tag em creaturesscripts.xml: <event type="advance" name="bike" event="script" value="bike.lua"/> Agora, abra login.lua e coloque esse if em algum lugar dentro da função onLogin: if getPlayerStorageValue(cid, 32001) == 0 then doChangeSpeed(cid, 300) end Me retorne o resultado. Abraços,
-
Sim, isso mesmo, ela serve para fazer callbacks. Você pode colocar a função que quiser nela. Ao invés de fazer como eu fiz, você pode criar uma função X e chamar ela pelo addEvent: function X(a, b, c) end addEvent(X, tempo, a, b, c) Você pode, ainda, chamar funções pre-definidas pelo addEvent: addEvent(doSendMagicEffect, tempo, getPlayerPosition(cid), 10)
-
Aqui só sumona um, rs estranho.. Então, na verdade ele deve sumir pq, possivelmente, na funcao de chamar o poke deve ter algum "check" que verifica se vc tem algum outro sumon e remove ele antes de sumonar. O que você quer eu talvez precise fazer para um sistema que eu quero fazer, se eu fizer mesmo basta você adaptar para pokemons, ai eu posto aqui. Abraços,
-
Eu me baseei nessa sua frase, pensei no "utevo res". Eu não entendo a dinâmica do ot pokemon atual, nem as funções nem nada.. Vai ser difícil fazer então. O cd era pra ta funcionando, aqui ele fica em cd. Não pus limite de pokes, pois estando em cd ele não pode usar novamente, então só vai usar 1.. Infelizmente não tenho sources aqui para te ajudar. Uma coisa, eles ao menos atacam os targets que você ataca? rs
-
Bom cara, acho que achei uma luz pra você. Vamos lá: Antes do local combat, crie uma função function formulaByWeaponDmg(cid, level, skill, attack, p, factor) min = -(1.2 * (attack * (skill + 5.8) / 25 + (level - 1) / 10) / factor) max = -(2 * (attack * (skill + 5.8) / 25 + (level - 1) / 10) / factor) return min, max end Troca a linha do setCombatFormula por: setCombatCallback(combat, CALLBACK_PARAM_SKILLVALUE, "formulaByWeaponDmg") Pronto, agora ele vai bater baseado no dmg da arma tb. Se você quiser que seja só com base no dmg da arma, mude as fórmulas de min e max a seu gosto (attack é o ataque da arma). Com relação a ice rapier, dentro de onCastSpell coloque: if(getPlayerSlotItem(cid, CONST_SLOT_LEFT).itemid == ID_RAPIER) then doPlayerRemoveItem(cid, ID_RAPIER, 1) end Bom, espero que te ajude. Qualquer coisa me fala.
- 10 respostas
-
- fprmula spell
- dano da spell de acordo
- (e 1 mais)
-
Bem lembrado wolf, eu estava no celular ficou meio difícil fazer bonitinho. Isso evita brechas que geram aqueles warnings chatos no console! ^^ Rep
-
Bom, fiz algo aqui. Não sincronizei o poder do monstro com o level do player, isso vai dar um pouco mais de trabalho então como disse que não era necessário fiquei com preguiça. Cria um arquivo em actions/scripts chamado pokehelp.lua e coloque esse código dentro: E a tag do actions.xml: <action itemid="ID DO ITEM" script="pokehelp.lua"/> Bom é isso, testa ai e diz se tem algo a adicionar. obs: se o player morrer ou logar, o cara perde o summon.
-
Olá, Editado, ops não vi que tinha um efeito, estou no celular. Basta substituir: doTeleportThing(cid, townpos) doSendMagicEffect(getPlayerPosition(cid), 10) Por addEvent(function() doTeleportThing(cid, townpos) doSendMagicEffect(getPlayerPosition(cid), 10) end, Tempo, cid, townpos) Abraços,
-
Po calma, to te dando os créditos da ideia. Ta certo, eu fiz. Mas o que é o mundo sem as ideias? hahaha Se tudo der certo acho que esse mes sai a v2.0, inclusive se quiser me ajudar a pensar em funcionalidades para o mesmo, estou aberto à sugestões obs: Editei pra adicionar um reset nos storages toda vez que o server for iniciado, isso impede que o server salve com várias instâncias criadas e a posição '0' mude de lugar.
-
Valeu Daniel! Passei da minha época já, hoje em dia faço por hobbie quando to atoa. Tenho uma pequena ideia em mente, vou tocando ela devagarzinho em sigilo, mas o sistemas que a envolvem eu vou compartilhando com vocês! @Topic Adicionei algumas imagens e fixei um bug estranho.
-
Consegui alterar, valeu! Eu tava terminando um script de evento baseado SoT. Hoje acabei ele e comecei a implementar a sua sugestão, saiu uma V1.0, da uma olhada lá depois: http://www.xtibia.com/forum/topic/238745-instanciando-mapas-v10/ Em breve posto uma 2.0 melhorada, pq esse ta simples ainda. Abraços
-
Fala galera, tudo bem? Semana passada abri uma dúvida perguntando se alguém conhecia algum jeito de players compartilharem o mesmo espaço no mapa sem interagirem entre si, como se fossem duas dimensões separadas. Ninguém soube me dar uma solução que fizesse exatamente isso, porém, o Danihcv me deu uma luz sugerindo que eu fizesse algo próximo de um instanciador de mapa. Ou seja, uma forma de clonar automaticamente um pedaço do mapa desejado sem ter que criar mil vezes no map editor. Ainda estou trabalhando na automação do mesmo - pretendo fazer um sistema, sem ser talkaction, que sempre que for necessário ele instancia uma novo espaço para aquele mesmo mapa. Esta é uma primeira versão, feita em talkaction pois achei melhor de trabalhar num primeiro momento e testar todas as funções que eu queria adicionar, ela faz basicamente cópia de uma área do mapa. Pro projeto que eu pensei para esse sistema é suficiente que ele suporte somente mapas do mesmo tamanho e, portanto, foquei em atender esse requisito. Ainda sim, é possível trabalhar com mapas de tamanhos diferentes, desde que eles fiquem em linhas diferentes. Vamos lá Primeiramente, eu fiz um banco de funções que foram utilizadas ou serão úteis mais para frente. Em lib, crie um arquivo chamado cloneMap.lua e adicione o código abaixo: As funções estão todas funcionando, porém algumas não foram utilizadas nessa versão, ficam de bônus pra vocês. Depois disso, vá em talkactions.xml adicione a tag: <talkaction words="!clonemap" event="script" value="cmap.lua"/> Feito isso, crie dentro de scripts um arquivo chamado cmap.lua e adicione o código abaixo: Por último, vá em globalevents/scripts e abra o arquivo start.lua. Dentro da função onStartup(), antes do return true, adicione as 3 linhas a seguir: setGlobalStorageValue(5546, -1) setGlobalStorageValue(5547, -1) setGlobalStorageValue(5548, -1) Pronto. Agora algumas configurações que você deve fazer de acordo com seu mapa: emptySpaceBeginPos - É a posição no mapa onde começa a área vazia que você determinou para a criação das instâncias (Canto superior esquerdo da área, ela cresce para direita até o fim do mapa e depois para baixo e se encerra quando o mapa acaba). Storages - Storages globais onde serão armazenadas os próximos valores X, Y e Z a serem utilizados. (A progressão no eixo z ainda não foi implementada, mas a lógica é a mesma). safe_dist - É a distância entre os mapas, você pode variar de acordo com a utilização que vai dar ao mapa. Feito isso, está pronto para utilizar o Instanciador de Mapas V1.0. Como funciona: !clonemap CenterX CenterY CenterZ Side Floors Centers (X, Y e Z) são as coordenadas centrais do seu mapa (e Z é o floor mais baixo do mapa, caso ele seja multi floor, isto é o floor de valor mais alto - ex, se o seu mapa vai de z=7 até z =10, use CenterZ = 10). Side é a distância entre o centro e uma das bordas (Caso o mapa não seja quadrado, basta usar a maior distância. É possível implementar usando a mesma lógica um SideX e SideY, mas eu não tive tempo de fazê-lo). Floors é o número de andares que tem o seu mapa, se ele ocupa só um andar floor = 1, 2 floor = 2 e assim por diante. Bom é isso, espero que gostem e que seja útil para vocês. Agora vou empenhar no sistema completo, assim que terminar eu posto a versão 2.0 do instanciador com muito mais recursos. Algumas Imagens OBSERVAÇÃO IMPORTANTE Quando você utilizar o comando ingame, esteja longe da área onde o mapa será criado, senão o seu cliente irá debugar. Nada acontece, na verdade, acho que é algum problema do cliente, assim que você abre o tibia novamente tudo se estabiliza, mas é chato ficar re-abrindo então evite isso.\ Grande abraço. ps: Lembrando, novamente dos Créditos ao Danihcv pela ideia, sem o brainstorm por ele promovido no meu tópico isso não seria possível
-
Eu já sugeri isso e, segundo ele, o erro persistiu, amigo.
-
É, na verdade ele é um warning, ele não prejudica o desempenho do servidor, mas é péssimo ficar com esses erros no console, tb odeio. O estranho é que não tem motivo pra esse erro acontecer. Inclusive, aqui não acontece.. Mas fazer o que, aquelas coisas inexplicáveis da vida.
-
globalevent Luna Event + bonus spell (inspirado no sot#01)
tópico respondeu ao Skulls de Skulls em Globalevents e Spells
Muito obrigado! Quando testar me diga o que achou, Descobri hoje que em algumas versões do baiak existe um evento parecido, porém com fogo, chamado fire storm (ou algo assim). Mas eu achei a de gelo mais legal, rsrs -
Mas passado 30minutos ela volta pra posição original? Sim, o stackpos 1 refere-se ao primeiro elemento acima do piso naquela posição. Bom, você tentou mudar pra getThingFromPos? O erro se mantém? Há a possibilidade de algum monstro estar em cima da alavanca no momento que é chamado o evento? Esse erro na verdade quer dizer que o parâmetro que está sendo passado pra getThingFromPos é nulo, mas aqui funciona.. Estranho.
-
Primeiro, padroniza o script.. Usa o getThingfromPos pros 3 casos, tira esse getThingfromPosition dai, fica mais bonito, mais claro e menos confuso. Segundo, o erro está no getThingFromPosition que, ao que me parece, é relativo ao evento de "volta" das pedras e da alavanca. A alavanca está mudando de lado quando você da use nela? E está voltando depois de 30 minutos para o lado inicial? A posição {x=461, y=592, z=14, stackpos=1} é realmente a posição da alavanca?
-
globalevent Luna Event + bonus spell (inspirado no sot#01)
um tópico no fórum postou Skulls Globalevents e Spells
Fala galera, tudo bem? Então, eu li o sot#01 alguns dias atrás e achei bem legal a história no qual ele gira em torno. Tive algumas idéias e, mesmo o evento não tendo acontecido por falta de inscritos, resolvi fazer pra lembrar algumas coisas, afinal tinha uns 7 anos que não mexia com scripts para otserv. O resultado, que vou mostrar abaixo, é um evento global (mas que pode muito bem ser adaptado para uma quest ou outra finalidade). Como parte da recompensa do evento, fiz de bonus uma spell baseada na frozenOrb do whitewolf. Bom vamos lá. O Evento Basicamente é um evento estilo aquela brincadeira antiga de criança "dança das cadeiras". Como assim? Bom, na área do evento o número de espaços vazios vai ser sempre o número de players restantes no evento -1. Isso implica que, em cada turno, pelo menos um player deixará o evento. Contexto Luna é uma estrela endeusada pelos elfos e muito poderosa. De tempo em tempo ela se desperta todos os players onlines são convocados para tentarem domar a sua ira. Aquele que sobreviver à ira de Luna sem se congelar será capaz de controlar seu poder até o próximo despertar. editado: Esqueci de avisar que coloquei para ele ignorar o tile central na contagem de tiles livres pois no tile central, do meu mapa, eu coloquei um frozen starlight representando a luna e, a cada round, há uma animação na luna só para ficar bonitinho. Crie um arquivo chamado lunaevent.lua dentro de scripts e coloque o código abaixo nele: Em globalevents.xml coloque a tag: <globalevent name="Luna" interval="18000000" script="lunaevent.lua" /> A recompensa do evento é uma souvenir, um frozen starlight com o nome do vencedor do evento e x horas (no caso 5) podendo utilizar o poder de luna. Bom, eu criei uma spell para ilustrar o poder de luna e como utilizar o storage que foi preenchido para o vencedor do evento para controlar o uso de uma spell. Luna Strike Primeiramente adicione a tag abaixo em spells.xml: <instant name="Luna Strike" words="exori luna" lvl="100" manapercent="5" prem="0" range="6" casterTargetOrDirection="1" blockwalls="1" exhaustion="10000" groups="1,4000" icon="156" needlearn="0" event="script" value="attack/luna strike.lua"> <vocation id="1"/> <vocation id="2"/> <vocation id="3"/> <vocation id="4"/> <vocation id="5"/> <vocation id="6"/> <vocation id="7"/> <vocation id="8"/> </instant> Crie um arquivo chamado luna strike.lua dentro de scripts/attacks e coloque o código abaixo nele: Essa magia tem duas peculiaridades: 1. Ela tem uma chance de 1/15 para cada hit que ela dá de congelar o alvo e tornalo imóvel por 1.8 segundos, o que já está implementado nesse script e já funciona. 2. Em pvp, isso é, ao atacar um player, ela tem uma chance de 1/18 de liberar a Benção de Luna e tornar o caster imune aos ataques daquele player por 3 segundos (atenção, não são de todos os players da área, somente do player que liberou a benção de luna ao receber um hit). Para implementar essa segunda parte, precisamos ir em creature scripts. Adicione as tags abaixo a creaturescripts.xml: <event type="attack" name="NoAtt" event="script" value="luna.lua"/> <event type="cast" name="NoSpell" event="script" value="luna.lua"/> <event type="target" name="NoTgt" event="script" value="luna.lua"/> Crie um arquivo chamado luna.lua dentro de scripts e coloque o código abaixo nele: Pronto, o seu evento está configura e sua magia 'Luna Strike' poderá ser castada pelo último vencedor do mesmo. Espero que gostem, os scripts estão comentados e são bem auto-explicativos, mas qualquer dúvida podem me perguntar. Abraços, -
Porr.. eu nem sabia que eu tinha feito isso, kkkk Como desfaz?
-
Valeu, vou implementer aqui assim que eu acabar a minha ideia pro falecido concurso que ninguém participou. Eu gostaria de deixar aberto, caso alguem tenha uma solução melhor e mais próxima da minha ideia inicial, tem problema?
-
Quem Está Navegando 0 membros estão online
- Nenhum usuário registrado visualizando esta página.