Ir para conteúdo
Propaganda

Posts Recomendados

Compartilhando com vocês um bug do PDA que já derrubou muito servidor. Basicamente a nurse joy das bases de pda (e provavelmente de outras também) roda um looping no jogador procurando todas as pokébolas validas para curar, o problema é que se o jogador se encher de bags (propositalmente ou não) o looping rodado vai ser muito grande e vai causar travamento no servidor (principalmente dependendo da hospedagem, quantidade de players online e quantidade de bags e pessoas fazendo esse bug de forma proposital).

 

Eu corrigi isso em meus projetos de forma bem pragmática, colocando para só curar os pokémons na bag principal, se alguém ai usar pda e quiser usar esse mesmo metódo.

Função:

-- Retorna todas as pokébolas válidas dentro de um container (ex: mochila)
local function getPokeballsInContainerHeal(container)
    if not isContainer(container) then return {} end  -- Se não for container, retorna vazio
    local items = {}
    for slot = 0, getContainerSize(container) - 1 do -- Percorre todos os slots do container
        local item = getContainerItem(container, slot)
        if isPokeball(item.itemid) then               -- Só adiciona se for uma pokébola
            table.insert(items, item.uid)
        end
    end
    return items  -- Retorna a lista de pokébolas encontradas
end

---- Na hora de pegar as pokebolas para cura:
	local bp = getPlayerSlotItem(cid, CONST_SLOT_BACKPACK)
    local balls = getPokeballsInContainer(bp.uid)

 

Se quiser o npc heal pronto com essa proteção:

local posis = {
	[897530] = {x = 1054, y = 1050, z = 7},   -- saffron
	[897531] = {x = 1061, y = 900, z = 7},    -- cerulean
	[897532] = {x = 1203, y = 1040, z = 7},   -- lavender
	[897533] = {x = 1213, y = 1321, z = 7},   -- fuchsia
	[897534] = {x = 860, y = 1094, z = 6},    -- celadon
	[897535] = {x = 706, y = 1083, z = 7},    -- viridian
	[897536] = {x = 1073, y = 1233, z = 7},   -- vermilion
	[897537] = {x = 723, y = 844, z = 7},     -- pewter
	[897538] = {x = 848, y = 1394, z = 7},    -- cinnabar
	[897539] = {x = 1281, y = 1468, z = 6},   -- snow
	[897540] = {x = 258, y = 429, z = 7},     -- golden
	[897541] = {x = 243, y = 1028, z = 7},    -- Hammlin
	[897542] = {x = 268, y = 1163, z = 7},    -- Shamouti
	[897543] = {x = 252, y = 1260, z = 6},    -- Ascordbia
	[897544] = {x = 2612, y = 985, z = 7},    -- Vip 1
	[897545] = {x = 2680, y = 675, z = 7},    -- Vip 2
	[897546] = {x = 2559, y = 444, z = 5},    -- Vip 3 / Pallet / Coliseum / Outlands
}

function onThingMove(creature, thing, oldpos, oldstackpos) end
function onCreatureAppear(creature) end

function onCreatureDisappear(cid, pos)
	if focus == cid then
		selfSay('Good bye sir!')
		focus = 0
		talk_start = 0
	end
end

function onCreatureTurn(creature) end

local function msgcontains(txt, str)
	return (string.find(txt, str) and not string.find(txt, '(%w+)' .. str) and not string.find(txt, str .. '(%w+)'))
end

-- 🧩 Função de proteção — apenas pokébolas dentro do container válido serão curadas
local function getPokeballsInContainerHeal(container)
	if not isContainer(container) then return {} end
	local items = {}
	for slot = 0, getContainerSize(container) - 1 do
		local item = getContainerItem(container, slot)
		if isPokeball(item.itemid) then
			table.insert(items, item.uid)
		end
	end
	return items
end

