Welcome to xTibia - Sua comunidade de Otserv e Tibia

Register now to gain access to all of our features. Once registered and logged in, you will be able to contribute to this site by submitting your own content or replying to existing content. You'll be able to customize your profile, receive reputation points as a reward for submitting content, while also communicating with other members via your own private inbox, plus much more! This message will be removed once you have signed in.

MaXwEllDeN

Como funcionam os scripts?

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

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!


Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.


Entrar Agora