Welcome to xTibia - Sua comunidade de Otserv e Tibia

Registre-se para utilizar nossas ferramentas e baixar conteúdos. Quando registrado e logado em sua conta, lhe garantimos uma experiência incrível em nossa comunidade!

MaXwEllDeN

Como funcionam os scripts?

Avalie este tópico:

28 posts neste tópico

Como funcionam os Scripts?



Você já deve ter se perguntado como os scripts funcionam ou não. Por exemplo: Como o servidor sabe que quando eu apertar com o botão direito em um Health Potion ele terá que healar o player alvo?

Em primeiro lugar devemos entender o que são callbacks. Do modo mais simples callback é algo que acontece devido a uma reação, é como a

Registre-se para ver link(s).

que diz que toda ação gera uma reação, esse callback é a nossa reção, é uma função que vai ser executada assim que algo acontecer, no caso do Health Potion assim que ele for usado.


Quando um item é usado ele provoca a chamada de um callback dessa função:



function onUse(cid, item, fromPosition, itemEx, toPosition)
end


Max, que parâmetros são esses? :hum:
– É simples.




cid - É o CreatureID de quem usou o item.

NOTA: Seu OT possui várias criaturas, para seu servidor, todas as criaturas são representadas por um Número Único(Não é possível ter duas criaturas com o mesmo UniqueID(UID)). Esse número nunca é o mesmo, sempre que você loga no servidor ele muda, e é um número geralmente gigante, do tipo 11789789. Para o programador não é necessário conhecer o número, só saber que ele é representado na maioria das vezes pelo cid(CreatureID).


item -É uma tabela contendo as informações do item que foi usado, em servidores 8.60 essa tabela tem a seguinte estrutura(provavelmente em versões superiores a estrutura é a mesma):
 

item = {actionid = 0, uid = 70000, itemid = 7618, type = 18}
Onde actionid é a actionid do item.

uid é o UniqueID do item, é parecido com o CreatureID das criaturas, só muda que ele serve para identificar itens, não criaturas, mas a ideia dele é a mesma, ele serve para identificar um item entre todos os itens que tem no seu servidor.

itemid é o id do item que foi usado, no caso um Health Potion.

type - Ele indica a quantidade de itens que tem no grupo que foi usado. Nesse caso eu tinha 18 Health Potions.

 



fromPosition - Essa é a posição que os Potions estavam quando eu usei eles.

itemEx - Se o alvo for um item vai retornar uma tabela igual à item, mas com as informações do item-alvo. Se o alvo for uma criatura, o itemEx.uid, será o CreatureID do alvo.

toPosition - Retorna uma tabela da posição do alvo(Do SQM que estava na mira do Crosshair).

 

O Script do Health Potion ficaria +/- assim:
 

local config = {
        min_heal = 100, -- Minimo que vai healar
        max_heal = 200, -- Máximo que vai healar
        empty = 7636, -- Id do Potion vazio
}
 
function onUse(cid, item, fromPosition, itemEx, toPosition)
        if isCreature(itemEx.uid) then
                doCreatureSay(cid, "Aaaah...", 19)
                doSendMagicEffect(toPosition, 12)
                doCreatureAddHealth(itemEx.uid, math.random(config.min_heal, config.max_heal))
                doTransformItem(item.uid, config.empty)
        else
                doPlayerSendCancel(cid, "You cannot use this object.")
        end
 
        return true
end


Funções usadas:

isCreature(uid) - Retorna um booleano, que indica se o parâmetro dado é uma criatura.

doCreatureSay(uid, words, type) - Faz a criatura uid, falar as palavras que estiverem no parâmetro word, e type é o tipo da Talk. Esses são os types existentes:

Types:
[spoiler]


TALKTYPE_FIRST = 1
TALKTYPE_SAY = TALKTYPE_FIRST
TALKTYPE_WHISPER = 2
TALKTYPE_YELL = 3
TALKTYPE_PRIVATE_PN = 4
TALKTYPE_PRIVATE_NP = 5
TALKTYPE_PRIVATE = 6
TALKTYPE_CHANNEL_Y = 7
TALKTYPE_CHANNEL_W = 8
TALKTYPE_RVR_CHANNEL = 9
TALKTYPE_RVR_ANSWER = 10
TALKTYPE_RVR_CONTINUE = 11
TALKTYPE_BROADCAST = 12
TALKTYPE_CHANNEL_RN = 13
TALKTYPE_PRIVATE_RED = 14
TALKTYPE_CHANNEL_O = 15
TALKTYPE_CHANNEL_RA = 17
TALKTYPE_MONSTER = 19
TALKTYPE_MONSTER_YELL = 20
TALKTYPE_LAST = TALKTYPE_MONSTER_YELL
[/spoiler]

