Líderes
Conteúdo Popular
Exibindo conteúdo com a maior reputação em 02/11/16 em %
-
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,6 pontos
-
[Download] Remakes,pedras,paredes,escadas e Montanhas PXG
Lord Stryton e 2 outros reagiu a kaleudd por um tópico no fórum
3 pontos -
Eae Galera da Ekz Entao fiz um launcher em c# e queria compartilhar com a comunidade, o launcher e simples e serve para otclient porem tem as sources e se vc quiser editar para usar o old client fique a vontade. Link Download Launcher+Source Scan tbm fiz um video explicando como funciona obs: Para o Launcher funcionar vc prescisa por na pasta do client o .exe do launcher, o config.ini e a dll , todos estao no winrar do link de download.1 ponto
-
Hoje vou postar mais um sistema para o PDE Sistema da vez: Pokébolas com maior chance de catch dependendo do tipo do pokemon! Também vou ensinar a adicionar pokébolas Não pensei em um nome melhor, então vou chamar de: Ball System Adicionando novas Pokebolas: Pokébolas com maior chance de catch dependendo do tipo do pokemon! Créditos: @Ceetros (talvez ? ) @zipter98 (tive a ideia no tópico do @@Bluester, para acessar clique aqui)1 ponto
-
Eae XTibianos, hoje venho liberar à vocês a base Pokémon Stage, que muitos vêm me pedindo ! ( Só avisando, é PDA e contém bugs que não são difíceis de se resolver ) Bom, então vamos ao que interessa ? • Menu: ├ Informações; ├ Erros/bugs; ├ Sistemas básicos; ├ Prints; ├ Download; └ Creditos. - Informações Básicas - - Prints do Servidor - http://imgur.com/sSdRNIr http://imgur.com/YN7XYrK http://imgur.com/SlUEjo2 http://imgur.com/mydBWJx http://imgur.com/zpJLuzL http://imgur.com/pgHYFtG - Erros/Bugs - - Sistemas básicos - - Downloads - Servidor + Client (Mediafire): (Sprites do Cllient estão na pasta: Client/data/images/topbuttons/ui/854 Scan: Caso alguém possa fazer scan para mim, agradeço... Minha net está ruim. Mas creio que tenha algumas DLLs podem ser acusadas como arquivos maliciosos, mas nada que afete o PC. - Creditos - Eu - Bluester vudi Slicer GabrielTXU Jair Kevick por alguns prints Se tiver mais alguém, me avisem. Não autorizo postar esse Servidor em outro fórum. Conteúdo do XTibia.1 ponto
-
Eae XTibianos, hoje venho liberar à vocês a base PDA By Bolz, que tinha achado aqui no meu PC, com uns pokémons e tal... Bom, então aqui vai as informações: Menu: ├ Informações; ├ Erros/bugs; ├ Sistemas básicos; ├ Prints; ├ Download; └ Creditos. - Informações Básicas - - Prints do Servidor - http://imgur.com/a/FKu3y - Erros/Bugs - - Sistemas básicos - - Downloads - Servidor + Client (Google Drive): Scan: - Creditos - Eu - Bluester brun123 Bolz Slicer AnnaFeeh Drazyn Zipter98 Se tiver mais alguém, me avisem. Bom, é só isso, até a próxima.1 ponto
-
Bom, faz um tempo que eu mostrei um addon system para o meu servidor E Hoje eu adaptei ele para o PDE 3.0 e irei ensinar a por em seu servidor! Só testado em PDE 3.0, não sei se vai funcionar em algum PDA ou outro tipo de servidor. Vá em actions/scripts e crie um arquivo chamado addon.lua. Adicione isso lá: function onUse(cid, item, fromPosition, itemEx, toPosition) local addons = { [ID DO ITEM] = {pokemon= "NOME DO POKEMON" , looktype = LOOKTYPE NORMAL, fly = FLY, SE NÃO TIVER PONHA 0, ride = RIDE, SE NÃO TIVER PONHA 0, surf = SE NÃO TIVER SURF PONHA 0}, } if #getCreatureSummons(cid) > 0 then doPlayerSendCancel(cid, "Please back your pokemon.") return false end local addon = addons[item.itemid].looktype local fly = addons[item.itemid].fly local ride = addons[item.itemid].ride local surf = addons[item.itemid].surf local pb = getPlayerSlotItem(cid, 8).uid local pk = addons[item.itemid].pokemon if getItemAttribute(pb,"poke") ~= pk then doPlayerSendCancel(cid, "Sorry, you can't use this addon on this poke.") return false end if getItemAttribute(pb,"addon") >= 0 then doRemoveItem(item.uid, 1) doPlayerSendTextMessage(cid, 27, "Congratulations! Now your pokemon will use the addon.") doSetItemAttribute(pb,"addon",addon) doSetItemAttribute(pb,"addonfly",fly) doSetItemAttribute(pb,"addonride",ride) doSetItemAttribute(pb,"addonsurf",surf) return true end return true end Em actions.xml adicione: <action itemid="ID;ID;ID" event="script" value="addon.lua"/> Agora em actions/goback.lua antes de: else doPlayerSendCancel(cid, "This pokemon is fainted.") end return true end Adicione: local pk = getCreatureSummons(cid)[1] local pb = getPlayerSlotItem(cid, 8).uid local look = getItemAttribute(pb,"addon") if not look then doSetItemAttribute(pb,"addon",0) end if look > 0 then doSetCreatureOutfit(pk, {lookType = look}, -1) end Em lib/order.lua encontre: local pokemon = flys[getPokemonName(getCreatureSummons(cid)[1])] doPlayerSendTextMessage(cid, 27, "Type \"up\" or \"h1\" to fly higher and \"down\" or \"h2\" to fly lower.") doChangeSpeed(cid, -getCreatureSpeed(cid)) local speed = 500 + PlayerSpeed/5 + getSpeed(sid) * 6 * speedRate doChangeSpeed(cid, speed) setPlayerStorageValue(cid, 54844, speed) doSetCreatureOutfit(cid, {lookType = pokemon[1] + 351}, -1) doItemSetAttribute(getPlayerSlotItem(cid, 8).uid, "hp", getCreatureHealth(getCreatureSummons(cid)[1]) / getCreatureMaxHealth(getCreatureSummons(cid)[1])) doRemoveCreature(getCreatureSummons(cid)[1]) setPlayerStorageValue(cid, 17000, 1) Abaixo adicione: local addonfly= getPlayerSlotItem(cid, 8).uid local addofly = getItemAttribute(addonfly,"addonfly") if not addofly then doSetItemAttribute(addonfly,"addonfly",0) end if addofly > 0 then doSetCreatureOutfit(cid, {lookType = addofly}, -1) end Continuando em order.lua Encontre: local pokemon = rides[getPokemonName(getCreatureSummons(cid)[1])] doChangeSpeed(cid, -getCreatureSpeed(cid)) local speed = 150 + PlayerSpeed + getSpeed(sid) * 5 * speedRate doChangeSpeed(cid, speed) setPlayerStorageValue(cid, 54844, speed) doSetCreatureOutfit(cid, {lookType = pokemon[1] + 351}, -1) doItemSetAttribute(getPlayerSlotItem(cid, 8).uid, "hp", getCreatureHealth(getCreatureSummons(cid)[1]) / getCreatureMaxHealth(getCreatureSummons(cid)[1])) doRemoveCreature(getCreatureSummons(cid)[1]) setPlayerStorageValue(cid, 17001, 1) Em baixo adicione: local addonride = getPlayerSlotItem(cid, 8).uid local addoride = getItemAttribute(addonride,"addonride") if not addoride then doSetItemAttribute(addonride,"addonride",0) end if addoride > 0 then doSetCreatureOutfit(cid, {lookType = addoride}, -1) en Agora em movements/surf.lua encontre: doSetCreatureOutfit(cid, {lookType = surfs[getPokemonName(getCreatureSummons(cid)[1])].lookType + 351}, -1) doCreatureSay(cid, ""..getPokeName(getCreatureSummons(cid)[1])..", lets surf!", 1) doChangeSpeed(cid, -(getCreatureSpeed(cid))) E troque por: local addonsurf = getPlayerSlotItem(cid, 8).uid local addosurf = getItemAttribute(addonsurf,"addonsurf") if not addosurf then doSetItemAttribute(addonsurf,"addonsurf",0) doSetCreatureOutfit(cid, {lookType = surfs[getPokemonName(getCreatureSummons(cid)[1])].lookType + 351}, -1) end if addosurf > 0 then doSetCreatureOutfit(cid, {lookType = addosurf}, -1) end doCreatureSay(cid, ""..getPokeName(getCreatureSummons(cid)[1])..", lets surf!", 1) doChangeSpeed(cid, -(getCreatureSpeed(cid))) No mesmo arquivo ache: doSummonMonster(cid, pokemon) Logo abaixo adicione: local pk = getCreatureSummons(cid)[1] local balla = getPlayerSlotItem(cid, 8).uid local balladdon = getItemAttribute(balla,"addon") if not balladdon then doSetItemAttribute(balla,"addon",0) end if balladdon > 0 then doSetCreatureOutfit(pk, {lookType = balladdon}, -1) end Por ultimo em actions/order.lua encontre: doPlayerSay(cid, ""..getPokeName(getCreatureSummons(cid)[1])..", let me get down!", 1) doRegainSpeed(cid) --alterado v1.7 doRemoveCondition(cid, CONDITION_OUTFIT) Abaixo adicione: local pkjg = getCreatureSummons(cid)[1] local pkza = getPlayerSlotItem(cid, 8).uid local pkxd = getItemAttribute(pkjg,"addon") if not pkxd then doSetItemAttribute(pkza,"addon",0) elseif pkxd > 0 then doSetCreatureOutfit(pkjg, {lookType = pkxd}, -1) end Vá em creaturescripts/scripts/login.lua Troque tudo por: Créditos: @Ceetros1 ponto
-
Poke tournament (pokemon)
Silvaninho reagiu a PokeTournament por um tópico no fórum
POKE TOURNAMENT lute em arenas por fama e premiações, participe de campeonatos e faça amigos em poke tournament. Estamos online!!! Crie sua conta e faça download aqui! sobre: Em poke tournament você encontrara um novo estilo de jogo entre os Poketibias, nele você poderá controlar seu pokemon diretamente, fazer fases PVE fechadas tanto individual como em grupo, lutar PVP com seus amigos em arenas fechadas rankiado ou não, personalizar os combos dos seus pokemons e se divertir de montão com uma jogabilidade facil e competitiva! estilo: O Poke Tournament pode ser considerado um jogo do estilo M.O.B.A. (Multiplayer Online Battle Arena) apesar do jogo não contar com fases no estilo do jogo DOTA, o PkT tem como foco principal as batalhas pvp levando um novo estilo de jogo de luta 2D com a variedade estrategica de cada pokemon da serie. graficos: Alem desse novo estilo de jogo tambem estamos trabalhando em graficos novos para interface do client e movimentos de combate no pokemon, então você irá encontrar telas que facilitam a jogabilidade e movimentos para todos os ataques dos pokemons do jogo. Por enquanto estamos trabalhando somente com pokemons não evoluidos "pequenos". jogabilidade: A jogabilidade do PkT é um pouco baseada nos jogos de luta, com combos e contra ataques você terá a experiencia da adrenalina enquanto joga. Alem de poder customizar os combos de seus pokemons ao seu gosto o jogo conta com varios sistemas de batalhas inovadores, entre eles vocês encontrarão sistema de movimento ao bater, contra ataque, defesa, avanço rapido, sistema de dor, sistema de Special e muito mais. historia: A historia do jogo e baseada na primeira versão da serie de games pokemon rpg (Pokemon Red/Green), sem diferenças relevantes, a unica diferença e que depois de pallet o seu personagem irá para um Lobby onde será sua unica cidade para sempre. quests: Apesar do Pkt ser um jogo de Arena PVP, não podiamos deixar de ter aquelas quests premiadas não e mesmo? alem de quests de historia você tambem poderá fazer missões diarias, missões premiadas e missões secretas. premios: Depois de tudo isso ainda temos premios diarios para quem marcar presança, permanecer online e ate uma quantidade de Vip Points por participar de batalhas PVP Rankiadas. Progresso Final: 65% Fases (mapa): 50% prontas - (Route1, Viridian Forest, MT. Moon, Bills Route,Rock Tunel) Pokemons: 60% falta - (os pokemons que vem vem depois do numero 105) Ataques: 60% falta - (a maioria dos pokemons ainda faltam 1 ou 2 ataques) Sistemas: 95% falta - (testes e ajuste de danos e seleção de premios) Client: 60% falta - (novo designer base, recompilação do client, nova janela de health bar, equipamentos, nova janela de skills pro pokemon e nova pokedex). Prints: alguns golpes Escolhendo a fase tela pvp rankiada - fases e oponentes são sorteados tela de conversa com npc npc de produção npc de quests equipando skill no combo nosso mascote e premio especial Lucky Draw Sistema de Colisão Videos Pokeball System Vídeo da primeira fase tutorial https://www.facebook.com/Pok%C3%A9-Tournament-1398028193775843/1 ponto -
Boa noite galera, Estou a alguns dias tentando resolver um problema que tive com o OTC: ao usar a função doCreatureSetHideHealth simplesmente o player trava e não consegue fazer nada até o hidehealth ser desfeito. Isso ocorre porque, na source do OTC, a declaração de morte é feita baseada em porcentagem de vida e essa inexiste quando o hideHealth é acionado, somente a vida total e a vida máxima é que continuam com valores relevantes. Então, o OTC simplesmente te considera como um morto vivo quando você usa hideHealth e você não pode realizar nenhuma ação no jogo a não ser deslogar. Após alguns dias fuçando consegui finalmente resolver o problema e vim compartilhar a solução com vocês. 1) Na source do seu OTC vá em creatures.cpp. Crie as funções abaixo: double Creature::getLocalPlayerHealth() { return g_game.getLocalPlayer()->getHealth(); } bool Creature::isDead() { if (!isLocalPlayer()) return m_healthPercent <= 0; double m_health = getLocalPlayerHealth(); return m_health <= 0; } Substitua: if(m_healthPercent < 1) // creature is dead return; por if(m_healthPercent < 1) // creature is dead if (!isLocalPlayer()) return; 2) Vá em creature.h e troque a declaração da função isDead() por: bool isDead(); 3) Em game.cpp troque a função proccessDeath por: void Game::processDeath(int deathType, int penality) { if (m_localPlayer->getHealth() > 0){ m_dead = true; m_localPlayer->stopWalk(); g_lua.callGlobalField("g_game", "onDeath", deathType, penality); } } Pronto, o seu OTC agora suporta a função doCreatureSetHideHealth (e de bônus você consegue enxergar o seu player com uma barra preta e seu nome, apesar dos outros não te verem). Bom é simples, mas útil espero que ajude. Abraços,1 ponto
-
Importar s3db para o Mysql
othereality reagiu a Furabio por uma questão
Eu também descobri outro jeito usando um programa que se chama DbConverter, ele converte seu arquivo sql, para mysql, mandado direto para o seu banco de dados... Se quiser usar a que tu me enviou, vou anexar aqui. Ps: mesmo com o programa teve tabelas que não conseguiram ser convertidas, mas as mais importantes permaneceram. http://www.mediafire.com/view/8tvn968o8v7vdht/database.sql Tópico Movido Este tópico foi movido de "OTServ → Websites → Suporte Websites" para "OTServ → Websites → Suporte Websites → Tópicos Resolvidos | Websites".1 ponto -
Pokémon Origins Show-Off!
jeanflamengo reagiu a Refe por um tópico no fórum
Hoje vim mostrar uns sistemas do CLIENT do Pokémon Origins Tela de Login: Catch Window: Fazendo ultimas modificações Pokémon Info: Info Window: Addon, TM/HM, Nick, Etc. Terminando a parte de Addon! Pokédex/Badge Case: Começando a fazer o design! Player Info: Coisas que eu julguei interessante para esse tópico:1 ponto -
Hm, pode ser. Mudarei isso então, fica até mais simples, pq ao inves de for terá um random. xDEditei la da forma que você sugeriu. Fiz a spell1 do jeito que eu entendi, não sei se está do jeito que você queria mas com alguns ajustes chegamos lá: <instant name="Spell1" words="baratask spell1" lvl="1" mana="100" prem="0" exhaustion="20000" groups="1,2000" icon="23" needlearn="0" event="script" value="attack/spell1.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> local config = { cd = 20, hit_delay = 2000, stg = 5573, life_percent = 5, mana_percent = 10, hits = 3 } local combat = createCombatObject() local area = createCombatArea(AREA_SQUARE3X3) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_LOSEENERGY) setCombatArea(combat, area) function onTargetCreature(cid, target) if not isCreature(target) then return false end local healthDmg = -getCreatureHealth(target)*config.life_percent/100 local manaDmg = -getCreatureMana(target)*config.mana_percent/100 doSendMagicEffect(getCreaturePosition(target), CONST_ME_MAGIC_RED) doTargetCombatHealth(cid, target, COMBAT_LIFEDRAIN, healthDmg, healthDmg, CONST_ME_MAGIC_RED) doTargetCombatMana(cid, target, manaDmg, manaDmg, CONST_ME_MAGIC_BLUE) return true end setCombatCallback(combat, CALLBACK_PARAM_TARGETCREATURE, "onTargetCreature") function attack(cid, var, hits) n = hits or 0 if n >= config.hits then return false end doCombat(cid, combat, var) addEvent(attack, config.hit_delay, cid, var, n+1) end function onCastSpell(cid, var) if not isPlayer(cid) then return false end if getPlayerStorageValue(cid, config.stg) - os.time() <= 0 then setPlayerStorageValue(cid, config.stg, os.time() + config.cd) attack(cid, var) else doPlayerSendCancel(cid, "You're exhausted.") end return true end Up, e ao cara funcionou?!1 ponto
-
[Download] Remakes,pedras,paredes,escadas e Montanhas PXG
Developer Berg reagiu a kaleudd por um tópico no fórum
opa,tenho sim,irei liberar assim que chegar em casa.1 ponto -
Muito bom, obrigado pela contribuição. Rep+1 ponto
-
Qual site baixar
othereality reagiu a Furabio por uma questão
Recomendo esse :http://www.xtibia.com/forum/topic/238658-gesior-2012-modificado-por-sekk1 ponto -
Você pode usar dentro da função que você criou getPlayerSkillLevel(cid, skillId) e usar esse skill na formula, mas não faria muito sentido. rs @Lobo e Caronte, obrigado pelos comentarios e feedbacks! Abraços,1 ponto
-
Na verdade CALLBACK_PARAM_SKILLVALUE cria uma formula sua que você pode definir o que quiser baseado em level, skill, attack, factor. O skill que é passado por parâmetro para a função que você definiu nesse callback é o skill da arma que você estiver empunhando. No caso de nenhuma, ai é fist.1 ponto
-
Slá mano, nunca joguei esse ot, mais acho que se parece com: http://www.xtibia.com/forum/topic/238577-pokemon-servidor-pokestage/page-11 ponto
-
Terceira: <instant name="Skell Summon" words="utevo res skell" lvl="1" mana="500" prem="0" exhaustion="1" groups="1,1" icon="23" needlearn="0" event="script" value="attack/skellsummon.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> local config = { creature = "Demon", summon_time = 15*1000, cd = 20, stgs = {cd = 5571, remove = 5572}, life_percent = 20 } local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MAGIC_BLUE) setCombatParam(combat, COMBAT_PARAM_AGGRESSIVE, false) local condition = createConditionObject(CONDITION_INFIGHT) setConditionParam(condition, CONDITION_PARAM_TICKS, 15 * 1000) function removeSummon(cid) if getPlayerStorageValue(cid, config.stgs.remove) == -1 then return false end if not isPlayer(cid) then return false end summons = getCreatureSummons(cid) for _, i in pairs(summons) do if isCreature(i) then if getCreatureName(i) == config.creature then doRemoveCreature(i) setPlayerStorageValue(cid, config.stgs.remove, -1) doRemoveCondition(cid, CONDITION_INFIGHT) return true end end end return false end function onCastSpell(cid, var) if not isPlayer(cid) then return false end if getPlayerStorageValue(cid, config.stgs.remove) ~= -1 then summons = getCreatureSummons(cid) for _, i in pairs(summons) do if isCreature(i) then if getCreatureName(i) == config.creature then doRemoveCreature(i) setPlayerStorageValue(cid, config.stgs.remove, -1) doCreatureAddHealth(cid, getCreatureMaxHealth(cid)*config.life_percent/100) doCombat(cid, combat, var) doRemoveCondition(cid, CONDITION_INFIGHT) return true end end end return false end if getPlayerStorageValue(cid, config.stgs.cd) - os.time() <= 0 then doAddCondition(cid, condition) setPlayerStorageValue(cid, config.stgs.cd, os.time() + config.cd) setPlayerStorageValue(cid, config.stgs.remove, 1) doCombat(cid, combat, var) monster = doSummonCreature(config.creature, getCreaturePosition(cid)) doConvinceCreature(cid, monster) addEvent(removeSummon, config.summon_time, cid) else doPlayerSendCancel(cid, "You're exhausted.") end return true end Testa ai e ve se ta no jeito. PS: mude o nome de Demon para o monstro que você quiser. Abraços, EDITADO: SOBRE A PRIMEIRA SPELL ELA EH AREA 3x3 EM VOLTA DO PLAYER OU DIRECIONADA?1 ponto
-
Depois de tanto tempo sem mappear estou tendo dificuldades com alguns detalhes, principalmente com as graminhas, mas enfim, apenas um local de fazendas:1 ponto
-
[PEDIDO] Npc de troca por storage
Johnnyirie reagiu a Furabio por uma questão
Não se esqueça de colocar o id dos itens ... local item_1 = XXXX -- ID do item necessário para a troca local item_2 = XXXX -- ID do item que recebe ao dar item_1 local keywordHandler = KeywordHandler:new() local npcHandler = NpcHandler:new(keywordHandler) NpcSystem.parseParameters(npcHandler) function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end function onThink() npcHandler:onThink() end local function creatureSayCallback(cid, type, msg) if not npcHandler:isFocused(cid) then return false end player = Player(cid); if msgcontains(msg, "troca") then if player:getStorageValue(9874) < 1 then if player:getItemCount(item_1) > 1 then npcHandler:say("Você tem certeza ?", cid); npcHandler.topic[cid] = 1; else npcHandler:say("Você não tem o item para a troca.", cid); npcHandler.topic[cid] = 0; end else npcHandler:say("Você já fez a troca.", cid); npcHandler.topic[cid] = 0; end elseif msgcontains(msg, "yes") and npcHandler.topic[cid] == 1 and player:getItemCount(item_1) > 1 then npcHandler:say("Aqui está o seu item!", cid); player:removeItem(item_1, 1); player:addItem(item_2, 1); player:setStorageValue(9874, 1); npcHandler.topic[cid] = 0; end return true end npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new())1 ponto -
ok, @@Caronte, muito obrigado pela ajuda, peço desculpas por ter respondido ele, ele ja me prejudicou muito, em sentido de ferrar meu servidor, mais agradeço muito seu auxilio, isso não irá se repetir !!!1 ponto
-
[Download] Remakes,pedras,paredes,escadas e Montanhas PXG
Developer Berg reagiu a kaleudd por um tópico no fórum
opa,vlw tamo ai =)1 ponto -
Acabei fazendo a 2 aqui de bobeira xD @@baratask Tente isso: <instant name="Statue Attack" words="utevo res statue" lvl="1" mana="500" prem="0" exhaustion="20000" groups="1,4000" icon="23" needlearn="0" event="script" value="attack/statue.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> Em um arquivo chamado statue.lua, dentro de spells/attack coloque o codigo: local config = { statue = 1444, range = 5, max_dmg = -150, min_dmg = -50, hit_delay = 1000, statue_time = 10*1000, cd = 20, stg = 5570 } local max_hits = config.statue_time/config.hit_delay local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_DEATHDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_MORTAREA) setCombatFormula(combat, COMBAT_FORMULA_DAMAGE, 0, config.min_dmg, 0, config.max_dmg) local condition = createConditionObject(CONDITION_INFIGHT) setConditionParam(condition, CONDITION_PARAM_TICKS, 10 * 1000) function removeItem(pos) doRemoveItem(getTileItemById(pos, config.statue).uid) end function attackSpecs(cid, pos, var, hits) n = hits or 0 if n >= max_hits then return false end local spec = getSpectators(pos, config.range, config.range) i = spec[math.random(1, #spec)] if #spec <= 1 then return false end while(i == cid) do i = spec[math.random(1, #spec)] end if isCreature(i) then var.pos = getCreaturePosition(i) doSendDistanceShoot(pos, var.pos, CONST_ANI_SUDDENDEATH) doCombat(cid, combat, var) end addEvent(attackSpecs, config.hit_delay, cid, pos, var, n+1) end function itemInteraction(cid, pos, var) attackSpecs(cid, pos, var) addEvent(removeItem, config.statue_time, pos) end function onCastSpell(cid, var) if not isPlayer(cid) then return false end if getPlayerStorageValue(cid, config.stg) - os.time() <= 0 then doAddCondition(cid, condition) setPlayerStorageValue(cid, config.stg, os.time() + config.cd) local pos = Position(getCreaturePosition(cid).x+1, getCreaturePosition(cid).y, getCreaturePosition(cid).z) doCreateItem(config.statue, 1, pos) itemInteraction(cid, pos, var) else doPlayerSendCancel(cid, "You're exhausted.") end return true end Me dê retorno. gif dela: Abraços, ps: você não deu maiores detalhes como no que depende o dano, velocidade dos hits, nem cooldown, qual estatua usar, etc. Então fiz do jeito que preferi, mas é altamente customizável basta mexer/pedir.1 ponto
-
rip hehe heuheue dash v6 , vc estava no caminho certo até n dar mais noticias1 ponto
-
Author:Printer Como funciona: Instalação: Vá em actions/actions.xml e adicione essa linha: <action actionid="8000" script="tronEventLever.lua" /> Vá em actions/scripts e crie um arquivo chamado ''tronEventLever.lua'' e adicione isso dentro: function onUse(player, item, fromPosition, target, toPosition, isHotkey) if item.itemid == 1945 then if tronEvent:onUseLever(player) == false then return true end end item:transform(item.itemid == 1945 and 1946 or 1945) return true end Agora vá em movements/movements.xml e remova essas linhas: <movevent event="AddItem" itemid="1492" function="onAddField" /> <movevent event="StepIn" itemid="1493" function="onStepInField" /> <movevent event="StepIn" itemid="1500" function="onStepInField" /> <movevent event="AddItem" itemid="1500" function="onAddField" /> <movevent event="StepIn" itemid="1506" function="onStepInField" /> <movevent event="AddItem" itemid="1506" function="onAddField" /> E adicione essas linhas: <movevent event="StepIn" itemid="1492" script="tronEventMovement.lua" /> <movevent event="StepIn" itemid="1500" script="tronEventMovement.lua" /> <movevent event="StepIn" itemid="1506" script="tronEventMovement.lua" /> Vá em movements/scripts e crie um arquivo chamado "tronEventMovement.lua" e adicione isso dentro: function onStepIn(creature, item, position, fromPosition) local player = creature:getPlayer() if player == nil then return false end position:sendMagicEffect(CONST_ME_FIREAREA) tronEvent:onPlayerDeath(player, tonumber(item:getAttribute(ITEM_ATTRIBUTE_TEXT)) or 0) return true end Agora em data/global.lua,adicione essa linha: dofile('data/tronEvent.lua') Create new lua inside data folder and name it: "tronEvent.lua" and paste this: http://pastebin.com/qdjptfYe1 ponto