Ir para conteúdo

Featured Replies

Postado
  • Este é um post popular.

Tutorial de NPCS

Esse tutorial irá servir para quem gostar de fazer certo NPCs mais complexos com storages, varias missões e tudo mais.

Usando como base o Jiddo system apenas para comprar e vender itens, pois não gosto de usar sistemas que facilitam

Pois não criam scripters e sim preguiçosos, ainda mais quando o sistema é abandonado ai você se lasca :P

O npc é dividido em duas partes :

- Arquivo XML : Responsavel pelo visual e algumas propriedades dele (pelo jiddo system)

- Arquivo Lua : Responvasel pelas falas e vendas (Lua puro)

Visual do Npc

Bem primeiro vamos explicar o visual de um npc,


<npc name="Bonifacius" script="data/npc/scripts/default.lua" walkinterval="25" floorchange="0" access="5" level="1" maglevel="1">

	 <health now="150" max="150"/>

	 <look type="128" head="97" body="100" legs="115" feet="114" corpse="2212"/>

</npc>

Explicando parte a parte Name : Nome dele que aparecerá para todos. script : Arquivo lua do script dele walkinterval : De quanto em quanto milessegundos ele irá caminhar. floorchange : Se ele irá subir escadas ou cair em buracos. access : O valor de acesso dele, caso ele tenha um acesso 5 poderá usar todo os comandos de GODS. level,maglevel : É tosco, você pode fazer ele soltar magias (nunca tentei) e no caso isso contaria. Health Now : Sangue que terá max : Maximo de health (ja fizeram npc com life media) look type : Tipo de roupa dele, Caso queira ele como objeto use look typeex. head,body,legs,feet : Cor da cabeça,corpo,calça e pé do npc. corpse : Corpo caso ele morra (LOL não dá...) Esse é a base do arquivo xml do npc. Caso você queirá enfiar tosquisses pelo Jiddo System fica mais ou menos assim:

<?xml version="1.0" encoding="UTF-8"?>

<npc name="Bonifacius" script="data/npc/scripts/default.lua" walkinterval="25" floorchange="0" access="5" level="1" maglevel="1">

	 <health now="150" max="150"/>

	 <look type="128" head="97" body="100" legs="115" feet="114" corpse="2212"/>

<parameters>

			 <parameter key="module_shop" value="1"/>

			 <parameter key="shop_buyable" value="banana,2676,2;grapes,2681,3;melon,2682,8;orange,2675,5;pumpkin,2683,10;chees

e,2696,5;egg,2695,2;cookie,2678,2;meat,2266,5"/>

			 <parameter key="message_greet" value="What you doing soldier ? Take your weapon and go war!"/>

			 <parameter key="message_walkaway" value="Hey Hey, where you go ?"/>

			 <parameter key="message_farewell" value="Bye bye brave soldier. Remember, peoples without head, don't transform in undeads."/>

			 <parameter key="message_alreadyfocused" value="You are drunked ? You talk really talk to me ?"/>

</parameters>

</npc> 
<parameters>

			 <parameter key="module_shop" value="1"/>

			 <parameter key="shop_buyable" value="banana,2676,2;grapes,2681,3;melon,2682,8;orange,2675,5;pumpkin,2683,10;chees

e,2696,5;egg,2695,2;cookie,2678,2;meat,2266,5"/>

			 <parameter key="message_greet" value="What you doing soldier ? Take your weapon and go war!"/>

			 <parameter key="message_walkaway" value="Hey Hey, where you go ?"/>

			 <parameter key="message_farewell" value="Bye bye brave soldier. Remember, peoples without head, don't transform in undeads."/>

			 <parameter key="message_alreadyfocused" value="You are drunked ? You talk really talk to me ?"/>

</parameters>
Esse é um exemplo basico de npc vendedor, que não faz muita coisa. module_shop : Quer dizer que ao falar trade ele irá abrir a janela tosca de venda de itens. shop_buyable : Isso faz tudo que tiver ai ele vender sendo a sintaxe