doSendMagicEffect(pos, id) - Manda um efeito de ID, id, na posição pos.

Lista dos ids de efeito:
[spoiler]

CONST_ME_DRAWBLOOD = 0
CONST_ME_LOSEENERGY = 1
CONST_ME_POFF = 2
CONST_ME_BLOCKHIT = 3
CONST_ME_EXPLOSIONAREA = 4
CONST_ME_EXPLOSIONHIT = 5
CONST_ME_FIREAREA = 6
CONST_ME_YELLOW_RINGS = 7
CONST_ME_GREEN_RINGS = 8
CONST_ME_HITAREA = 9
CONST_ME_TELEPORT = 10
CONST_ME_ENERGYHIT = 11
CONST_ME_MAGIC_BLUE = 12
CONST_ME_MAGIC_RED = 13
CONST_ME_MAGIC_GREEN = 14
CONST_ME_HITBYFIRE = 15
CONST_ME_HITBYPOISON = 16
CONST_ME_MORTAREA = 17
CONST_ME_SOUND_GREEN = 18
CONST_ME_SOUND_RED = 19
CONST_ME_POISONAREA = 20
CONST_ME_SOUND_YELLOW = 21
CONST_ME_SOUND_PURPLE = 22
CONST_ME_SOUND_BLUE = 23
CONST_ME_SOUND_WHITE = 24
CONST_ME_BUBBLES = 25
CONST_ME_CRAPS = 26
CONST_ME_GIFT_WRAPS = 27
CONST_ME_FIREWORK_YELLOW = 28
CONST_ME_FIREWORK_RED = 29
CONST_ME_FIREWORK_BLUE = 30
CONST_ME_STUN = 31
CONST_ME_SLEEP = 32
CONST_ME_WATERCREATURE = 33
CONST_ME_GROUNDSHAKER = 34
CONST_ME_HEARTS = 35
CONST_ME_FIREATTACK = 36
CONST_ME_ENERGYAREA = 37
CONST_ME_SMALLCLOUDS = 38
CONST_ME_HOLYDAMAGE = 39
CONST_ME_BIGCLOUDS = 40
CONST_ME_ICEAREA = 41
CONST_ME_ICETORNADO = 42
CONST_ME_ICEATTACK = 43
CONST_ME_STONES = 44
CONST_ME_SMALLPLANTS = 45
CONST_ME_CARNIPHILA = 46
CONST_ME_PURPLEENERGY = 47
CONST_ME_YELLOWENERGY = 48
CONST_ME_HOLYAREA = 49
CONST_ME_BIGPLANTS = 50
CONST_ME_CAKE = 51
CONST_ME_GIANTICE = 52
CONST_ME_WATERSPLASH = 53
CONST_ME_PLANTATTACK = 54
CONST_ME_TUTORIALARROW = 55
CONST_ME_TUTORIALSQUARE = 56
CONST_ME_MIRRORHORIZONTAL = 57
CONST_ME_MIRRORVERTICAL = 58
CONST_ME_SKULLHORIZONTAL = 59
CONST_ME_SKULLVERTICAL = 60
CONST_ME_ASSASSIN = 61
CONST_ME_STEPSHORIZONTAL = 62
CONST_ME_BLOODYSTEPS = 63
CONST_ME_STEPSVERTICAL = 64
CONST_ME_YALAHARIGHOST = 65
CONST_ME_BATS = 66
CONST_ME_SMOKE = 67
CONST_ME_INSECTS = 68
CONST_ME_DRAGONHEAD = 69
CONST_ME_NONE = 255
CONST_ME_LAST = CONST_ME_DRAGONHEAD
[/spoiler]

doCreatureAddHealth(uid, amount) - Adiciona amount de health à criatura uid.
math.random(interval1, interval2) - Pega um número aleatório entre interval1 e interval2.
doTransformItem(uid, newid) - Muda o id do item uid, para newid.


doPlayerSendCancel(uid, text) - Manda uma mensagem text para criatura uid.


 

tv_Kb.png

 

 