function onCreatureSay(cid, type, msg)
	local msg = string.lower(msg)
	local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid

	for a, b in pairs(gobackmsgs) do
		local gm = string.gsub(b.go, "doka!", "")
		local bm = string.gsub(b.back, "doka!", "")
		if string.find(string.lower(msg), string.lower(gm)) or string.find(string.lower(msg), string.lower(bm)) then
			return true
		end
	end

	if ((msgcontains(msg, 'hi') or msgcontains(msg, 'heal') or msgcontains(msg, 'help')) and (getDistanceToCreature(cid) <= 3)) then

		if exhaustion.get(cid, 1) then
			selfSay('Por Favor espere um momento para eu curar novamente seus Pokémons!')
			return true
		end

		if not getTileInfo(getThingPos(cid)).protection and nurseHealsOnlyInPZ then
			selfSay("Por Favor, entre no Centro Pokémon para eu poder curar seus Pokémons!")
			return true
		end

		if getPlayerStorageValue(cid, 52480) >= 1 then
			selfSay("Não posso curar seus Pokémons enquanto você está em duelo!")
			return true
		end

		exhaustion.set(cid, 9211, 1)

		doCreatureAddHealth(cid, getCreatureMaxHealth(cid) - getCreatureHealth(cid))
		doCureStatus(cid, "all", true)
		doSendMagicEffect(getThingPos(cid), 103)

		local mypb = getPlayerSlotItem(cid, 8)

		if #getCreatureSummons(cid) >= 1 then
			if not nurseHealsPokemonOut then
				selfSay("Por favor, retorne seu Pokémon para a Pokébola!")
				return true
			end

			local s = getCreatureSummons(cid)[1]
			doCreatureAddHealth(s, getCreatureMaxHealth(s))
			doSendMagicEffect(getThingPos(s), 13)
			doCureStatus(s, "all", false)
			if getPlayerStorageValue(s, 1008) < baseNurseryHappiness then
				setPlayerStorageValue(s, 1008, baseNurseryHappiness)
			end
			if getPlayerStorageValue(s, 1009) > baseNurseryHunger then
				setPlayerStorageValue(s, 1009, baseNurseryHunger)
			end
		else
			if mypb.itemid ~= 0 and isPokeball(mypb.itemid) then
				doItemSetAttribute(mypb.uid, "hp", 1)
				if getItemAttribute(mypb.uid, "hunger") and getItemAttribute(mypb.uid, "hunger") > baseNurseryHunger then
					doItemSetAttribute(mypb.uid, "hunger", baseNurseryHunger)
				end
				for c = 1, 15 do
					setCD(mypb.uid, "move" .. c, 0)
				end
				if getItemAttribute(mypb.uid, "happy") and getItemAttribute(mypb.uid, "happy") < baseNurseryHappiness then
					doItemSetAttribute(mypb.uid, "happy", baseNurseryHappiness)
				end
				if getPlayerStorageValue(cid, 17000) <= 0 and getPlayerStorageValue(cid, 17001) <= 0 and getPlayerStorageValue(cid, 63215) <= 0 then
					for a, b in pairs(pokeballs) do
						if isInArray(b.all, mypb.itemid) then
							doTransformItem(mypb.uid, b.on)
						end
					end
				end
			end
		end

		-- 🧠 Proteção: cura apenas pokébolas dentro da mochila do jogador
		local bp = getPlayerSlotItem(cid, CONST_SLOT_BACKPACK)
		local balls = getPokeballsInContainerHeal(bp.uid)

		for _, uid in ipairs(balls) do
			doItemSetAttribute(uid, "hp", 1)
			for c = 1, 15 do
				setCD(uid, "move" .. c, 0)
			end
			if getItemAttribute(uid, "hunger") and getItemAttribute(uid, "hunger") > baseNurseryHunger then
				doItemSetAttribute(uid, "hunger", baseNurseryHunger)
			end
			if getItemAttribute(uid, "happy") and getItemAttribute(uid, "happy") < baseNurseryHappiness then
				doItemSetAttribute(uid, "happy", baseNurseryHappiness)
			end
			local this = getThing(uid)
			for a, b in pairs(pokeballs) do
				if isInArray(b.all, this.itemid) then
					doTransformItem(uid, b.on)
				end
			end
		end

		selfSay('Todos os seus Pokémons foram curados! Boa sorte em sua jornada!')
		if useKpdoDlls then
			doUpdateMoves(cid)
		end
		if useOTClient then
			onPokeHealthChange(cid)
		end
	end
end

 

Observação: script feito em cima da base cyan, caso sua base seja diferente basta apenas adaptar.

  • Like 1
Link para o comentário
https://tibiadevs.com/forums/topic/1295-prote%C3%A7%C3%A3o-npc-joy-pda/
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
×
  • Criar Novo...