parameter key="shop_buyable" value="nome inutil (inutil mesmo não serve para nada),id do produto,preço;

Podendo você adicionar milhares e milhares, unico porém de você adicionar pelo XML é que não há possibilidade de fazer a venda por backpack (pelo menos até a versão que testei) message_farewell Mensagem de despedida Essas message tem alguns tipos explicados abaixo :
  Citar
greet - mensagem de boas vindas farewell - Mensagem de despedida buy - Mensagem de confirmação de compra onbuy - Sei la o0 bought - Mensagem de compra confirmada sell - Mensagem de confirmação de venda onsell - sei la o0 sold - Mensagem venda confirmada missingmoney - Que você ta liso (sem nada) needmoney - Que você não tem dinheiro suficiente missingitem - Falta o item necessario needitem - Que você não te o item ou não tem a qtd suficiente needspace - Que falta espaço na bp para o item needmorespace - Que prescisa de mais alguns espaços idletimeout - Que você demoro e perdeu a vez walkaway - Saiu da visão dele decline - Que desistiu da ação sendtrade - Quando abre a janela de trade noshop - Que ele não tem janela de trade para mostrar oncloseshop - Que você fechou a janela de trade alreadyfocused - Que tu deu um tapa na pantera, ou seja, ele já está falando com você placedinqueque - Para você ter paciencia que já será atendido
Tudo isso acima deverá estar depois de message_ e as mensagens em default você poderá encontrar em npc/lib/npcsystem/npchandler.lua Se você fazer asneira lá os npcs não funfam cuidado o0 Ainda há o npc de barco, muito simples :

<parameter key="travel_destinations" value="desert,1594,835,5,180;edron,931,825,6,90;"/>

Sintaxe

	 value="nome da cidade ,coordenada x,coordenada y,coordenada z ,valor;"


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

npcHandler:addModule(FocusModule:new())

Ou seja npcs, que aquilo que mostrei no xml é suficiente você pode direcionar para o default.lua Eu disse que npcs feitos no XML, a opção de compra por backpack não é possivel Então para faze-la em um npc Lua ficará assim :

local keywordHandler = KeywordHandler:new()

local npcHandler = NpcHandler:new(keywordHandler)

NpcSystem.parseParameters(npcHandler)

local talkState = {}

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 shopModule = ShopModule:new()

npcHandler:addModule(shopModule)

shopModule:addBuyableItem({'health potion'}, 7618, 45, 1, 'health potion')

shopModule:addBuyableItem({'mana potion'}, 7620, 50, 1, 'mana potion')

shopModule:addBuyableItemContainer({'bp hp'}, 2000, 7618, 900, 1, 'backpack of health potions')

shopModule:addBuyableItemContainer({'bp mp'}, 2001, 7620, 1000, 1, 'backpack of mana potions')

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

npcHandler:addModule(FocusModule:new())

Nesse exemplo o npc vende health potion,mana potion e bp dos respectivos. Sendo a sintaxe

shopModule:addBuyableItem({'nome inutil'}, id preço, quantidade ou sub tipo, 'nome inutil')

Esse nome só serve para você não se perder, pois ao dizer trade ele aparecerá o nome do item pelo items.xml e não o que voce falou Sintaxe da backpack

shopModule:addBuyableItemContainer({'nome'}, id da backpack, id, preço, sub tipo ou quantidade (caso seja agrupavel), 'nome inutil')


local keywordHandler = KeywordHandler:new()

local npcHandler = NpcHandler:new(keywordHandler)

NpcSystem.parseParameters(npcHandler)

local talkState = {}

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

