Histórico de Curtidas
-
detoneitormen deu reputação a Ryzor em [LUA] Conhecendo o os.dateEste tutorial abaixo foi inteiramente criado por shoeei.
Introdução
Vou tentar ajudar vocês com um tutorial de os.date. Sendo sincero, eu aprendi a pouco tempo como usar o os.date, em um exemplar de programação lua. Estou fazendo este tutorial para esclarecer a maioria das duvidas que vocês possam ter, então, por favor, prestem muita atenção se forem ler, e não leiam a menos, que estejam com tempo, paciência e vontade de aprender, pois eu creio que mesmo sendo novato com o os.date, eu vou conseguir fazer um bom tutorial.
Publico Alvo
Este tutorial foi feito para ensinar programadores lua, do nível iniciante/intermediário, ou seja, aqueles que já tem algum conhecimento quanto a os.time, variáveis, loopings, e etc...
Tutorial
Em OtServers, os.date é pouco explorado, já que sua funcionalidade, é, por muitos, desconhecida. Então vou explicar como você poderia usa-lo em um script para o seu ot. Vamos ver, digamos que você queira que um script funcione a partir das oito da manhã, e pare de funcionar a partir das duas da tarde; para isso, você poderia usar o os.date. O os.date, assim como o os.time, serve para controlar valores de tempo, e retornam os mesmos de acordo com os valores da cpu, a partir de quando o script entra em funcionamento, então, o exemplo acima ficaria assim:
function onSay(cid, words, param) if os.date("%X") >= "08:00:00" and os.date("%X") <= "14:00:00" then doPlayerSendTextMessage(cid, 22, "Teste") end end No exemplo acima, a talkaction só ira funcionar se for depois das oito da manhã, e antes das duas da tarde, então, dentro deste intervalo de tempo, o script funcionará normalmente, e irá mandar a mensagem "Teste" para o jogador. Já se o script for executado fora deste intervalo, no caso, nada acontecerá.
Deve-se notar, também, que no script acima, dentro dos parênteses esta isto:
"%X" Certo, eu acho que eu poderia chamar isto de Pattern; existem vários destes parâmetros que podem ser utilizados, neste caso, eu usei o "%X", pois ele retorna valores do horário na seguinte forma:
Onde, azul são as horas, vermelho são os minutos, e verde são os segundos; neste caso, você deveria usar os números como um relógio digital de 24 horas.
Acho que a lógica do os.date já deu para entender, mas vamos recapitular:
O os.date é usado para retornar algum valor de tempo;
Você pode usa-lo como uma condição para executar um outro comando;
Dentro dos parênteses do os.date, você deve usar parâmetros.
Uma coisa muito importante do os.date, é que você deve igualar ele, com valores entre aspas, mesmo que sejam números, por exemplo:
if os.date("%X") >= "08:00:00" and os.date("%X") <= "20:00:00"Perceba que os números estão entre aspas. Certo, depois de termos recapitulado a lógica do os.date, vamos aos mais importantes parâmetros que podem ser usados e os valores que são retornados por eles; segue a lista:
Pattern - Explicação:
%a - dia da semana abreviado (Wed) %A - dia da semana completo (Sunday) %b - nome do mês abreviado (Sep) %B - nome do mês completo (April) %c - data e hora (09/16/98 23:48:10) %d - dia do mês [01-31] %H - hora de um relógio de 24 horas [00-23] %I - hora de um relógio de 12 horas [01-12] %M - minutos [00-59] %m - mês [01-12] %S - segundos [00-60] %w - dia da semana por números [0-6 = Domigo-Sabado] %x - data (09/16/98) %X - hora (23:48:10) %Y - ano (1998) Vocês podem perceber que todas as palavras que forem usadas, tanto abreviações, como palavras inteiras, devem ser em ingles, é claro.
Certo, dito os mais usados parâmetros e a lógica do os.date, acho que isso pode encerrar o nosso tutorial, mas antes, uma ultima dica; se você tem duvida de que valor o parâmetro vai retornar, faça o seguinte:
function onSay(cid, words, param) local par = os.date("Parâmetro") doPlayerSendTextMessage(cid, 22, "O valor é "..par.."!") end E por ultimo, mas não menos importante, para se criar uma tabela usando o os.date, deve-se usá-lo da seguinte maneira:
os.date("*t", Valor_da_Tabela) Finalização
Isso deve funcionar e encerrar o nosso tutorial; é claro que o os.date pode ter mais alguma utilidade que eu desconheça, mas eu acho que isso pode ser uma boa introdução dele. Espero que tenham gostado, ate mais.
-
detoneitormen deu reputação a amarelosk em [AJUDA] Otclient Não tem o canal NPCsja tive esse problema, demorei a achar a solução, tenta isso aqui https://github.com/edubart/otclient/pull/778/files, vai na pasta modules/gamelib/const.lua e faça essa mudança aqui em baixo
@@ -218,8 +218,8 @@ MessageModes = { RVRAnswer = 47, RVRContinue = 48, GameHighlight = 49, - NpcFromStartBlock = 50, - Last = 51, + NpcFromStartBlock = 51, + Last = 52, Invalid = 255, }
-
detoneitormen deu reputação a xBen em oldKorelin - AvatarOlá estou desenvolvendo um projeto para relembrar um dos primeiros otserver em que se pode falar de inovação. (isso se não for o primeiro)
Pra quem não sabe Korelin é um servidor baseado no anime Avatar a lenda de Aang no protocolo 8.00, onde é possivel escolher entre os 4 Elementos e poder usar suas dobras (spells).
TERRA - AGUA - FOGO - AR
E com isso cada elemento tem suas vantagens.
Alem dos 4 elementos atualmente existem 3 vocações secundarias sendo elas: Knight - Paladin - Berserker.
As vocações secundarias são perfeitas para aqueles que gostam de treinar skills e também te ajuda em combate com spells exclusivas com a utilização de armas
Nosso mapa está o mais parecido possivel com o do verdadeiro KoreliN.
Já fizemos todos os sistemas como
Castle War
Forja
Water Pouch e Water Ambient
(Dobradores de agua precisam de uma bolsa de agua ou estar perto de mar ou rio para utilizar suas dobras)
Sistema Avatar
(O player que conseguir destravar a alavanca vira o novo avatar por 24horas sendo assim podendo usar os 4 elementos)
Bosses e Quest
Acompanhe nossa pagina no facebook para mais informações, postamos videos diariamente mostrando o desenvolvimento deem uma conferida.
Facebook
Show off
-
detoneitormen deu reputação a BeluciGamer em Script de oracleDesculpe reabrir o tópico mais acho que isso é oque vc precisa
http://www.tibiaking.com/forum/topic/46263-oracle-100-editavel/
-
detoneitormen recebeu reputação de Snowsz em [Sistema] AttackSpeed - Sem sourceMuito bom kra, criativo ;]
Não testei, mas imagino que funcione kkk, só tem um erro aqui:
elseif slotRight.uid > 0 then if (multi*getPlayerSkill(pid, skill)) >= 1999 then doItemSetAttribute(slotLeft.uid, "attackspeed", 1) else doItemSetAttribute(slotLeft.uid, "attackspeed", 2000-(multi*getPlayerSkill(pid, skill))) end No caso, slotRight...
Eu escrevi aqui no creaturescripts, deve funcionar também:
function onThink(cid, interval) local multi = 200 local skill = 2 local limite = 99 local slotLeft, slotRight = getPlayerSlotItem(cid, CONST_SLOT_LEFT), getPlayerSlotItem(cid, CONST_SLOT_RIGHT) if last_interval == nil then last_interval= os.clock() end if (os.clock() - last_interval) > 1 then if slotLeft.uid > 0 then if (multi*getPlayerSkill(cid, skill)) >= limite then doItemSetAttribute(slotLeft.uid, "attackspeed", 1) else doItemSetAttribute(slotLeft.uid, "attackspeed", 2000-(multi*getPlayerSkill(cid, skill))) end elseif slotRight.uid > 0 then if (multi*getPlayerSkill(cid, skill)) >= limite then doItemSetAttribute(slotRight.uid, "attackspeed", 1) else doItemSetAttribute(slotRight.uid, "attackspeed", 2000-(multi*getPlayerSkill(cid, skill))) end end last_interval= os.clock() return true end return false end Mas imagino que o bug esteja na repetição, então, como o servidor vai ficar sendo carregado o tempo inteiro com o script, o andar automático, por exemplo, será interrompido...isso pelo creaturescripts, mas talvez pelo global também, não sei.
-
detoneitormen deu reputação a Snowsz em [Sistema] AttackSpeed - Sem sourceBom, postei este tópico nessa área e não em globalevents por que não considero que lá deem muitas visualizações em globalevents, não é por que quero ganhar reputação ou algo do tipo, mas para ajudar quem precisa de tal coisa.
Resumindo: Este script é um globalevent que a cada 2 segundos muda o attackspeed de um item conforme o skill fist fighting do player, funcionando como um sistema de attackspeed com source, quanto mais skill, mais rápido ele ataca, mas como este sistema não utiliza sources, eu fiz o melhor que eu pude.
Testado em um TFS 0.4
Lag: Não se se irá causar lag, pouco lag, ou muito lag, eu fiz em globalevent por causa do seu intervalo que pode ser configurável para mais ou para menos, não pensei muito em usar o creatureevent por conta que o onThink ou onAttack fica se repetindo a cada meio segundo se não me engano, então, preferi fazer desta forma.
Instalação:
Na pasta globalevents/scripts crie um arquivo com extensão .lua com nome de playerattackspeed(ficando playerattackspeed.lua) e ponha isso dentro:
function onThink(interval) local multi = 20 local skill = 0 for _, pid in ipairs(getPlayersOnline()) do local slotLeft, slotRight = getPlayerSlotItem(pid, CONST_SLOT_LEFT), getPlayerSlotItem(pid, CONST_SLOT_RIGHT) if isCreature(pid) then if slotLeft.uid > 0 then if (multi*getPlayerSkill(pid, skill)) >= 1999 then doItemSetAttribute(slotLeft.uid, "attackspeed", 1) else doItemSetAttribute(slotLeft.uid, "attackspeed", 2000-(multi*getPlayerSkill(pid, skill))) end elseif slotRight.uid > 0 then if (multi*getPlayerSkill(pid, skill)) >= 1999 then doItemSetAttribute(slotRight.uid, "attackspeed", 1) else doItemSetAttribute(slotRight.uid, "attackspeed", 2000-(multi*getPlayerSkill(pid, skill))) end end end end return true end Agora volte uma pasta e vá só para globalevents lá você encontrará um arquivo chamado globalevents com extensão .xml(sendo globalevents.xml) nele adicione a tag antes das duas últimas linhas:
<globalevent name="PlayerAttackSpeed" interval="2000" event="script" value="playerattackspeed.lua"/> Bom, o script foi instalado com sucesso.
Configuração:
No arquivo com extensão final .lua você pode modificar o id do skill em "local skill = 0", 0 significa o skill fist fighting, você pode ir alternando
Ainda no arquivo com extensão final .lua pode-se alterar o "local multi = 20", o 20 é a multiplicação do skill, ou seja, skill x 20, quando o skill configurado(eu deixei fist fighting) atingir 100 com o multi em 20, ele chegará ao máximo de attackspeed, após isso mesmo que ele pegue skill 1000 continuará essa mesma velocidade por conta de limitações que o tibia impõe nas suas sources, se quiser que ele ataque ainda mais rápido deverá mudar se não me engano só uma linha nas sources.
Agora no arquivo globalevents.xml você pode alterar a tag, mudando interval, 1000 é igual a um segundo, ou seja, no script ta configurado para a cada 2 segundos alterar o attackspeed conforme a configuração, você pode alterar para quanto quiser, lembre-se 1000 é um segundo, ou seja, se colocar 5000 fica 5 segundos de intervalo para o script agir.
Espero que gostem!
Talvez quando eu estiver mais avançado em lua eu possa criar uma segunda versão que possa atacar mais rápido, mas, no momento nem penso nisso
Versão Creaturescripts - Créditos: detoneitormen
(Obs: Não testei esta versão, só copiei do modo que ele escreveu.)
function onThink(cid, interval) local multi = 200 local skill = 2 local limite = 99 local slotLeft, slotRight = getPlayerSlotItem(cid, CONST_SLOT_LEFT), getPlayerSlotItem(cid, CONST_SLOT_RIGHT) if last_interval == nil then last_interval= os.clock() end if (os.clock() - last_interval) > 1 then if slotLeft.uid > 0 then if (multi*getPlayerSkill(cid, skill)) >= limite then doItemSetAttribute(slotLeft.uid, "attackspeed", 1) else doItemSetAttribute(slotLeft.uid, "attackspeed", 2000-(multi*getPlayerSkill(cid, skill))) end elseif slotRight.uid > 0 then if (multi*getPlayerSkill(cid, skill)) >= limite then doItemSetAttribute(slotRight.uid, "attackspeed", 1) else doItemSetAttribute(slotRight.uid, "attackspeed", 2000-(multi*getPlayerSkill(cid, skill))) end end last_interval= os.clock() return true end return false end A configuração é igual a minha versão, só muda a variável "limite" e "multi", para deixar igual ao meu, basta trocar:
Isso:
local limite = 99 Por isso:
local limite = 1999 E isso:
local multi = 200 Por isso:
local multi = 20 Obrigado detoneitormen.
-
detoneitormen deu reputação a xWhiteWolf em Sistema de Auto-Facing: Vire Automaticamente para o Target ao Atacar (TFS 0.3.6)Bom galera, tem uma coisa bem simples que nem o tibia global fez e que eu to trazendo aqui pra vocês. Trata-se de um pequeno sistema que fará você sempre virar pra direção do seu target ao atacar.
Testado em TFS 0.3.6 Cliente 8.54.
Imagem auto explicativa:
Chega de atacar de costas!
Agora pra instalar é bem tranquilo. Abra um arquivo .lua em data\creaturescripts\scripts chamado target e coloque o seguinte conteudo dentro dele:
Feito isso adicione essa linha no creaturescripts.xml:
<event type="attack" name="targetCreature" script="target.lua"/> E para finalizar adicione a seguinte tag em creaturescripts\scripts\login.lua:
registerCreatureEvent(cid, "targetCreature") Espero que vcs tenham curtido, é algo bem simples mas ninguém havia pensado nisso antes (nem o próprio Tibia), é uma coisa bem básica e que torna o jogo bem mais importante e sério.
EDIT:: Usem essa versão que está mais completa, na anterior se o target estivesse na diagonal ele não virava.
-
detoneitormen deu reputação a Luquinha em [BÁSICO] - Novo Tipo De Rua !Introdução
Uma rua ou calhe é normalmente entendida como um espaço público no qual o direito de ir e vir é plenamente realizado. Entretanto, o conceito também é aplicado a espaços que se assemelhem a ela, como ruas internas em condomínios de acesso privado ou mesmo em corredores internos de centros comerciais.
Em ambientes medievais, raramente existia calçadas e as ruas eram largas.
Fonte: wikipedia
1. Para começar escolha o tipo de rua que irá melhor se encaixar com o tema de sua cidade, no meu caso irei usar o ID: 724
*Ficando assim:
- Mas não está muito larga?
R: Espera e verá o porque disto!
2. Como a ideia aqui é fazer outro tipo de rua, iremos colocar algo que raramente se vê: uma calçada! Para isto utilizei os seguintes IDS: 3152-3157
*Ficando assim:
3. Hora de fazer as bordas para as calçadas e para o canteiro central.
*Ficando assim:
4. Chegamos no fim, agora só falta detalhar, adicionar nature e construções em volta, um exemplo:
É só isso galera, espero que tenham aprendido e gostado do tutorial.
Créditos:
Left4Dead - PELAS FOTOS
-
detoneitormen deu reputação a Kaiotp em Criatividade - poste suas idéias!Creditos;
DuMal
Kaiotp
Uma Area Com Uma Forca...
-
detoneitormen deu reputação a MaXwEllDeN em PatternsPattern
Pattern ("Padrão" em pt-br) é uma poderosa funcionalidade para manipulação de strings (caso você não saiba o que é uma "string", busque saber antes de continuar, recomendo
também ter um certo domínio sobre a biblioteca string), e usada para buscar um padrão de texto pré-definido.
Porque aprender ?
Possui recursos indispensáveis quando se precisa trabalhar com strings, alta aplicabilidade em scripts direcionados a otserv (talkactions), não que se vá usar isso a todo o momento, mas é altamente recomendado que se saiba trabalhar com patterns, é extremamente útil as vezes.
Funções
Algumas funções da biblioteca padrão string que aceitam pattern em seus parâmetros:
string.find(string, pattern) – Procura a primeira instância da pattern na string
string.gfind(string, pattern) – Quando for chamada repetidamente, retorna cada instância da pattern na string
string.gsub(string, pattern, replace) – Retorna uma string em que todas as instâncias da pattern foram substituidas por replace
string.match(string, pattern, init) – Retorna uma lista de ocorrências da pattern na string, começando em init (1 significa o primeiro caractere da string, 2 o segundo, assim por diante)
Conjuntos
Quando se constrói uma pattern, se utiliza alguns caracteres, cada um representando um conjunto diferente:
(onde "x" não é um caractere mágico ^$()%.[]*+-?) → Representa o caractere "x" mesmo;
. → Representa todos os caracteres;
%a → Representa todas as letras;
%c → Representa todos os caracteres de controle;
%d → Representa todos os dígitos;
%l → Representa todas as letras minusculas;
%p → Representa todos os caracteres de pontuação;
%s → Representa todos os caracteres de espaço;
%u → Representa todas as letras maiúsculas;
%w → Representa todos os caracteres alfanuméricos;
%x → Representa todos os dígitos hexadecimais;
%z → Representa o caractere com a representação do 0 (zero). Ao usar zeros na pattern ela não irá funciona, use esta nesse caso;
Ao usar letra maiúscula, isso faz representar o contrário (Exemplo: %A → Representa tudo que não for letras; %D → Representa tudo que não for um digito; assim por diante...).
Como dito anteriormente, para se criar uma pattern é necessário utilizar esses conjuntos, uma pattern é feita de uma sequência desses conjuntos. Se você quisesse criar uma pattern para encontrar uma certa string em um texto, por exemplo, para encontrar os números da string "23otserv", você teria que usar esta pattern "%d%dotserv", assim você estaria definindo que quer os numeros que estão ao lado da palavra ‘otserv’.
Mas e se tivesse que encontrar um numero com 10 "casas" ? Por isso existe os modificadores, para evitar essa repetição desnecessária.
Modificadores
Servem principalmente para poupar serviço e são quatro, entenda 'x' como sendo algum conjunto (%a, %c, %d, ...):
x* → Retorna 0 ou mais repetições do conjunto x. Sempre retornará a maior cadeia possível encontrada;
x+ → Retorna 1 ou mais repetições do conjunto x. Sempre retornará a maior cadeia possível encontrada;
x- → Retorna 0 ou mais repetições do conjunto x. Sempre retornará a menor cadeia possível encontrada;
x? → Retorna 0 ou 1 ocorrência de x;
Elementos especiais
Existe também quatro elementos especiais:
%n → Sendo n um numero entre 1 e 9, busca a enésima captura (apenas vi sendo usada na função string.gsub);
%bxy → Procura uma string que inicia com x e termina com y;
^ → Quando está no começo da pattern, força a pattern a ser encontrada no começo da string;
$ → Quando está no final da pattern, força a pattern a ser encontrada no fim da string;
Nota: Se ^ ou $ estiverem em outros lugares da pattern, não fazem nada, apenas representam eles mesmos.
Construindo uma pattern
Vamos construir algumas patterns com os elementos citados acima.
Primeiro alguns exemplos e depois uma explicação mais detalhada de cada elemento da pattern:
String para as patterns: "Exemplo lua de pattern lua feito em lua"
exemplos toscos, a gente se vê por aqui
Pattern:
(%a+) lua
Capturaria:
Exemplo lua de pattern lua feito em lua
Ele só retornará o primeiro caso que corresponder com a pattern.
Agora, ao invés de usar o "%a" fosse usado o "." (que captura tudo), aconteceria isso:
Pattern:
(.+) lua
Capturaria:
Exemplo lua de pattern lua feito em lua
Como "%a" captura apenas letras e não o "espaço", foi por isso que no primeiro exemplo só capturou a palavra "Exemplo" e no segundo exemplo, como foi usado o "." que captura tudo, capturou uma parte maior (ai que vêm a parte do modificador) por causa do modificador "+" que sempre vai buscar a maior cadeia possivel, agora veja um exemplo usando o "-":
Pattern:
(.-) lua
Capturaria:
Exemplo lua de pattern lua feito em lua
O modificador "-", como dito anteriormente, captura a menor cadeia e por isso capturaria apenas o "Exemplo".
Todos os modificadores são importantes.
Um exemplo maior:
Pattern:
(%a+) lua (.-) lua (.+)
Capturaria:
Exemplo lua de pattern lua feito em lua
Para quem não entendeu
Explicação passo a passo:
(%d+)
Captura → O parenteses define que você quer que retorne essa captura.
Conjunto → No caso é o de digitos.
Modificador → No caso mostra que é para obter a maior cadeia possivel com 1 ou mais repetições do conjunto.
Um exemplo mais avançado
Agora usando de exemplo a pattern da função string.trim, que remove os espaços em branco do lado esquerdo e direito da string.
function string.trim(str) -- Function by Colandus return (string.gsub(str, "^%s*(.-)%s*$", "%1")) end
string.gsub(str, "^%s*(.-)%s*$", "%1")
str → Uma string qualquer;
^ → Força o começo da pattern ser encontrada no começo de str;
%s* → Conjunto de espaços, podendo ter 0 ou mais repetições;
(.-) → A captura principal, a que vai ser retornada, podendo ser digitos, letras, espaço, etc;
$ → Força o final da pattern ser encontrada no fim de str;
%1 → Retorna a 1ª captura da pattern e usa como parametro da função (Esse é um dos elementos especiais, %n);
Dessa forma será removido os espaços apenas no começo e no fim da string !
Complemento
Depois de dominar e entender como funciona as patterns, vamos aplica-las em funções, vou mostrar um exemplo de cada função (as que foram citadas no começo).
string.find:
init, end, case1, case2 = string.find("minha string123", "(%a+) (.+)")
init → Onde inicia a captura encontrada (nesse caso, init = 1);
end → Onde termina a captura encontrada (end = 15);
case1 → Primeira captura que equivale a pattern (%a+) (case1 = minha);
case2 → Segunda captura que equivale a pattern (.+) (case2 = string123);
string.gfind: for occ in string.gfind("a1a2a3a4a5", "(%a%d)") do print(occ) end occ → Terá um valor para cada instância da pattern (%a%d) encontrada, então irá printar a1, a2, a3, a4 e a5. string.match: case1, case2 = string.match("Eu tenho 50 reais", "(%d+) (%a+)")
case1 → Primeira captura que equivale a pattern (%d+) (case1 = 50);
case2 → Segunda captura que equivale a pattern (%a+) (case2 = reais);
Referência
http://www.lua.org/manual/5.1/pt/manual.html#5.4.1
http://lua-users.org/wiki/PatternsTutorial
Então é isso, espero ter sido o mais claro possivel,
Qualquer dúvida, erro ou sugestão, poste ! -
detoneitormen deu reputação a vmf91 em Entendendo O Comando Os.time() Para Vip SystemSe você já se perguntou: Por que na coluna vip_time aparece um número absurdo, se eu adicionei apenas alguns dias vip?
Aqui encontrará a resposta!
Os players do seu server que tem conta VIP terão em sua vip_time um número parecido com este: 1344747131
Mas, o que este número quer dizer?
Este número é o tempo em segundos medido desde a Era Unix, ou seja, desde 1 de Janeiro de 1970 às 00:00:00.
Logo...
Digamos que no dia 1 de janeiro de 2012 às 0h, eu tenha adicionado 1 dia vip em determinada conta do meu server.
O número que aparecerá na vip_time será: 1324512000
Que é, aproximadamente, o resultado de: 42 anos * 365 dias * 24 horas * 60 minutos * 60 segundos.
Ou seja, o tempo medido em segundos desde 1 de janeiro de 1970 até 1 de janeiro de 2012.
Este foi apenas o meu primeiro tutorial.
Se copiar estas informações em qualquer outro fórum, por favor, cite-me.
-
detoneitormen deu reputação a Skyforever em [CreatureScripts] Reflect Amulet Healerem data/creaturescripts/scripts crie um arquivo e renomeie para um nome desejado e adicione isso dentro:
agora as tags
-------------- tags ------------
<event type="statschange" name="ReflectHeal" event="script" value="nome_do_script.lua"/> registerCreatureEvent(cid, "ReflectHeal")
------------ ----------------------
em items.xml substitua:
por
se baseia num script que quando você usa um certo amuleto e a chance e maior que 25 você recebe 15% de hp do dano recebido
QUALQUER ERRO REPORTE NO TÓPICO(tirando os de ortografia)
-
detoneitormen deu reputação a Garou em Perfect Upgrade SystemSistema atualizado, mais limpo e com novas funções.
-
detoneitormen deu reputação a Garou em Perfect Upgrade SystemObrigado pelos reports. Todos os bugs foram arrumados.
-
detoneitormen deu reputação a Garou em Perfect Upgrade SystemNome: Perfect Upgrade System
Tipo: Biblioteca, Action, Sistema
Autor: Oneshot
Essa é a versão final do Perfect Refine System ou Perfect Upgrade System criado por mim.
É um sistema construído em cima de funções em POO (orientação a objetos), o que o torna muito versátil, possibilitando a outros programadores/scripters criarem seus próprios sistemas com base na biblioteca.
A função do sistema é simples. Não passa de um sistema de refino, presente em todos os servidores, onde você usa um item em um equipamento e este fica mais forte e ganha um nome caracterizando o nível de força - bem clichê - mas muito interessante.
Meu sistema é um pouco diferente dos outros, pois possui algumas características exclusivas, listadas abaixo:
O nível máximo configurável é praticamente ilimitado O sistema funciona com armas de combate corpo-a-corpo, bows e crossbows. O refino pode falhar, não acontecendo nada, regredindo o nível ou resetando ele. Há um sistema nativo de broadcasts, que são enviados quando um jogador consegue refinar um equipamento até um certo nível ou maior. As chances são configuradas manualmente e sua randomização é muito precisa. Há dois modos de instalar o sistema em seu servidor, o primeiro é baixar a pasta com os scripts necessários e apenas copiar as chaves nos arquivos XMLs ou então seguir o curto tutorial de instalação.
Crie um arquivo chamado upgradesystem.lua na pasta data/lib e copie o conteúdo abaixo:
--[[ PERFECT UPGRADE SYSTEM 2.0 Criado por Oneshot É proibido a venda ou a cópia sem os devidos créditos desse script. ]]-- UpgradeHandler = { levels = { [1] = {100, false, false}, [2] = {90, false, false}, [3] = {75, false, false}, [4] = {60, true, false}, [5] = {45, true, false}, [6] = {30, true, false}, [7] = {25, true, false}, [8] = {20, true, true}, [9] = {15, true, true}, [10] = {10, true, true}, [11] = {10, true, true}, [12] = {5, true, true} }, broadcast = 7, attributes = { ["attack"] = 2, ["defense"] = 1, ["armor"] = 1 }, message = { console = "Trying to refine %s to level +%s with %s%% success rate.", success = "You have upgraded %s to level +%s", fail = "You have failed in upgrade of %s to level +%s", downgrade = "The upgrade level of %s has downgraded to +%s", erase = "The upgrade level of %s has been erased.", maxlevel = "The targeted %s is already on max upgrade level.", notupgradeable = "This item is not upgradeable.", broadcast = "The player %s was successful in upgrading %s to level +%s.\nCongratulations!!", invalidtool = "This is not a valid upgrade tool.", toolrange = "This upgrade tool can only be used in items with level between +%s and +%s" }, tools = { [8306] = {range = {0, 10}, info = {chance = 0, removeable = true}}, }, isEquipment = function(self) local weaponType = self:getItemWeaponType() return ((weaponType > 0 and weaponType < 7) or self.item.armor ~= 0) end, setItemName = function(self, name) return doItemSetAttribute(self.item.uid, "name", name) end, chance = function(self) local chances = {} chances.upgrade = (self.levels[self.item.level + 1][1] or 100) chances.downgrade = (self.item.level * 5) chances.erase = (self.item.level * 3) return chances end } function UpgradeHandler:new(item) local obj, ret = {} obj.item = {} obj.item.level = 0 obj.item.uid = item.uid for key, value in pairs(getItemInfo(item.itemid)) do obj.item[key] = value end ret = setmetatable(obj, {__index = function(self, index) if _G[index] then return (setmetatable({callback = _G[index]}, {__call = function(self, ...) return self.callback(item.uid, ...) end})) else return UpgradeHandler[index] end end}) if ret:isEquipment() then ret:update() return ret end return false end function UpgradeHandler:update() self.item.level = (tonumber(self:getItemName():match("%+(%d+)")) or 0) end function UpgradeHandler:refine(uid, item) if not self.item then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, self.message.notupgradeable) return "miss" end local tool = self.tools[item.itemid] if(tool == nil) then doPlayerSendTextMessage(uid, MESSAGE_EVENT_DEFAULT, self.message.invalidtool) return "miss" end if(self.item.level > #self.levels) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.maxlevel:format(self.item.name)) return "miss" end if(self.item.level < tool.range[1] or self.item.level >= tool.range[2]) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.toolrange:format(unpack(tool.range))) return "miss" end local chance = (self:chance().upgrade + tool.info.chance) doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, self.message.console:format(self.item.name, (self.item.level + 1), math.min(100, chance))) if(tool.info.removeable == true) then doRemoveItem(item.uid, 1) end if chance * 100 > math.random(1, 10000) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_ORANGE, self.message.success:format(self.item.name, (self.item.level + 1))) if (self.item.level + 1) >= self.broadcast then doBroadcastMessage(self.message.broadcast:format(getCreatureName(uid), self.item.name, (self.item.level + 1))) end self:setItemName((self.item.level > 0 and self:getItemName():gsub("%+(%d+)", "+".. (self.item.level + 1)) or (self:getItemName() .." +1"))) for key, value in pairs(self.attributes) do if getItemAttribute(self.item.uid, key) ~= nil or self.item[key] ~= 0 then doItemSetAttribute(self.item.uid, key, (self.item.level > 0 and getItemAttribute(self.item.uid, key) or self.item[key]) + value) end end return "success" else if(self.levels[self.item.level][3] == true and (self:chance().erase * 100) > math.random(1, 10000)) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.erase:format(self.item.name)) self:setItemName(self.item.name) for key, value in pairs(self.attributes) do if self.item[key] > 0 then doItemSetAttribute(self.item.uid, key, self.item[key]) end end elseif(self.levels[self.item.level][2] == true and (self:chance().downgrade * 100) > math.random(1, 10000)) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.downgrade:format(self.item.name, (self.item.level - 1))) self:setItemName((self.item.level == 1 and self.item.name or self:getItemName():gsub("%+(%d+)", "+".. (self.item.level - 1)))) for key, value in pairs(self.attributes) do if getItemAttribute(self.item.uid, key) ~= nil or self.item[key] ~= 0 then doItemSetAttribute(self.item.uid, key, (self.item[key] + value * (self.item.level - 1))) end end else doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.fail:format(self.item.name, (self.item.level + 1))) end return "fail" end end Crie um arquivo chamado upgrade.lua em data/actions/scripts e cole o conteúdo abaixo:
function onUse(cid, item, fromPosition, itemEx, toPosition) if isCreature(itemEx.uid) then return doPlayerSendDefaultCancel(cid, RETURNVALUE_NOTPOSSIBLE) end local obj = UpgradeHandler:new(itemEx) if(obj == false) then return doPlayerSendCancel(cid, UpgradeHandler.message.notupgradeable) end local status = obj:refine(cid, item) if status == "success" then --doSendAnimatedText(toPosition, "Success!", COLOR_GREEN) doSendMagicEffect(toPosition, CONST_ME_MAGIC_GREEN) elseif status == "fail" then --doSendAnimatedText(toPosition, "Fail!", COLOR_RED) doSendMagicEffect(toPosition, CONST_ME_POFF) else doSendMagicEffect(toPosition, CONST_ME_POFF) end return true end No arquivo actions.xml, cole a seguinte linha:
<action itemid="8306" event="script" value="upgrade.lua"/> Para adicionar mais níveis de refino no sistema, edite a seguinte tabela:
levels = { [1] = {100, false, false}, [2] = {90, false, false}, [3] = {75, false, false}, [4] = {60, true, false}, [5] = {45, true, false}, [6] = {30, true, false}, [7] = {25, true, false}, [8] = {20, true, true}, [9] = {15, true, true}, [10] = {10, true, true} }, Por padrão, ela já está configurado como na maioria dos MMORPGs, 10 níveis de refino, com chances de sucesso, regressão e "quebra". Mas se você quiser, por exemplo, adicionar mais dois níveis, siga o modelo, sempre colocando uma vírgula no final com exceção da última linha da tabela:
levels = { [1] = {100, false, false}, [2] = {90, false, false}, [3] = {75, false, false}, [4] = {60, true, false}, [5] = {45, true, false}, [6] = {30, true, false}, [7] = {25, true, false}, [8] = {20, true, true}, [9] = {15, true, true}, [10] = {10, true, true}, [11] = {10, true, true}, [12] = {5, true, true} }, O primeiro valor é chance de sucesso, o segundo se o item pode regredir na tentativa e o terceiro é se o item para "quebrar" (perder todo o nível de refino). Para criar novas ferramentas (itens) de refinar, configure a tabela abaixo:
tools = { [8306] = {range = {0, 10}, info = {chance = 0, removeable = true}}, }, Seguindo o mesmo esquema da tabela anterior, vírgulas em todas as linhas com exceção da última, seguindo o modelo abaixo. Por exemplo, uma ferramenta de ID 8303 que refine do level +6 ao +10, que dê 10% de chance bônus e que seja finita, eu faço assim:
tools = { [8306] = {range = {0, 10}, info = {chance = 0, removeable = true}}, [8310] = {range = {6, 10}, info = {chance = 10, removeable = true}} }, Em breve vídeo de demonstração com sistema em funcionamento.
Perfect Upgrade System.rar