Bem, esse aí é o script, agora só é você salvar, colocar na sua pasta actions/scripts e pronto!

– Max, se existem vários scripts na pasta actions/scripts, como meu OT sabe qual usar?
– Por causa das chamadas TAGs.
TAGs?
– Sim, é uma linha que é colocada no .xml para dizer ao seu servido que o Callback para um item x será a função daquele script.

As Tags das actions seguem esse modelo:
 

<action itemid = "7618" event = "script" value = "HealthPotion.lua" />

itemid - É o id do item, que ao ser usado o callback dele vai ser o script que está em value, no caso HealthPotion.lua
event - Indica o que vai acontecer quando usar o item, no caso vai ler o script. Não precisa se preocupar com isso por enquanto.
value - É o nome do script que tem o callback que você quer usar no item 7618

Exercício: Crie uma Action que quando eu usar uma Warlord Sword em alguém essa pessoa diga "Aí, isso doi". Poste a TAG também!

Resposta SÓ ABRA DEPOIS DE RESOLVER:
[spoiler]



function onUse(cid, item, fromPosition, itemEx, toPosition)
if isCreature(itemEx.uid) then
doCreatureSay(itemEx.uid, "Aí isso doi", 1)
end

return true
end

Tag:

<action itemid = "2408" event = "script" value = "Warlord.lua"/>

[/spoiler]

É isso aí pessoal, essa foi a primeira aula de Scriptwriting que eu escreví, espero que gostem :3

Compartilhar este post


Link para o post
Compartilhar em outros sites
Parabéns e obrigado por compartilhar o conteúdo!

Aprovado e movido! [img]http://www.xtibia.com/forum//public/style_emoticons/default/button_ok.png[/img][size=4] [/size]

Compartilhar este post


Link para o post
Compartilhar em outros sites

Postado (editado) · Denunciar post

[code]function onUse(cid, item, frompos, item2, topos)

if isCreature(itemEx.uid) then
doCreatureSay(itemEx.uid, "Aí, isso doi") then

end

return true
end

[/code] Editado por AlexandreGiacobo

Compartilhar este post


Link para o post
Compartilhar em outros sites

Postado (editado) · Denunciar post


Muito bom Max!
Essa aula com certeza, abre a mente das pessoas
que querem fazer scripts.
Parabéns!
Abraços.


Obrigado ^^.


Ótimo tutorial Max.

[spoiler][pastebin]Hhf20Ruz[/pastebin][/spoiler]


Só uma coisinha desnecessária que você colocou Sky.

[pastebin]END9a7iW[/pastebin]


function onUse(cid, item, frompos, item2, topos)

if isCreature(itemEx.uid) then
doCreatureSay(itemEx.uid, "Aí, isso doi") then

end

return true
end


Quase certo, mas dá uma olhada. No seu script, o alvo do item está sendo chamado de item2. Tem duas soluções para o seu problema. Ou você muda o nome da variável para itemEx, ou usa item2 no lugar de itemEx.

Mudando o nome da variável para itemEx:

Antes:

function onUse(cid, item, frompos, item2, topos)
if isCreature(itemEx.uid) then
doCreatureSay(itemEx.uid, "Aí, isso doi") then
end
return true
end



Depois:

function onUse(cid, item, frompos, itemEx, topos)
if isCreature(itemEx.uid) then
doCreatureSay(itemEx.uid, "Aí, isso doi")
end
return true
end

Usando item2 no lugar de itemEx:

Antes:

function onUse(cid, item, frompos, item2, topos)
if isCreature(itemEx.uid) then
doCreatureSay(itemEx.uid, "Aí, isso doi") then
end
return true
end

Depois:

function onUse(cid, item, frompos, item2, topos)
if isCreature(item2.uid) then
doCreatureSay(item2.uid, "Aí, isso doi")
end
return true
end

Abraço! Editado por MaXwEllDeN

Compartilhar este post


Link para o post
Compartilhar em outros sites
-Max

Obrigado por corrigir só vi teu tópico e fiz correndo nem prestei atenção no que tava botando,agora posso olhar com calma.

Aguardando ansiosamente seus novos tutoriais/exercícios!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Postado (editado) · Denunciar post

só esqueceu de checar se é um player,n faria semtido uma slime falar ou um ghost falar que doi
ashusahusahsau