function creatureSayCallback(cid, type, msg)

	 if(not npcHandler:isFocused(cid)) then

			 return false

	 end

	 local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid


	 if msgcontains(msg, 'rainbow') or msgcontains (msg, 'perch') then

					 if getPlayerStorageValue(cid,30013) == 8 then

							 selfSay('Yeah. But peguins, stoled my last crate of this. Please go lair of this plague and take again my itens. You go ?', cid)

							 talkState[talkUser] = 1

					 else

							 selfSay('You are a lier. Leave here!', cid)

					 end

	 elseif msgcontains(msg, 'mission') then

					 if doPlayerRemoveItem(cid,7707,1) == 1 then

							 selfSay('Congratulations. Give this for Willard.', cid)

							 setPlayerStorageValue(cid,30013,10)

							 talkState[talkUser] = 0

					 else

							 selfSay('You don\'t have nothing!', cid)

					 end

	 elseif talkState[talkUser] == 1 then

			 if msgcontains(msg, 'yes') then

							 selfSay('Great. Later report me asking mission.', cid)

							 setPlayerStorageValue(cid,30013,9)

							 talkState[talkUser] = 0

			 else

							 selfSay('You don\'t have nothing!', cid)

			 end

	 end

	 return true

end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

npcHandler:addModule(FocusModule:new())

Esse npc ai é um simples de quest, você pode se basear nele para seu primeiro npc Vamos explicar umas coisas importantissimas talkState = Isso ai é a genialidade, a cada passo você pode mandar o player para um estagio. Se você leu meus tutos percebeu que ele é um vetor, mais por que ? Porque, ao ser uma variavel ele é armazenada no servidor certo ? Então se não fosse um vetor, o npc falando com dois ao mesmo tempo poderia se confudir e ferrar tudo literalmente Se você dominar o talkState dominará 50% de npcs de missões Storages = Isso também é indispensavel nos npcs, é sempre bom reservar uns para cada missão Para se ela tiver varias etapas você não se confudir, Ou usar o mesmo value para poder aproveitar no questlog (explicado no tutorial SUper Quests) O npc acima ele é 4º npc da minha quest global do meu otserver de testes. Ignore os erros de Inglês.

if msgcontains(msg, 'rainbow') or msgcontains (msg, 'perch') then

					 if getPlayerStorageValue(cid,30013) == 8 then

							 selfSay('Yeah. But peguins, stoled my last crate of this. Please go lair of this plague and take again my itens. You go ?', cid)

							 talkState[talkUser] = 1

					 else

							 selfSay('You are a lier. Leave here!', cid)

					 end

Aqui ao você falar rainbow ou perch ele começa a girar essa parte do script. Ou seja no caso eh msgcontains se você falar
  Citar
Sou gay rainbow e você é bobo,feio e chato
Ele irá entender normalmente, e rodará o script. Caso fosse msg ai sim teria quer ser certinho (até maiscula e miniscula acho que ele duvidaria) No caso ele checa o storage 30013 se tem o valor 8, caso tenha ele fala aquela frase enorme e muda seu talkstate para 1 Se não tiver o storage com valor 8, ele te ofende. Esse storage 8 é adicionado no npc anterior. Se você tiver tudo certo ele tem pergunto algo, porém isso só será checado no talkstate 1

elseif talkState[talkUser] == 1 then

			 if msgcontains(msg, 'yes') then

							 selfSay('Great. Later report me asking {mission}.', cid)

							 setPlayerStorageValue(cid,30013,9)

							 talkState[talkUser] = 0

			 else

							 selfSay('You don\'t have nothing!', cid)

			 end

Se você falar yes, ele manda você ir no penguim hell para você pegar os treco para ele. E te coloca o storage 30013 com valor 9.
  Citar
O valor do storage é fico importante depois da criação do quest log, pois nele os avanços da mesma missão Só pode ser feito pelo mesmo storage. Lembrando que depois do tfs 0.3.0 beta 1 , é possivel adicionar palavras no valor Podendo ser : setPlayerStorageValue(cid,30013,"estagio 1")
E veja que ele manda você falar mission quando completar
  Citar
Palavras entre { } de npcs fazem ele falar em palavras negriras
Vamos supor (não supositorio), que você completou ela e falo mission para ele. O que iria checar ?

	 elseif msgcontains(msg, 'mission') then

					 if doPlayerRemoveItem(cid,7707,1) == 1 then

							 selfSay('Congratulations. Give this for Willard.', cid)

							 setPlayerStorageValue(cid,30013,10)

							 talkState[talkUser] = 0

					 else

							 selfSay('You don\'t have nothing!', cid)

					 end

