Ir para conteúdo

El Rusher

Cavaleiro
  • Total de itens

    164
  • Registro em

  • Última visita

  • Dias Ganhos

    20

Tudo que El Rusher postou

  1. local UPGRADE_ITEM_ID = 5902 -- Item para ativar leech local LIFE_LEECH_INCREMENT = 1 -- Incremento de Life Leech local MANA_LEECH_INCREMENT = 1 -- Incremento de Mana Leech local MAX_LEECH_PERCENT = 100 -- Máximo de leech permitido function onUse(cid, item, fromPosition, itemEx, toPosition) if not isPlayer(cid) then return false end local weapon = getPlayerSlotItem(cid, CONST_SLOT_LEFT) if weapon.itemid == 0 then weapon = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) end if weapon.itemid == 0 then doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "You need to be holding a weapon to upgrade it.") return false end local currentLifeLeech = tonumber(getItemAttribute(weapon.uid, "lifeLeech")) or 0 local currentManaLeech = tonumber(getItemAttribute(weapon.uid, "manaLeech")) or 0 local newLifeLeech = math.min(currentLifeLeech + LIFE_LEECH_INCREMENT, MAX_LEECH_PERCENT) local newManaLeech = math.min(currentManaLeech + MANA_LEECH_INCREMENT, MAX_LEECH_PERCENT) doItemSetAttribute(weapon.uid, "lifeLeech", newLifeLeech) doItemSetAttribute(weapon.uid, "manaLeech", newManaLeech) local description = "This weapon now has " .. newLifeLeech .. "% Life Leech and " .. newManaLeech .. "% Mana Leech. The maximum is 100%." doItemSetAttribute(weapon.uid, "description", description) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Your weapon has been upgraded with " .. newLifeLeech .. "% Life Leech and " .. newManaLeech .. "% Mana Leech.") local position = getCreaturePosition(cid) doSendAnimatedText(position, "+Leech!!!", 35) return true end Agora, configure o dano e o leech para funcionar sempre que a arma equipada atingir uma criatura. Este script pode ser adicionado ao creature scripts do servidor, ativando o leech no evento onAttack. Adicione este código no arquivo de creature scripts: function onAttack(cid, target) if not isPlayer(cid) or not isCreature(target) then return true end local weapon = getPlayerSlotItem(cid, CONST_SLOT_LEFT) if weapon.itemid == 0 then weapon = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) end local lifeLeech = tonumber(getItemAttribute(weapon.uid, "lifeLeech")) or 0 local manaLeech = tonumber(getItemAttribute(weapon.uid, "manaLeech")) or 0 if lifeLeech > 0 or manaLeech > 0 then local damage = math.random(50, 150) -- Dano variável para cada ataque (ajuste conforme necessário) doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -damage, -damage, CONST_ME_EXPLOSIONHIT) -- Calcula o leech local lifeSteal = math.floor((damage * lifeLeech) / 100) local manaSteal = math.floor((damage * manaLeech) / 100) doCreatureAddHealth(cid, lifeSteal) doPlayerAddMana(cid, manaSteal) -- Mensagem opcional para mostrar o leech doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Life Leech: " .. lifeSteal .. " | Mana Leech: " .. manaSteal) end return true end 2.Atualize o arquivo creaturescripts.xml para adicionar o novo script: <event type="attack" name="WeaponLeech" script="leechAttack.lua"/> 3.No arquivo login.lua, adicione uma linha para registrar o evento onAttack: registerCreatureEvent(cid, "WeaponLeech")
  2. local combat = Combat() combat:setParameter(COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) -- Tipo de dano físico para simular spear combat:setParameter(COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) -- Efeito visual combat:setParameter(COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SPEAR) -- Animação da spear arremessada -- Configurações de ricochete local bounceCount = 2 -- Número de ricochetes local bounceRange = 5 -- Alcance de cada ricochete function onCastSpell(creature, var) local target = creature:getTarget() -- Obtém o alvo principal if not target or target:getHealth() <= 0 then creature:sendCancelMessage("Você precisa de um alvo válido para essa magia!") return false end -- Confirma que o jogador está usando uma spear local weapon = creature:getSlotItem(CONST_SLOT_LEFT) if not weapon or weapon:getType():getName():lower() ~= "spear" then creature:sendCancelMessage("Você precisa estar usando uma spear para lançar esta magia.") return false end -- Aplica dano no alvo principal combat:execute(creature, var) -- Função para encontrar alvos adicionais para o ricochete local function getNearbyTarget(currentTarget, excludeList) local spectators = Game.getSpectators(currentTarget:getPosition(), false, true, bounceRange, bounceRange, bounceRange, bounceRange) for _, spectator in ipairs(spectators) do if spectator:isMonster() and spectator ~= currentTarget and not excludeList[spectator:getId()] then return spectator end end return nil end -- Aplica ricochete nos alvos próximos local ricochetTarget = target local excludeList = {[target:getId()] = true} for i = 1, bounceCount do ricochetTarget = getNearbyTarget(ricochetTarget, excludeList) if not ricochetTarget then break end -- Para o ricochete se não houver alvo próximo -- Atualiza a variável de alvo para o próximo ricochete local bounceVar = Position(ricochetTarget:getPosition()) combat:execute(creature, Variant(bounceVar)) -- Adiciona o alvo à lista de excluídos para não ser alvo novamente excludeList[ricochetTarget:getId()] = true end return true end
  3. El Rusher

    Canary 3.2.1 13.40

    local portalId, t = 25058, { ["glacius death"] = { message = "You have defeated Glacius Death!", config = { createPos = {}, -- O portal será criado onde o monstro morrer. toPos = {x = 32202, y = 31863, z = 13}, -- Posição onde o portal irá teleportar portalTime = 1, -- Duração do portal em minutos } }, } --------------------------------------------------------------------------------------- -- Fim da Configuração --------------------------------------------------------------------------------------- local function spectatorStartCountdown(time, position) local spectators = Game.getSpectators(position, false, false, 5, 5, 5, 5) if #spectators > 0 then for i = 1, #spectators do if time > 1 then spectators:say("" .. time .. "", TALKTYPE_MONSTER_SAY, false, spectators, position) else spectators:say("Time out!", TALKTYPE_MONSTER_SAY, false, spectators, position) break end end end local portal = Tile(position):getItemById(portalId) if portal then addEvent(spectatorStartCountdown, 1000, time - 1, position) end end local function removePortal(position) local portal = Tile(position):getItemById(portalId) if portal then portal:remove() end end local deathMonsterCreatePortal = CreatureEvent("deathMonsterCreatePortal") function deathMonsterCreatePortal.onDeath(creature, corpse, killer, mostDamageKiller) if not creature:isMonster() or creature:getMaster() then return true end -- Debug para ver se a criatura correta foi detectada print("A criatura morreu: " .. creature:getName()) local k = t[creature:getName():lower()] if not k then print("A criatura " .. creature:getName() .. " não está na lista de criação de portais.") return true end print("Criando portal para a criatura: " .. creature:getName()) local pos = creature:getPosition() local cPos = k.config.createPos if next(cPos) == nil then cPos = pos end if Tile(cPos):getItemById(portalId) then print("Portal já existente na posição: " .. cPos.x .. ", " .. cPos.y .. ", " .. cPos.z) return true end local item = Game.createItem(portalId, 1, cPos) if item:isTeleport() then item:setDestination(k.config.toPos) print("Portal criado com sucesso na posição: " .. cPos.x .. ", " .. cPos.y .. ", " .. cPos.z) else print("Erro ao criar o portal.") end local pt = k.config.portalTime addEvent(spectatorStartCountdown, 500, pt * 60, cPos) addEvent(removePortal, pt * 60 * 1000, cPos) return true end deathMonsterCreatePortal:type("death") deathMonsterCreatePortal:register() --------------------------------------------------------------------------------------- -- Registrar script onLogin --------------------------------------------------------------------------------------- local monsterDeathLogin = CreatureEvent("monsterDeathLogin") function monsterDeathLogin.onLogin(player) player:registerEvent("deathMonsterCreatePortal") return true end monsterDeathLogin:type("login") monsterDeathLogin:register() Ao matar o monstro glacius death, veja no console as mensagens de debug. Elas ajudarão a identificar se o problema está na identificação do monstro ou na criação do portal. Verifique se a posição do portal (onde o monstro morre) é adequada e acessível para criar o item. Certifique-se de que o portalId (25058) corresponde ao item do portal correto.
  4. El Rusher

    Canary 3.2.1 13.40

    local portalId, t = 25058, { ["glacius death"] = { message = "You have defeated Glacius Death!", config = { createPos = {}, -- O portal será criado onde o monstro morrer. toPos = {x = 32202, y = 31863, z = 13}, -- Posição onde o portal irá teleportar portalTime = 1, -- Duração do portal em minutos } }, } --------------------------------------------------------------------------------------- -- Fim da Configuração --------------------------------------------------------------------------------------- local function spectatorStartCountdown(time, position) local spectators = Game.getSpectators(position, false, false, 5, 5, 5, 5) if #spectators > 0 then for i = 1, #spectators do if time > 1 then spectators:say("" .. time .. "", TALKTYPE_MONSTER_SAY, false, spectators, position) else spectators:say("Time out!", TALKTYPE_MONSTER_SAY, false, spectators, position) break end end end local portal = Tile(position):getItemById(portalId) if portal then addEvent(spectatorStartCountdown, 1000, time - 1, position) end end local function removePortal(position) local portal = Tile(position):getItemById(portalId) if portal then portal:remove() end end local deathMonsterCreatePortal = CreatureEvent("deathMonsterCreatePortal") function deathMonsterCreatePortal.onDeath(creature, corpse, killer, mostDamageKiller) if not creature:isMonster() or creature:getMaster() then return true end local k = t[creature:getName():lower()] if not k then return true end local pos = creature:getPosition() local cPos = k.config.createPos if next(cPos) == nil then cPos = pos end if Tile(cPos):getItemById(portalId) then return true end local item = Game.createItem(portalId, 1, cPos) if item:isTeleport() then item:setDestination(k.config.toPos) end local pt = k.config.portalTime addEvent(spectatorStartCountdown, 500, pt * 60, cPos) addEvent(removePortal, pt * 60 * 1000, cPos) return true end deathMonsterCreatePortal:type("death") deathMonsterCreatePortal:register() --------------------------------------------------------------------------------------- -- Registrar script onLogin --------------------------------------------------------------------------------------- local monsterDeathLogin = CreatureEvent("monsterDeathLogin") function monsterDeathLogin.onLogin(player) player:registerEvent("deathMonsterCreatePortal") return true end monsterDeathLogin:type("login") monsterDeathLogin:register()
  5. El Rusher

    Sala Boss!

    Esse script define a dungeon na qual o jogador entrou e armazena essa informação na storage do player. Ele também teleporta o jogador para a posição inicial da dungeon.(Action 17003) function onUse(player, item, fromPosition, target, toPosition) local dungeonId = 1 -- ID da dungeon, altere conforme a dungeon específica local dungeonEntryPosition = Position(100, 100, 7) -- Defina a posição da entrada da dungeon (x, y, z) -- Armazena o ID da dungeon no storage do player player:setStorageValue(12345, dungeonId) -- 12345 é o storage para a dungeon atual -- Teleporta o player para a posição inicial da dungeon player:teleportTo(dungeonEntryPosition) player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Você entrou na Dungeon " .. dungeonId .. ".") return true end Esse script verifica qual dungeon o jogador entrou, e com base nisso, ele spawna o boss correspondente à dungeon naquela sala, se ela estiver disponível. (Action 14400) function onUse(player, item, fromPosition, target, toPosition) local dungeonId = player:getStorageValue(12345) -- Recupera o ID da dungeon do player local bossPosition = Position(105, 105, 7) -- Posição onde o boss vai ser spawnado (x, y, z) local playerBossRoomPosition = Position(110, 110, 7) -- Posição para onde o player será teleportado na sala do boss local bossId -- Verifica se o jogador tem um dungeonId válido if dungeonId == -1 then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Você não entrou em nenhuma dungeon.") return false end -- Define o boss de acordo com o ID da dungeon if dungeonId == 1 then bossId = "Boss1" -- Nome do Boss 1 elseif dungeonId == 2 then bossId = "Boss2" -- Nome do Boss 2 elseif dungeonId == 3 then bossId = "Boss3" -- Nome do Boss 3 else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Dungeon inválida.") return false end -- Checa se a sala do boss está disponível (sem criaturas) if not Tile(bossPosition):getTopCreature() then -- Spawna o boss na posição definida Game.createMonster(bossId, bossPosition) player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, bossId .. " apareceu!") -- Teleporta o player para a sala do boss player:teleportTo(playerBossRoomPosition) player:getPosition():sendMagicEffect(CONST_ME_TELEPORT) else player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "A sala do boss já está ocupada.") end return true end Explicação dos Scripts: Entrada na Dungeon (17003): Armazena o ID da dungeon na storage 12345 do player. Teleporta o player para a posição inicial da dungeon. Exibe uma mensagem informando que ele entrou na dungeon. Entrada na sala do Boss (14400): Verifica qual dungeon o jogador entrou usando o valor armazenado na storage 12345. Com base no ID da dungeon, seleciona o boss correto e tenta spawná-lo na sala do boss. Se a sala estiver disponível (sem criaturas), spawna o boss e teleporta o jogador para a sala. Se a sala estiver ocupada, exibe uma mensagem de erro. Modificações que você pode fazer: IDs de Dungeon e Boss: Altere os IDs das dungeons e os nomes dos bosses de acordo com o que você quiser. Posições: Ajuste as posições de entrada da dungeon, sala do boss, e local de teleporte para o que for necessário no seu mapa. Cooldown ou reset: Se precisar de um cooldown para respawnar o boss ou resetar a sala, esse sistema pode ser facilmente estendido.
  6. podemos remover a parte do código que está verificando e consumindo o item de aprimoramento e ajustar o cálculo do dano para depender exclusivamente do nível de lifeLeech do item. local LIFE_LEECH_INCREMENT = 10 -- Porcentagem a ser adicionada ao Life Leech a cada uso local MANA_LEECH_INCREMENT = 10 -- Porcentagem a ser adicionada ao Mana Leech a cada uso local MAX_LEECH_PERCENT = 100 -- Limite máximo para Life Leech e Mana Leech local BASE_DAMAGE = 100000000000 -- Dano base da arma local STORAGE_KEY = 10000 -- Chave de armazenamento para o nível de aprimoramento function onUse(cid, item, fromPosition, itemEx, toPosition) -- Verifica se o jogador é válido if not isPlayer(cid) then return false end -- Obtém a arma que o jogador está segurando (mão esquerda ou direita) local weapon = getPlayerSlotItem(cid, CONST_SLOT_LEFT) if weapon.itemid == 0 then weapon = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) end -- Verifica se o jogador está segurando uma arma if weapon.itemid == 0 then doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "Você precisa estar segurando uma arma para aprimorá-la.") return false end -- Obtém os valores atuais de Life Leech e Mana Leech (se existirem) local currentLifeLeech = tonumber(getItemAttribute(weapon.uid, "lifeLeech")) or 0 local currentManaLeech = tonumber(getItemAttribute(weapon.uid, "manaLeech")) or 0 -- Acumula novos valores de leech, limitados pelo máximo local newLifeLeech = math.min(currentLifeLeech + LIFE_LEECH_INCREMENT, MAX_LEECH_PERCENT) local newManaLeech = math.min(currentManaLeech + MANA_LEECH_INCREMENT, MAX_LEECH_PERCENT) -- Aplica os novos valores de Life Leech e Mana Leech à arma doItemSetAttribute(weapon.uid, "lifeLeech", newLifeLeech) doItemSetAttribute(weapon.uid, "manaLeech", newManaLeech) -- Modifica a descrição da arma para exibir os novos valores de leech local description = getItemAttribute(weapon.uid, "description") or "" description = "Esta arma agora tem " .. newLifeLeech .. "% de Life Leech e " .. newManaLeech .. "% de Mana Leech. O máximo é 100%." doItemSetAttribute(weapon.uid, "description", description) -- Envia uma mensagem para o jogador informando sobre o aprimoramento doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Sua arma foi aprimorada! Agora tem " .. newLifeLeech .. "% de Life Leech e " .. newManaLeech .. "% de Mana Leech. O máximo é 100%.") -- Exibe um texto animado "+Leech!!!" em verde (cor 35) local position = getCreaturePosition(cid) doSendAnimatedText(position, "+Leech!!!", 35) -- Armazena o novo nível de aprimoramento da arma setPlayerStorageValue(cid, STORAGE_KEY, newLifeLeech) -- Obtém o alvo atual do jogador local target = getCreatureTarget(cid) -- Verifica se há um alvo válido if isCreature(target) then -- Calcula o dano proporcional ao nível de aprimoramento da arma local damage = (newLifeLeech / 100) * BASE_DAMAGE -- Dano proporcional ao nível de leech doTargetCombatHealth(cid, target, COMBAT_UNDEFINEDDAMAGE, -damage, -damage, CONST_ME_HITAREA) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você realizou um ataque poderoso com sua arma aprimorada! Causou " .. damage .. " de dano.") else doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "Você não tem um alvo válido para atacar.") end return true end
  7. local LEACH_WEAPON_STORAGE = 47892 -- Armazenamento para a arma sanguessuga local FIXED_DAMAGE = 100000000000 -- Um valor de dano razoável local LEECH_PERCENT = 100 -- Porcentagem de sanguessuga para vida e mana local MAX_LEECH = 100 -- Máximo de 100% de sanguessuga para evitar sobrepujar -- Função para calcular e aplicar sanguessuga function applyLeech(cid, target, damage) -- Verifica se o alvo é uma criatura válida e se o jogador tem habilidade de sanguessuga if not isCreature(target) or getPlayerStorageValue(cid, LEACH_WEAPON_STORAGE) <= 0 then return end -- Garante que o valor do dano seja razoável if damage <= 0 then return end -- Calcula as quantidades de sanguessuga local lifeLeech = math.floor(damage * math.min(LEECH_PERCENT, MAX_LEECH) / 100) local manaLeech = math.floor(damage * math.min(LEECH_PERCENT, MAX_LEECH) / 100) -- Aplica sanguessuga à saúde e mana do jogador doCreatureAddHealth(cid, lifeLeech) doCreatureAddMana(cid, manaLeech) -- Envia efeito e feedback ao jogador doSendMagicEffect(getCreaturePosition(cid), CONST_ME_MAGIC_BLUE) doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você sugou " .. lifeLeech .. " saúde e " .. manaLeech .. " mana.") end -- Função principal de combate function onCombat(cid, target) -- Aplica um valor de dano fixo local fixedDamage = FIXED_DAMAGE -- Causa dano fixo ao alvo if isCreature(target) then doTargetCombatHealth(cid, target, COMBAT_UNDEFINEDDAMAGE, -fixedDamage, -fixedDamage, CONST_ME_FIREATTACK) -- Aplica sanguessuga com base no dano fixo causado applyLeech(cid, target, fixedDamage) else doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "Você não tem um alvo válido para atacar.") end return true end Correções: A função applyLeech não chama recursivamente a si mesma, prevenindo assim o erro de overflow. Certificamos que o alvo seja válido e que o dano aplicado seja positivo antes de proceder com o cálculo de leech.
  8. local UPGRADE_ITEM_ID = 5902 -- O item de melhoria, ex: "spooky blue eye" local LIFE_LEECH_INCREMENT = 1 -- Porcentagem a ser adicionada ao Life Leech local MANA_LEECH_INCREMENT = 1 -- Porcentagem a ser adicionada ao Mana Leech local MAX_LEECH_PERCENT = 100 -- Limite máximo para Life Leech e Mana Leech local FIXED_DAMAGE = 100000000 -- Dano fixo que será causado à criatura e ao jogador function onUse(cid, item, fromPosition, itemEx, toPosition) -- Verifica se o jogador é válido if not isPlayer(cid) then return false end -- Obtém a arma que o jogador está segurando (mão esquerda ou direita) local weapon = getPlayerSlotItem(cid, CONST_SLOT_LEFT) if weapon.itemid == 0 then weapon = getPlayerSlotItem(cid, CONST_SLOT_RIGHT) end -- Verifica se o jogador está segurando uma arma if weapon.itemid == 0 then doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "Você precisa estar segurando uma arma para melhorá-la.") return false end -- Obtém os valores atuais de Life Leech e Mana Leech (se houver) local currentLifeLeech = tonumber(getItemAttribute(weapon.uid, "lifeLeech")) or 0 local currentManaLeech = tonumber(getItemAttribute(weapon.uid, "manaLeech")) or 0 -- Acumula novos valores de leech local newLifeLeech = math.min(currentLifeLeech + LIFE_LEECH_INCREMENT, MAX_LEECH_PERCENT) local newManaLeech = math.min(currentManaLeech + MANA_LEECH_INCREMENT, MAX_LEECH_PERCENT) -- Aplica os novos valores de Life Leech e Mana Leech à arma doItemSetAttribute(weapon.uid, "lifeLeech", newLifeLeech) doItemSetAttribute(weapon.uid, "manaLeech", newManaLeech) -- Modifica a descrição da arma para mostrar os novos valores de leech local description = getItemAttribute(weapon.uid, "description") or "" description = "Esta arma agora tem " .. newLifeLeech .. "% de Life Leech e " .. newManaLeech .. "% de Mana Leech." doItemSetAttribute(weapon.uid, "description", description) -- Mensagens e efeitos doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Sua arma foi melhorada! Agora ela tem " .. newLifeLeech .. "% de Life Leech e " .. newManaLeech .. "% de Mana Leech.") doSendMagicEffect(getPlayerPosition(cid), CONST_ME_FIREATTACK) -- Exibe texto animado local position = getCreaturePosition(cid) -- Define a posição para o texto animado doSendAnimatedText(position, "+Leech", 35) -- Exibe o texto animado com a cor 35 (verde) -- Remove o item de melhoria doRemoveItem(item.uid, 1) -- Verifica se o jogador tem mana suficiente local maxMana = getCreatureMaxMana(cid) if getCreatureMana(cid) < maxMana then doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você não tem mana suficiente para realizar o ataque!") return false end -- Obtém o alvo e verifica se é válido local target = getCreatureTarget(cid) if not isCreature(target) then doPlayerSendTextMessage(cid, MESSAGE_STATUS_SMALL, "Você não tem um alvo válido para atacar.") return false end -- Causa dano fixo à criatura alvo doTargetCombatHealth(cid, target, COMBAT_PHYSICALDAMAGE, -FIXED_DAMAGE, -FIXED_DAMAGE, CONST_ME_SOUND_WHITE) -- Reduz a mana do jogador doCreatureAddMana(cid, -maxMana) -- Envia uma mensagem sobre o ataque doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Você usou toda sua mana para atacar! Dano causado: " .. FIXED_DAMAGE .. " ao seu alvo.") return true end Reduzi o valor de FIXED_DAMAGE para um número mais razoável (100000000). Coloquei as verificações de alvo e mana no lugar correto para evitar erros de execução. Simplifiquei o sistema de dano e remoção de mana para ser mais direto, garantindo que as operações funcionem como esperado. Teste o script novamente com essas modificações para ver se ele resolve o problema de não causar dano.
  9. Soul System: ok!, action: ok!, auras: ok!, creaturescript: ok!, soul: ok! conclusao: Certifique-se de que o item que você está tentando encantar está listado em L_Soul.enchant.weapons. Cada item deve ter o ID correto correspondente. Atributos do Item: Verifique se os atributos como "Soul" estão sendo corretamente definidos no item durante o processo de encantamento. Pode haver um problema de manipulação de atributos. Tipos de Danos e Efeitos: Confira se os tipos de danos e efeitos estão definidos corretamente em L_Soul.souls para garantir que o encantamento aplique o efeito esperado. Garanta que as funções externas, como L_Soul.souls, L_Soul.creatures, L_Soul.lang, e L_Soul.language, estejam devidamente carregadas e acessíveis.
  10. Esse erro indica que o sistema está tentando executar a função onUse, mas não consegue encontrá-la corretamente.. Verifique a função onUse: Certifique-se de que a função onUse está corretamente definida no seu arquivo scripts/water action.lua. Deve estar assim: function onUse(player, item, fromPosition, target, toPosition, isHotkey) -- Seu código aqui return true end Verifique a configuração do arquivo actions.xml: No arquivo actions.xml (localizado na pasta data/actions), certifique-se de que o caminho para o script está correto. Deve parecer algo como: <action itemid="XXXX" script="water action.lua"/> Certifique-se de que o script está na pasta correta: Verifique se o arquivo water action.lua está realmente localizado na pasta scripts dentro de data/actions.
  11. esse login e senha geralmente fica em baixo ou atras do seu roteador, caso nao tiver, solicite a provedora da sua internet
  12. Procure o arquivo CSS do seu site: Normalmente, o arquivo CSS está na pasta layouts, css, ou styles do seu site. O nome do arquivo pode ser algo como styles.css, main.css, ou similar. Abra o arquivo CSS e localize a seção correspondente ao Highscore Box: Use um editor de texto (como Notepad++ ou VSCode) e procure por classes ou IDs relacionados ao Highscore Box, como .highscore, #highscore, ou algo similar. Ajuste a fonte: Adicione ou modifique a propriedade font-family. Por exemplo: .highscore { font-family: Arial, sans-serif; /* Ou a fonte de sua preferência */ }
  13. -- kills.lua function onSay(cid, words, param) if not isPlayer(cid) then return false end -- Obtém o GUID do jogador local playerGUID = getPlayerGUID(cid) local resultId = db.storeQuery("SELECT unjustified_frags_day, unjustified_frags_week, unjustified_frags_month FROM player_kills WHERE player_id = " .. playerGUID) if resultId ~= false then -- Recupera os frags injustificados local unjustifiedKillsDay = result.getDataInt(resultId, "unjustified_frags_day") or 0 local unjustifiedKillsWeek = result.getDataInt(resultId, "unjustified_frags_week") or 0 local unjustifiedKillsMonth = result.getDataInt(resultId, "unjustified_frags_month") or 0 -- Configuração de quantos frags são necessários para obter red skull ou ban local dailyFragLimit = getConfigValue("dailyFragsToRedSkull") or 3 local weeklyFragLimit = getConfigValue("weeklyFragsToRedSkull") or 5 local monthlyFragLimit = getConfigValue("monthlyFragsToRedSkull") or 10 -- Envia as informações ao jogador doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Você tem " .. unjustifiedKillsDay .. " mortes injustificadas nas últimas 24 horas.") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Você tem " .. unjustifiedKillsWeek .. " mortes injustificadas nos últimos 7 dias.") doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Você tem " .. unjustifiedKillsMonth .. " mortes injustificadas nos últimos 30 dias.") -- Informar se está perto de obter red skull ou ban if unjustifiedKillsDay >= dailyFragLimit or unjustifiedKillsWeek >= weeklyFragLimit or unjustifiedKillsMonth >= monthlyFragLimit then doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "Cuidado! Você está próximo de obter uma Red Skull ou ser banido!") else doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Você ainda está seguro, mas continue atento às suas mortes injustificadas.") end result.free(resultId) else doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Não foi possível recuperar suas mortes injustificadas.") end return true end Certifique-se de que o banco de dados contém as colunas unjustified_frags_day, unjustified_frags_week e unjustified_frags_month na tabela player_kills. Além disso, ajuste os valores de configuração dailyFragsToRedSkull, weeklyFragsToRedSkull, e monthlyFragsToRedSkull para se alinhar ao que você deseja no arquivo de configuração do servidor.
  14. em data/actions/scripts/water_action.lua: local waterOutfit = {lookType = 134} -- ID da outfit para o navio local originalVoc = 1 -- Vocação original que o player retorna ao sair da água function onStepIn(creature, item, position, fromPosition) local player = creature:getPlayer() if not player then return true end -- Verifica se o jogador já está na outfit de navio if player:getOutfit().lookType ~= waterOutfit.lookType then player:setStorageValue(12345, player:getVocation():getId()) -- Salva a vocação original do jogador player:setOutfit(waterOutfit) -- Altera para a outfit de navio player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Você entrou na água e agora está em modo de navegação!") end return true end function onStepOut(creature, item, position, fromPosition) local player = creature:getPlayer() if not player then return true end local originalVocationId = player:getStorageValue(12345) if originalVocationId > 0 then player:setVocation(Vocation(originalVocationId)) -- Retorna à vocação original player:setOutfit({lookType = player:getSex() == PLAYERSEX_FEMALE and 136 or 128}) -- Outfit padrão baseado no sexo do jogador player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Você saiu da água e voltou ao modo normal.") end return true end Adicione o seguinte ao seu arquivo actions.xml que fica em data/actions/actions.xml: <action actionid="1001" script="water_action.lua"/> No seu editor de mapas, configure os tiles da área de água que o jogador vai entrar para a ActionID 1001. Observações A waterOutfit pode ser alterada para qualquer ID de outfit que você deseja usar para o "modo navio". Lembre-se de ajustar os IDs de acordo com as vocações e outfits que você quer utilizar. Ao pisar na água, a outfit do jogador mudará, e ao sair, ele retornará à sua vocação e outfit originais. Isso deve lhe dar uma base para começar a implementar a funcionalidade de navegação que você deseja!
  15. 1. Criar um comando para CTRL + Z (reportar bugs) No TFS, crie um comando que simule a função de CTRL + Z, que vai gerar um arquivo de log específico para bugs. Arquivo: talkactions/scripts/report_bug.lua function onSay(player, words, param) local reportText = param if reportText == "" then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Você precisa especificar um relatório de bug.") return false end local file = io.open("data/logs/bug_reports.log", "a") file:write("Player: " .. player:getName() .. " reported: " .. reportText .. "\n") file:close() player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Bug reportado com sucesso.") return true end 2. Criar um comando para CTRL + J (log de players) Em seguida, crie um comando que simule a função de CTRL + J, para criar logs de atividades de jogadores. Arquivo: talkactions/scripts/log_player.lua function onSay(player, words, param) local logMessage = param if logMessage == "" then player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Você precisa especificar o log.") return false end local file = io.open("data/logs/player_logs.log", "a") file:write("Player: " .. player:getName() .. " log message: " .. logMessage .. "\n") file:close() player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Log gravado com sucesso.") return true end 3. Configurar talkactions.xml Agora, adicione os comandos ctrlz e ctrlj no arquivo talkactions.xml para associar os scripts que você criou: Arquivo: talkactions.xml <talkaction words="/ctrlz" script="report_bug.lua"/> <talkaction words="/ctrlj" script="log_player.lua"/> 4. Como Usar Para reportar um bug (equivalente ao CTRL + Z), o jogador digita no chat: /ctrlz [descrição do bug] Para registrar um log de jogador (equivalente ao CTRL + J), o jogador digita no chat: /ctrlj [mensagem de log]
  16. El Rusher

    Depot House

    sim.. Crie um script chamado depot_sync.lua com o seguinte conteúdo: local function syncDepots(player) local mainDepot = player:getDepot(1) -- ID do depot do CP local houseDepot = player:getDepot(2) -- ID do depot na casa (ajuste conforme necessário) -- Sincroniza os itens do depot da casa com o depot do CP for i = 0, houseDepot:getCapacity() - 1 do local item = houseDepot:getItem(i) if item then mainDepot:addItemEx(item) end end end function onUse(player, item, fromPosition, target, toPosition, isHotkey) syncDepots(player) player:sendTextMessage(MESSAGE_INFO_DESCR, "Seus depots foram sincronizados com sucesso.") return true end Substitua XXXX pelo ID do item que você quer usar para abrir e sincronizar o depot. Como Funciona: O script sincroniza os itens do depot da house com o depot do CP (central) sempre que o jogador clicar no item configurado. A função syncDepots cuida da sincronização dos itens entre os depots. A função onUse é o evento que ocorre quando o jogador clica no item. Ela chama a função de sincronização e exibe uma mensagem ao jogador. Com isso, o jogador pode clicar no item específico e sincronizar seus depots. Depois, registre a action no arquivo actions.xml, associando o item com o script: <action itemid="XXXX" script="depot_sync.lua"/>
  17. local config = { [17003] = { nameDz = "Bronze", chave = 2155, count = 1, areas = { {fromx = 1712, fromy = 1211, fromz = 15, tox = 1966, toy = 1303, toz= 15}, {fromx = 1970, fromy = 1319, fromz = 15, tox = 2248, toy = 1303, toz= 15}, {fromx = 1712, fromy = 1211, fromz = 14, tox = 1966, toy = 1303, toz= 14}, {fromx = 1970, fromy = 1319, fromz = 14, tox = 2248, toy = 1303, toz= 14} }, teleport = { {x = 1789, y = 1288, z = 15}, {x = 2062, y = 1288, z = 15}, {x = 1789, y = 1288, z = 14}, {x = 2062, y = 1288, z = 14} }, pokemons = {"Elder Zubat", "Elder Rattata"}, finish = 15 * 60 * 1000, spawnCount = 64, -- Corrigido para 64 }, -- Outros níveis de Dungeon configurados aqui } -- Função para verificar se o local é walkable function isWalkable(pos, creature, proj, pz, water) if getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid == 0 then return false end if isWater(getTileThingByPos({x = pos.x, y = pos.y, z = pos.z, stackpos = 0}).itemid) and water then return false end if getTopCreature(pos).uid > 0 and creature then return false end if getTileInfo(pos).protection and pz then return false, true end local n = not proj and 3 or 2 for i = 0, 255 do pos.stackpos = i local tile = getTileThingByPos(pos) if tile.itemid ~= 0 and not isCreature(tile.uid) then if hasProperty(tile.uid, n) or hasProperty(tile.uid, 7) then return false end end end return true end -- Função para spawnar Pokémons na área correta function spawnPokemons(area, pokemons, spawnCount) local spawnedCount = 0 for i = 1, spawnCount do local posX = math.random(area.fromx, area.tox) local posY = math.random(area.fromy, area.toy) local posZ = area.fromz local position = {x = posX, y = posY, z = posZ} if isWalkable(position) then local chosenPokemon = pokemons[math.random(1, #pokemons)] doCreateMonster(chosenPokemon, position) spawnedCount = spawnedCount + 1 end end return spawnedCount end function onUse(cid, item, fromPosition, itemEx, toPosition) local cfg = config[item.actionid] if not cfg then return true end if isRiderOrFlyOrSurf(cid) then doPlayerSendCancel(cid, "Saia do ride ou fly para acessar a dungeon.") return true end if getPlayerStorageValue(cid, 468703) - os.time() > 0 then doPlayerSendCancel(cid, "Aguarde "..convertTime(getPlayerStorageValue(cid, 468703) - os.time()).." para entrar na Dungeon.") return true end if getPlayerItemCount(cid, cfg.chave) >= cfg.count then for i, area in ipairs(cfg.areas) do if #getPlayersInArea(area) < 1 then -- Remove monstros existentes e inicia os novos spawns removeNpcInArea({x = area.fromx, y = area.fromy, z = area.fromz}, {x = area.tox, y = area.toy, z = area.toz}, true, false) creatureInSurvival({x = area.fromx, y = area.fromy, z = area.fromz}, {x = area.tox, y = area.toy, z = area.toz}, true, false) -- Teleporta o jogador para a área correspondente doTeleportThing(cid, cfg.teleport[i]) setPlayerStorageValue(cid, 2154610, 1) doPlayerRemoveItem(cid, cfg.chave, cfg.count) -- Spawnar os pokémons na área correta local spawnedPokemons = spawnPokemons(area, cfg.pokemons, cfg.spawnCount) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "Foram spawnados "..spawnedPokemons.." pokémons na dungeon.") end end return true else doPlayerSendCancel(cid, "Você precisa de "..cfg.count.." "..getItemNameById(cfg.chave).." para entrar.") end return true end Neste script: A função spawnPokemons foi ajustada para tentar spawnar um total de 64 pokémons por área (ou o número especificado em spawnCount). Foram feitas correções para garantir que apenas posições "walkable" sejam consideradas para o spawn. O número de pokémons spawnados é mostrado ao jogador após o teleporte.
  18. 1. Corrigir o erro do gsub: O erro de gsub ocorre quando o tipo de dado passado para ele não é válido. No caso do erro que você está recebendo, parece que o sistema está esperando uma string, mas recebeu outro tipo de valor. 2. Verificar o erro Creature not found: Esse erro sugere que o NPC está tentando interagir com uma criatura (cid) que não existe ou foi removida do jogo. Pode ser resolvido verificando se o cid é uma criatura válida antes de tentar interagir com ele. Sugestões de ajustes no código: Função teleportPlayerToPositionReborn: function teleportPlayerToPositionReborn(cid) if not isCreature(cid) then selfSay('Player not found.', cid) return false end local playerRebornPositionX = getPlayerStorageValue(cid, PLAYER_REBORN_POSITION_X) local playerRebornPositionY = getPlayerStorageValue(cid, PLAYER_REBORN_POSITION_Y) local playerRebornPositionZ = getPlayerStorageValue(cid, PLAYER_REBORN_POSITION_Z) if playerRebornPositionX == -1 or playerRebornPositionY == -1 or playerRebornPositionZ == -1 then selfSay('You have not died yet.', cid) return false end doTeleportThing(cid, {x = playerRebornPositionX, y = playerRebornPositionY, z = playerRebornPositionZ}) return true end isCreature(cid): Verifica se o cid ainda é uma criatura válida antes de tentar acessá-la. Isso ajuda a evitar o erro Creature not found. Função onThink: Certifique-se de que o onThink está bem implementado no NPC: function onThink() if not npcHandler:isFocused() then return false end npcHandler:onThink() return true end
  19. No script Lua do NPC que lida com transações comerciais (geralmente dentro da pasta data/npc/scripts/), você deve incluir verificações do saldo bancário do jogador, além de verificar o dinheiro que ele tem em mãos. Usar a função getBankBalance: Use a função getPlayerBalance(cid) para verificar o saldo bancário do jogador. Se o jogador não tiver dinheiro suficiente em mãos, mas tiver saldo no banco, o NPC pode debitar diretamente do banco. Exemplo de implementação: Aqui está um exemplo básico de como ajustar o código de um NPC para verificar o saldo bancário: local function playerHasMoney(cid, amount) local money = getPlayerMoney(cid) -- Dinheiro que o jogador tem na mochila local bankBalance = getPlayerBalance(cid) -- Saldo do banco -- Verifica se o jogador tem dinheiro suficiente na mochila ou no banco return (money + bankBalance) >= amount end local function removePlayerMoney(cid, amount) local money = getPlayerMoney(cid) if money >= amount then -- Se o jogador tiver dinheiro suficiente na mochila, remover da mochila doPlayerRemoveMoney(cid, amount) else -- Se não, remover o que tem na mochila e o restante do banco doPlayerRemoveMoney(cid, money) doPlayerSetBalance(cid, getPlayerBalance(cid) - (amount - money)) end end -- Exemplo de função de venda de item local function sellItem(cid, itemId, amount, cost) if not playerHasMoney(cid, cost) then npcHandler:say("Você não tem dinheiro suficiente.", cid) return false end -- Se o jogador tiver dinheiro suficiente, remover o dinheiro e dar o item removePlayerMoney(cid, cost) doPlayerAddItem(cid, itemId, amount) npcHandler:say("Aqui está o seu item!", cid) return true end -- Exemplo de uso no script de NPC local tradeItems = { {name = "sword", id = 2376, price = 100}, -- Exemplo de item para vender } function onCreatureSay(cid, type, msg) if msgcontains(msg, 'trade') then npcHandler:say("Gostaria de comprar algo?", cid) openShopWindow(cid, tradeItems) -- Abre a janela de trade end end Explicação: playerHasMoney(cid, amount): Verifica se o jogador tem dinheiro suficiente na mochila e/ou no banco. removePlayerMoney(cid, amount): Deduz a quantia necessária primeiro da mochila e depois, se necessário, do banco. Adicionar ao sistema de NPC existente: Certifique-se de ajustar os nomes das funções e estruturas de diálogo do NPC para o formato usado no seu servidor. Você pode integrar essa lógica com o sistema de eventos de NPCHandler que já está no OTX2. sellItem: Implementa a lógica de venda de um item, removendo o dinheiro do jogador e entregando o item.
  20. Aqui está uma modificação na lógica para garantir que os itens sejam empilhados corretamente nos containers (backpacks) dentro do inventário do jogador: Cylinder* Player::__queryDestination(int32_t& index, const Thing* thing, Item** destItem, uint32_t& flags) { if (index == 0 /* drop to capacity window */ || index == INDEX_WHEREEVER) { *destItem = NULL; const Item* item = thing->getItem(); if (!item) return this; // Tentar encontrar um slot apropriado no inventário for (int32_t i = SLOT_FIRST; i < SLOT_LAST; ++i) { if (!inventory[i]) { if (__queryAdd(i, item, item->getItemCount(), 0) == RET_NOERROR) { index = i; return this; } } else if (inventory[i] != tradeItem) { if (Item* inventoryItem = inventory[i]) { // Tentar empilhar itens no inventário if (inventoryItem->getID() == item->getID() && inventoryItem->isStackable() && inventoryItem->getItemCount() < 100) { *destItem = inventoryItem; index = i; return this; } } } } // Tentar adicionar ou empilhar nos containers do inventário std::list<std::pair<Container*, int32_t> > deepList; for (int32_t i = SLOT_FIRST; i < SLOT_LAST; ++i) { if (inventory[i] == tradeItem) continue; if (Container* container = dynamic_cast<Container*>(inventory[i])) { // Verificar se o item pode ser empilhado em um container for (Item* containerItem : container->getItemList()) { if (containerItem->getID() == item->getID() && containerItem->isStackable() && containerItem->getItemCount() < 100) { *destItem = containerItem; index = INDEX_WHEREEVER; return container; } } // Caso não possa ser empilhado, tentar adicionar no container if (container->__queryAdd(-1, item, item->getItemCount(), 0) == RET_NOERROR) { index = INDEX_WHEREEVER; *destItem = NULL; return container; } // Adicionar container ao deepList para verificação em níveis mais profundos deepList.push_back(std::make_pair(container, 0)); } } // Verificar mais profundamente nos containers (backpacks dentro de backpacks) int32_t deepness = g_config.getNumber(ConfigManager::PLAYER_DEEPNESS); for (std::list<std::pair<Container*, int32_t> >::iterator dit = deepList.begin(); dit != deepList.end(); ++dit) { Container* c = (*dit).first; if (!c || c->empty()) continue; int32_t level = (*dit).second; for (ItemList::const_iterator it = c->getItems(); it != c->getEnd(); ++it) { if ((*it) == tradeItem) continue; if (Container* subContainer = dynamic_cast<Container*>(*it)) { // Verificar se o item pode ser empilhado em um subContainer for (Item* subContainerItem : subContainer->getItemList()) { if (subContainerItem->getID() == item->getID() && subContainerItem->isStackable() && subContainerItem->getItemCount() < 100) { *destItem = subContainerItem; index = INDEX_WHEREEVER; return subContainer; } } // Adicionar item no subContainer if (subContainer->__queryAdd(-1, item, item->getItemCount(), 0) == RET_NOERROR) { index = INDEX_WHEREEVER; *destItem = NULL; return subContainer; } // Verificar profundidade if (deepness < 0 || level < deepness) deepList.push_back(std::make_pair(subContainer, (level + 1))); } } } // Se não encontrou lugar adequado, retorna this return this; } Thing* destThing = __getThing(index); if (destThing) *destItem = destThing->getItem(); if (Cylinder* subCylinder = dynamic_cast<Cylinder*>(destThing)) { index = INDEX_WHEREEVER; *destItem = NULL; return subCylinder; } return this; } O que mudou: Adicionei uma verificação dentro dos containers para empilhar os itens (loop através dos itens dentro de containers, procurando por itens empilháveis). Verifico tanto o nível principal dos containers no inventário quanto containers dentro de containers (como backpacks aninhadas). O item será empilhado sempre que possível antes de ser adicionado em um novo espaço.
  21. Crie um arquivo chamado clear_console.lua dentro da pasta data/globalevents/scripts e adicione o seguinte código: function onThink(interval, lastExecution) io.write("\27[2J\27[H") -- Comando ANSI para limpar o console print("Console limpo automaticamente.") return true end Adicionar o evento ao globalevents.xml: <globalevent name="clearConsole" interval="43200000" event="script" value="clear_console.lua"/> O valor 43200000 corresponde a 12 horas em milissegundos. Reiniciar o servidor: Após adicionar o script e a entrada no globalevents.xml, reinicie o servidor. O console será automaticamente limpo a cada 12 horas.
  22. até da... mas vai dar um trampo.. geralmente é um arquivo LUA responsavel pela invocação dos pokemons, de modo mais facil era melhor dar um ctrl + f e procurar pela função doSummonCreature() e remover ou comentar ela.. -- doSummonCreature("nome_do_pokemon", pos) poketibia tambem tem bastante client mod que teria que ser removido.. ai você vai ter que adicionar vocações e sprites personalizaçao de mapa e por fim balanceamento..
  23. No Tibia, os efeitos gráficos são chamados de projectiles ou magic effects. Para criar o Kamehameha, você precisará usar um projectile que se move em uma direção. Aqui está um exemplo simples de como fazer isso: function onCastSpell(creature, variant) local position = creature:getPosition() -- Posição inicial do Goku local direction = creature:getDirection() -- Direção do Kamehameha local distance = 7 -- Distância que o ataque vai percorrer local damage = math.random(200, 300) -- Defina o dano do Kamehameha -- Definir o efeito gráfico do Kamehameha local projectileEffect = CONST_ANI_ENERGYBALL -- Escolha um efeito gráfico adequado -- Criação de um loop que movimenta o ataque for i = 1, distance do local newPosition = position:getNextPosition(direction, i) -- Calcula a posição seguinte creature:say("KAMEHAMEHA!", TALKTYPE_MONSTER_SAY) -- Grito de ataque, opcional -- Cria o projectile e o efeito creature:getPosition():sendDistanceEffect(newPosition, projectileEffect) -- Dano no alvo que está na posição do efeito local target = Tile(newPosition):getTopCreature() if target and target:isPlayer() then target:addHealth(-damage) target:getPosition():sendMagicEffect(CONST_ME_EXPLOSIONAREA) -- Efeito de explosão ao atingir end -- Intervalo para a movimentação do projectile addEvent(function() newPosition:sendMagicEffect(CONST_ME_ENERGYHIT) -- Efeito na posição final end, i * 100) -- Ajusta o intervalo da animação end return true end
  24. local function getWalkablePositions(area, maxPositions) local walkablePositions = {} for i = 1, #area do if #walkablePositions >= maxPositions then break -- Limitar o número de posições end local pos = area[i] if isWalkable(pos, true, false, true, true) then table.insert(walkablePositions, pos) end end return walkablePositions end -- Usar a função para obter exatamente 64 posições local positions = getWalkablePositions(area, 64)
  25. function pokemonWalk(summon, position, maxDistance, extra) -- Tenta encontrar um caminho para a posição desejada local path = summon:getPathTo(position, 0, maxDistance, true, true, 15) -- O terceiro parâmetro (true) indica que a criatura não pode atravessar bloqueios (como paredes). -- O quarto parâmetro (true) indica que a criatura pode atravessar outros monstros. if not path or #path == 0 then return false end -- Define um estado de inatividade após o monstro se mover setCreatureIdle(summon:getId(), #path * 500 + 10000) -- Inicia o movimento ao longo do caminho walkToPosition(summon:getId(), path, 1, extra) return true end function walkToPosition(cid, path, count, extra) local creature = Creature(cid) if not creature then return true end -- Verifica se a criatura ainda está se movendo if creature:getCondition(CONDITION_MOVING) == nil then return true end -- Pega a direção do próximo movimento local dir = path[count] -- Move a criatura para a próxima direção creature:move(dir) count = count + 1 -- Continua o movimento enquanto houver caminho if count <= #path then addEvent(walkToPosition, creature:getWalkDelay(dir), cid, path, count, extra) end end function setCreatureIdle(cid, time) local creature = Creature(cid) if not creature then return true end -- Aplica a condição de inatividade à criatura local condition = Condition(CONDITION_MOVING) condition:setParameter(CONDITION_PARAM_TICKS, time) creature:addCondition(condition) end O que foi ajustado: getPathTo: O terceiro parâmetro foi alterado para true, para impedir que os monstros atravessem paredes ou bloqueios. Isso deve resolver o problema principal. Continuação do Caminho: A movimentação só continua enquanto houver um caminho válido (count <= #path), garantindo que o monstro siga o caminho até o final. Movimento entre Criaturas: A função permite que o monstro atravesse outros monstros, mas você pode ajustar isso alterando o quarto parâmetro da função getPathTo para false, caso queira que eles evitem outros monstros também. Teste essas modificações para ver se resolve o problema dos monstros passando por obstáculos!
  • Quem Está Navegando   0 membros estão online

    • Nenhum usuário registrado visualizando esta página.
×
×
  • Criar Novo...