seriam sempre bom pensar nos minimos,tanto pela jogabilidade, quanto para n cometer erros como esquecer que os player podem estar usando utamo vita.

Editado por lordbug99

Compartilhar este post


Link para o post
Compartilhar em outros sites
[quote name='lordbug99' timestamp='1367438046' post='1514228']
só esqueceu de checar se é um player,n faria sendito uma slime falar ou um ghost falar que doi
ashusahusahsau

seriam sempre bom pensar nos minomos,tanto pela jogabilidade, quanto para n cometer erros como esquecer que os player podem estar usando utamo vita.
[/quote]

Cara, esse script é só pra exercitar as funções, não é útil pra ninguém um script como esse. E se fosse pra alguém usar em um servidor, seria mais viável criar uma tabela e dentro dela colocar o nome das criaturas que não falam, e se o alvo fosse uma delas, retornaria falso. Pois não são só players que falam, certo?

Compartilhar este post


Link para o post
Compartilhar em outros sites
sim mas to falando, mas porque as veses as pessoas esquecem de considerar fatores que podem prejudicar o script(no caso de script é meio inutel).

como um script que mate o player instanteneamente
[code]
function onSay(cid,param)
local player = getPlayerByName(param)
if player then
doTargetCombatHealth(cid, player, COMBAT_PHYSICALDAMAGE, -getCreatureMaxHealth(player), -getCreatureMaxHealth(player), CONST_ME_MORTAREA)
return true
end
end
[/code]

ve qual é o erro desse script?

Compartilhar este post


Link para o post
Compartilhar em outros sites
[quote name='lordbug99' timestamp='1367597757' post='1515046']
sim mas to falando, mas porque as veses as pessoas esquecem de considerar fatores que podem prejudicar o script(no caso de script é meio inutel).

como um script que mate o player instanteneamente
[code]
function onSay(cid,param)
local player = getPlayerByName(param)
if player then
doTargetCombatHealth(cid, player, COMBAT_PHYSICALDAMAGE, -getCreatureMaxHealth(player), -getCreatureMaxHealth(player), CONST_ME_MORTAREA)
return true
end
end
[/code]

ve qual é o erro desse script?
[/quote]
Tlg, esquecem mesmo. Mas o objetivo do tópico foi ensinar sobre as funções. Isso ai que você tá falando é PENSAR e isso é algo que eu não posso ensinar a alguém.

Bem, isso que você esqueceu de colocar não é considerado um erro, se o script carregar e rodar, está tudo certo, já que ele foi feito pra ser rodado assim, então não tem nenhum erro. A falta da verificação se a criatura existe já é falha do programador em não pensar na possibilidade da criatura não existir, e é como eu disse, isso depende se o cara sabe pensar.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Bom pessoal o meu script ficou diferente, porque eu fiz ele diferente...

ai esta o script:

[spoiler]function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000)
doCreatureSay(cid, "Aaaaii Delicia",19)
doPlayerSendCancel(uid, PEEEEIDEEEI)
end

return true

[/spoiler]

nesse meu script além de ele falar a palavra, ele da 15000 de Experiencia...

Compartilhar este post


Link para o post
Compartilhar em outros sites
[quote name='mazonifelipe' timestamp='1367613189' post='1515152']
Bom pessoal o meu script ficou diferente, porque eu fiz ele diferente...

ai esta o script:

[spoiler]function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000)
doCreatureSay(cid, "Aaaaii Delicia",19)
doPlayerSendCancel(uid, PEEEEIDEEEI)
end

return true

[/spoiler]

nesse meu script além de ele falar a palavra, ele da 15000 de Experiencia...
[/quote]

Não vai funcionar bem como no exercício. Olha ai está o seu código, comentado:

[code]
function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000) -- Vai adicionar 15000 de experiência para o player que usou a espada em alguém
doCreatureSay(cid, "Aaaaii Delicia",19) -- O player que usou a espada vai falar Aaaaaai Delicia
doPlayerSendCancel(uid, PEEEEIDEEEI) -- Vai dar erro, 1º Porque uid não é uma criatura válida, segundo porque PEEEEEEEEEEEIDEI não é uma string("PEEEEEEEEIDEIIIII", com àspas)
end

return true -- return true no lugar errado
[/code]

Correção no seu código:

[code]
function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000) -- Vai adicionar 15000 de experiência para o player que usou a espada em alguém
doCreatureSay(itemEx.uid, "Aaaaii Delicia",19) -- O player que estiver na mira da espada vai falar Aaaaaai Delicia
doPlayerSendCancel(cid, "PEEEEIDEEEI") -- Você vai receber uma mensagem dizendo: PEEIIDEEEI
return true -- No lugar certo
end
[/code]

Compartilhar este post


Link para o post
Compartilhar em outros sites
[quote name='MaXwEllDeN' timestamp='1367634050' post='1515352']
[quote name='mazonifelipe' timestamp='1367613189' post='1515152']
Bom pessoal o meu script ficou diferente, porque eu fiz ele diferente...

ai esta o script:

[spoiler]function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000)
doCreatureSay(cid, "Aaaaii Delicia",19)
doPlayerSendCancel(uid, PEEEEIDEEEI)
end

return true

[/spoiler]

nesse meu script além de ele falar a palavra, ele da 15000 de Experiencia...
[/quote]

Não vai funcionar bem como no exercício. Olha ai está o seu código, comentado:

[code]
function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000) -- Vai adicionar 15000 de experiência para o player que usou a espada em alguém
doCreatureSay(cid, "Aaaaii Delicia",19) -- O player que usou a espada vai falar Aaaaaai Delicia
doPlayerSendCancel(uid, PEEEEIDEEEI) -- Vai dar erro, 1º Porque uid não é uma criatura válida, segundo porque PEEEEEEEEEEEIDEI não é uma string("PEEEEEEEEIDEIIIII", com àspas)
end

return true -- return true no lugar errado
[/code]

Correção no seu código:

[code]
function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000) -- Vai adicionar 15000 de experiência para o player que usou a espada em alguém
doCreatureSay(itemEx.uid, "Aaaaii Delicia",19) -- O player que estiver na mira da espada vai falar Aaaaaai Delicia
doPlayerSendCancel(cid, "PEEEEIDEEEI") -- Você vai receber uma mensagem dizendo: PEEIIDEEEI
return true -- No lugar certo
end
[/code]
[/quote]

[b]áa,, você poderia me explicar o porque? que o Return true tem que ficar naquele lugar?[/b]

Compartilhar este post


Link para o post
Compartilhar em outros sites
[quote name='mazonifelipe' timestamp='1367794067' post='1516332']
[quote name='MaXwEllDeN' timestamp='1367634050' post='1515352']
[quote name='mazonifelipe' timestamp='1367613189' post='1515152']
Bom pessoal o meu script ficou diferente, porque eu fiz ele diferente...

ai esta o script:

[spoiler]function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000)
doCreatureSay(cid, "Aaaaii Delicia",19)
doPlayerSendCancel(uid, PEEEEIDEEEI)
end

return true

[/spoiler]

nesse meu script além de ele falar a palavra, ele da 15000 de Experiencia...
[/quote]

Não vai funcionar bem como no exercício. Olha ai está o seu código, comentado:

[code]
function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000) -- Vai adicionar 15000 de experiência para o player que usou a espada em alguém
doCreatureSay(cid, "Aaaaii Delicia",19) -- O player que usou a espada vai falar Aaaaaai Delicia
doPlayerSendCancel(uid, PEEEEIDEEEI) -- Vai dar erro, 1º Porque uid não é uma criatura válida, segundo porque PEEEEEEEEEEEIDEI não é uma string("PEEEEEEEEIDEIIIII", com àspas)
end

return true -- return true no lugar errado
[/code]

Correção no seu código:

[code]
function onUse(cid, item, fromPosition, itemEx, toPosition)
doPlayerAddExperience(cid, 15000) -- Vai adicionar 15000 de experiência para o player que usou a espada em alguém
doCreatureSay(itemEx.uid, "Aaaaii Delicia",19) -- O player que estiver na mira da espada vai falar Aaaaaai Delicia
doPlayerSendCancel(cid, "PEEEEIDEEEI") -- Você vai receber uma mensagem dizendo: PEEIIDEEEI
return true -- No lugar certo
end
[/code]
[/quote]

[b]áa,, você poderia me explicar o porque? que o Return true tem que ficar naquele lugar?[/b]
[/quote]
Porque tipo, do modo que você colocou, ele estava fora da função e, fora da função principal ele é inútil, ai ele tem que ser colocado no final da função principal, antes do último end, pra indicar que ocorreu tudo bem!

Compartilhar este post


Link para o post
Compartilhar em outros sites