Se você fala mission, ele automaticamente remoe o item 7707 (dado na quest) e parabeniza você. Dando o storage 30013 com valor 10 O valor necessario para o npc anterior voltar a falar com você. Caso você seja caloteiro ele já te desmente. Bem simples, não ? Claro que esse npc é minisculo. Porém ja da para seguir como base. Olhe a evolução dele.
  Citar
Você veio com storage com valor 8. Ele te oferece uma missão. Ao aceitar seu storage vira 9. Se não aceitar você não pode fazer a quest. Ao fazer a quest ganha o item 7707. Ao falar novamente ele pede o item 7707. Se você entregar ganha storage valor 10.

local keywordHandler = KeywordHandler:new()

local npcHandler = NpcHandler:new(keywordHandler)

NpcSystem.parseParameters(npcHandler)

local talkState = {}

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

function creatureSayCallback(cid, type, msg)

	 if(not npcHandler:isFocused(cid)) then

			 return false

	 end

	 local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid


	 if msgcontains(msg, 'mission') then

					 if getPlayerStorageValue(cid,2411) == -1 then

							 selfSay('Entregue essa carta a minha irmã Clarice.', cid)

							 setPlayerStorageValue(cid,2411,1)

							 doPlayerAddItem(cid,8370,1)

					 else

							 selfSay('Eu ja te dei a carta, aguardo resposta', cid)

					 end

	 end

	 return true

end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

npcHandler:addModule(FocusModule:new())

Ai checamos se ele já fez a quest. No caso se tiver -1 (que nunca fez) ele poderá começa-la. E dará a carta ao player (item 8370 nem sei o que é) Ok. Essa parte ta montada, ele dá a carta. Situação : A NPC Clarice está cantarolando em sua casa, quando você chega com uma carta de seu irmão. Ela recebe de bom grado porém prescisa provar que recebeu. Porém seu jogador não sabe que existe storage value, então Você poderá enviar outra carta ou inventar que ela irá falar com ele.


local keywordHandler = KeywordHandler:new()

local npcHandler = NpcHandler:new(keywordHandler)

NpcSystem.parseParameters(npcHandler)

local talkState = {}

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

function creatureSayCallback(cid, type, msg)

	 if(not npcHandler:isFocused(cid)) then

			 return false

	 end

	 local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid


	 if msgcontains(msg, 'letter') then

					 if getPlayerStorageValue(cid,2411) == 1 then

					 selfSay('Ah você relmente tem a carta de meu amado irmão?', cid)

					 talkState[talkUser] = 1

					 else

					 selfSay('Ah seu fanfarao saia daqui', cid)

					 end


	 elseif talkState[talkUser] == 1 then

			 if msgcontains(msg, 'yes') then

							 if doPlayerRemoveItem(cid,8013,1) == 1 then

									 setPlayerStorageValue(cid,2411,2)

									 selfSay('Obrigada. Agora eu irei falar com ele sobre o assunto', cid)

									 talkState[talkUser] = 0

							 else

									 selfSay('Você não tem a carta dele', cid)

							 end

			 else

					 selfSay('Então porque veio aqui ?', cid)

			 end

	 end

	 return true

end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)

npcHandler:addModule(FocusModule:new())

Veja que ela é a prova de erros. Primeiro ao falar letter ela checa se você tem o storage com valor 1 (Ou seja, se você falo com ele) Se não falou ela já te manda pescar, se houver, ela já mete pergunta se você tem a carta Caso não já te manda pescar Caso sim ela tenta pergunta se voce tem a carta Caso diga não ela te manda pescar também, Caso fale sim ela tenta tirar sua carta, caso você tenha ela te agradece e coloca o storage com valor 2 Caso não tenha ela diz que você não tem a carta
  Citar
Manda pescar é um jeito delicado de mandar você ir tomar suco no orificio...
Vamos suport, que você aceitou e entregou a carta tudo certinho. Você deve voltar ao Valdemar para ele te dar algo não ? Situação : Você ja deu uma de carteiro e agora quer receber sua recompensa, então ao Oscar, Porém ele não é trouxa E como ele sabe se você ja fez tudo ? Uma dica começa com S e termina com orage...
  Citar
local keywordHandler = KeywordHandler:new() local npcHandler = NpcHandler:new(keywordHandler) NpcSystem.parseParameters(npcHandler) local talkState = {} 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 function creatureSayCallback(cid, type, msg) if(not npcHandler:isFocused(cid)) then return false end local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid if msgcontains(msg, 'mission') then if getPlayerStorageValue(cid,2411) == -1 then selfSay('Entregue essa carta a minha irmã Clarice.', cid) setPlayerStorageValue(cid,2411,1) doPlayerAddItem(cid,8370,1) else selfSay('Eu ja te dei a carta, aguardo resposta', cid) end elseif getPlayerStorageValue(cid,2411) == 2 then selfSay('Parabens. Você fez o pedido certinho! Receba sua recompensa!!!', cid) setPlayerStorageValue(cid,2411,3) doPlayerAddItem(cid,2160,1) else selfSay('Termine o serviço!', cid) end return true end npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new())
Vejam que eu usei a mesma palavra missão e adicionei um else. Se ele tiver o storage com valor 2 e falar missão, obviamente ele fez tudo e como é a ultima missão Não necessita fazer perguntas retoricas (sem resposta), então ele já da sua recompensa e ja fecha seu storage com 3.
  Citar
Fechar storage - Termo usado quando se acaba a missão no Questlog.

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

npcHandler:addModule(FocusModule:new())


Se você observar ele tem 4 funções ai que nem foram usadas.[/left]

onCreatureAppear(cid) : Ela faz uma ação quando o player entrar em seu raio de ação

onCreatureDisappear(cid) : Ela faz uma ação quando o player sai do seu raio de ação.

onCreaturesay(cid) : Quando o player fala algo.

onThink(cid) : Seria ao pensar ao achar, não tenho certeza do que faz, porém é uma função muito usada.

onCreatureMove(creature, oldPos, newPos) : Quando a criatura se move de um lugar para outro.




local target = 0

local prevTarget = 0

local maxChaseDistance = 20

local origPos = 0

local origDir = NORTH

local lastAttack = 0

local followTimeout = 10

local function isSkulled(cid)

	 local skullType = getPlayerSkullType(cid)

	 if(skullType >= 3) then

			 return true

	 end


return false

end

local function goToOrigPos()

	 target = 0

	 lastAttack = 0

	 selfFollow(0)

	 doTeleportThing(getNpcCid(), origPos)

end


local function updateTarget()

	 if(isPlayer(target) == FALSE) then

			 goToOrigPos()

	 elseif(not isSkulled(target)) then

			 target = 0

			 selfSay("Now, behave in the future.")

	 end

	 if(target == 0) then

			 local list = getSpectators(getNpcPos(), 8, 8, false)

			 for i=1, table.getn(list) do

					 local _target = list[i]

					 if(_target ~= 0) then

							 if(isPlayer(_target) == TRUE and isSkulled(_target)) then

									 if(selfFollow(_target)) then

											 target = _target

											 if(target ~= prevTarget) then

													 selfSay("We do not tolerate people like you here!")

											 end


prevTarget = target

											 break

									 end

							 end

					 end

			 end

	 end

end

function onCreatureAppear(cid)

	 if(cid == getNpcCid()) then

			 --Wake up call

			 origPos = getNpcPos()

			 --origLook = getCreatureDir(cid)

	 end

end


function onCreatureDisappear(cid)

	 if(target == cid) then

			 goToOrigPos()

	 end

end

function onCreatureMove(creature, oldPos, newPos)

	 --

end


function onThink()

	 updateTarget()

	 if(target == 0) then


return

	 end

	 local playerPos = getCreaturePosition(target)

	 local myPos = getNpcPos()


if(myPos.z ~= playerPos.z) then

			 goToOrigPos()

			 return

	 end

	 if(math.abs(myPos.x - origPos.x) > maxChaseDistance or math.abs(myPos.y - origPos.y) > maxChaseDistance) then

			 selfSay("I'll catch you next time.")

			 goToOrigPos()

			 return

	 end


if(lastAttack == 0) then

			 lastAttack = os.clock()

	 end

	 if(os.clock() - lastAttack > followTimeout) then

			 --To prevent bugging the npc by going to a place where he can't reach

			 selfSay("You got me this time, but just wait.")

			 goToOrigPos()

			 return

	 end


if( (math.abs(playerPos.x - myPos.x) <= 1) and (math.abs(playerPos.y - myPos.y) <= 1)) then

			 doTargetCombatHealth(getNpcCid(), target, COMBAT_LIFEDRAIN, -200, -300, CONST_ME_BLOCKHIT)

			 lastAttack = os.clock()

	 end

end



Bem a função updateTarget faz ele apenas fixar a target (alvo) players com skull white ou red. Então deixe ela para outro dia. Vamos verificar a onThink

function onThink()

	 updateTarget()

	 if(target == 0) then

			 return

	 end

	 local playerPos = getCreaturePosition(target)

	 local myPos = getNpcPos()

	 if(myPos.z ~= playerPos.z) then

			 goToOrigPos()

			 return

	 end

	 if(math.abs(myPos.x - origPos.x) > maxChaseDistance or math.abs(myPos.y - origPos.y) > maxChaseDistance) then

			 selfSay("I'll catch you next time.")

			 goToOrigPos()

			 return

	 end

	 if(lastAttack == 0) then

			 lastAttack = os.clock()

	 end

	 if(os.clock() - lastAttack > followTimeout) then

			 --To prevent bugging the npc by going to a place where he can't reach

			 selfSay("You got me this time, but just wait.")

			 goToOrigPos()

			 return

	 end

	 if( (math.abs(playerPos.x - myPos.x) <= 1) and (math.abs(playerPos.y - myPos.y) <= 1)) then

			 doTargetCombatHealth(getNpcCid(), target, COMBAT_LIFEDRAIN, -200, -300, CONST_ME_BLOCKHIT)

			 lastAttack = os.clock()

	 end

Explicando cada if.

- Primeiro ele checa se ele tem target, se não tiver recomeça o ontarget

- Segundo se ele verifica se o player está no mesmo andar que ele (coordenada z) se não tiver volta pro começo

- Terceiro ele verifica se o player está muito longe (distancia maxima especificada acima), caso esteja ele fala

mais ou menos "te pego na proxima" e volta pro seu respawn.

- Quarto Ele muda seu ultima attack para o tempo atual do servidor

- Quinto Ele verifica se ja passou o "tempo de descanso dele)

- Se o tiver na posição certa de ataque, ele mete o sabugo no player espacando ele. Até o player morrer ou fugir.

Entederam a logica ? Não !? Tudo bem. Vai treinando...

Sinceramente esse npc é o mais complexo que ja vi.

Eu entendi ele, porém não tenho animo de refaze-lo xD

É Isso.

Creditos : Tibiaa4e ( 99%) (Por Fazer).

xFatality ( 1% ) (Por trazer ao TK).

Obrigado,

Abraços.

Da para você fazer tudo do LUA no XML, porém eu acho estranho e apenas frescura do Jiddo e dos Developers do TFS (não sei developer em Português) Caso seja curioso olhe nos arquivos bankmax.xml, merchant.xml e postman.xml que estão em npc/lib Bem a parte XML já acabo, ou seja, ela é muito simples. NPCS EM LUA Aqui é a parte legal do npc na qual até certos scripters novos fazem coisas desnecessarias ou que pioram... A base do arquivo usando Jiddo System é
Ai sempre virá uma bp cheia dos item especificado. Caso não saiba ao clicar com o direito no TRADE e usar buy with backpack virá com isso ai Essa é a parte facil até agora tentarei pensar aqui 25 minutos um jeito de explicar muita coisa xD NPCS de Missões Bem aqui ensinarei a fazer npcs de missões, isso mesmo até mesmo aqueles de post office, paradox (que eu até ja fiz) Como sempre ensinarei a logica, ou seja, darei conhecimento não ideias :P
Assim já para ter uma ideia de um npc maior... É só seguir essa base... Vamos criar um passo a passo para que não compreendeu. NPCs tutoriais Situação : O npc Valdemar quer que você entregue uma carta a irmã dele chamada Clarice. Pense. Ele irá dar uma carta, e algo que controle se você ja recebeu a carta. Porque se você deu calote uma vez Que não se repita, ou seja, um storage value. Que será o 2411 (bem masculo)
Caso você não tenha storage -1 e nem 2 só pode ser 1 (no caso dessa quest) então ele manda você termina o serviço PELO AMOR DE DEUS, SEMPRE ESTRUTURE SEU SCRIPT, SE NÃO VOCÊ IRÁ SE CONFUDIR COM ESSE SHOW DE ELSE E IF. Isso é a vantagem de se usar o Jiddo System, pois diminuiu a confusão. Porém como ja disse, é coisa de preguiçoso Mais cada um com o seu né... Aqui acaba o npc de missões. Eu expliquei apenas a parte dos ifs e elseifs. Isso é simples, agora depende de sua capacidade e criatividade. Melhor maneira de aperfeiçoar ? fazendo varios!!! Eu odeio npcs, quase morri de raiva de ter que fazer esses (serio :P) Espero que aproveitem xD. Funções de NPcs Se você leu esse tuto até aqui, é porque não entendeu nada, ou seu interesso muito, por npcs. Lembra dos npc base ?.
Pelo que você ja perceberam eu odeio npcs, então não usei muitas dessas funções. No tfs tem o npc cityguard que ataca todos os red skull que aparecem em seu raio.
Vamos estuda-lo e aprender juntos!!!

	 function onCreatureAppear(cid)

	 if(cid == getNpcCid()) then

			 --Wake up call

			 origPos = getNpcPos()

			 --origLook = getCreatureDir(cid)

	 end

end


Quando a criatura aparece ele chama a função getNpcCid que checa o player que o npc está focado. Ai a variavel origPos vira a coordenada que ele está no momento.

function onCreatureDisappear(cid)

	 if(target == cid) then

			 goToOrigPos()

	 end

end

Quando o player sai da tela, ele verifica se o target (player que ele está focado também!?) é um player Se for ele volta para a posição anterior

local function isSkulled(cid)

	 local skullType = getPlayerSkullType(cid)

	 if(skullType >= 3) then

			 return true

	 end

	 return false

end

Essa função seria a base do npc, ele segue apenas players com skull. Poderiamos mudar essa função para ele seguir apenas player druids ? Claro!!! Como é um tutorial mudar o nome da função iriamos que remodelar todo o script (enche o saco) vamos apenas mudar dentro da função

	 local function isSkulled(cid)

	 local vocType = getPlayerVocation(cid)

	 if(vocType== 2) or (vocType == 6) then

			 return true

	 end


		return false

end

Mudando só isso os druid iriam sofrer na mão desses npcs xD Da para fazer ele atacar apenas monstros ? (acho que sim)

			 local function isSkulled(cid)

	 local idType = isPlayer(cid)

	 if (idType ~= 1) then

			 return true

	 end

	 return false

end

No caso se for diferente de 1 ele arrebenta de magia. Teste essas modificações. Porém a ideia base é entender as funções e não só modifica-las.
  Citar
Pelo contrato da SVN tudo que você faz a partir dela é conteúdo livre e de total modificação. Porém tenha bom senso que não é facil fazer scripts assim. Então sempre mantenham os creditos, principalmente
Se você modificou
  • 4 years later...
  • 1 year later...

Participe da conversa

Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.6k

Informação Importante

Confirmação de Termo