Ir para conteúdo

El Rusher

Cavaleiro
  • Total de itens

    185
  • Registro em

  • Última visita

  • Dias Ganhos

    24

Tudo que El Rusher postou

  1. 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.
  2. 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
  3. 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.
  4. 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.
  5. 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.
  6. 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.
  7. esse login e senha geralmente fica em baixo ou atras do seu roteador, caso nao tiver, solicite a provedora da sua internet
  8. 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 */ }
  9. -- 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.
  10. 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!
  11. 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]
  12. 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"/>
  13. 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.
  14. 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
  15. 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.
  16. 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.
  17. 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.
  18. 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..
  19. 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
  20. 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)
  21. 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!
  22. Aqui está o script completo para o sistema de gema que funciona para todas as vocações, usando uma única gema (ID: 2156), com uma magia que mata o jogador instantaneamente e adiciona um efeito visual multicolorido ao redor do alvo. local gemID = 2156 -- ID da Gema local instantKillSpell = true -- Habilidade que mata o alvo instantaneamente -- Função para gerar o efeito multicolorido local colors = {TEXTCOLOR_RED, TEXTCOLOR_GREEN, TEXTCOLOR_BLUE, TEXTCOLOR_YELLOW} local function applyMulticolorEffect(position) local rnd = {"´ . ,", ". ´ ,", "` . ,", ", ` ."} -- Efeito visual randômico for i = 1, #rnd do doSendAnimatedText(position, rnd[math.random(1, #rnd)], colors[math.random(1, #colors)]) end end -- Função para matar instantaneamente o jogador local function instantKill(target) if isPlayer(target) then local targetPosition = getCreaturePosition(target) doCreatureAddHealth(target, -getCreatureHealth(target)) -- Mata o jogador instantaneamente applyMulticolorEffect(targetPosition) -- Aplica o efeito multicolorido end end -- Função principal que detecta o uso da gema function onUse(cid, item, fromPosition, itemEx, toPosition) if item.itemid == gemID and isPlayer(itemEx.uid) then local target = itemEx.uid -- Verifica se o jogador pode ser atacado (não está em uma zona de proteção) if not isInPz(target) and canAttack(cid, target) then instantKill(target) doRemoveItem(item.uid, 1) -- Remove a gema após o uso doSendMagicEffect(getCreaturePosition(target), CONST_ME_EXPLOSIONHIT) -- Efeito de morte else doPlayerSendCancel(cid, "Você não pode atacar este jogador.") end else doPlayerSendCancel(cid, "Use a gema em um jogador.") end return true end Explicação do Script Identificador da Gema: O script usa a gema de ID: 2156. Quando o jogador clica nela e a usa em um outro jogador, o script é ativado. Verificação de Jogador-Alvo: O script verifica se o alvo é um jogador usando isPlayer(itemEx.uid). Também verifica se o alvo pode ser atacado, garantindo que não esteja em uma zona de proteção com isInPz(target). Morte Instantânea: Ao usar a gema, o jogador alvo tem sua vida reduzida a zero com doCreatureAddHealth(target, -getCreatureHealth(target)), matando-o instantaneamente. Efeito Multicolorido: A função applyMulticolorEffect(position) é usada para criar um efeito visual ao redor do alvo morto. São geradas animações de texto aleatórias (rnd) com cores variadas (colors), como vermelho, verde, azul e amarelo. Remoção da Gema: Após o uso, a gema é consumida com doRemoveItem(item.uid, 1). Efeito Visual na Morte: Além do efeito multicolorido, um efeito visual adicional de explosão (CONST_ME_EXPLOSIONHIT) é mostrado na posição do jogador morto. Você pode alterar os efeitos visuais e as cores ao seu gosto, modificando as tabelas rnd e colors.
  23. Para evitar a criação de monstros em paredes, você precisa verificar se o local gerado aleatoriamente é um local "walkable" (ou seja, acessível para o monstro andar). O TFS tem uma função chamada isWalkable que pode ser usada para validar as posições antes de gerar um Pokémon. local config = { [17003] = { nameDz = "Bronze", chave = 2155, count = 1, areas = { -- Criei uma tabela de áreas para simplificar {fromx = 1712, fromy = 1211, fromz = 15, tox = 1966, toy = 1303, toz= 15}, {fromx = 1712, fromy = 1319, fromz = 15, tox = 1966, toy = 1411, toz= 15}, {fromx = 1712, fromy = 1427, fromz = 15, tox = 1966, toy = 1519, toz= 15}, {fromx = 1712, fromy = 1535, fromz = 15, tox = 1966, toy = 1627, toz= 15} }, teleport = { -- Criado teleporte para cada área {x = 1789, y = 1288, z = 15}, {x = 1789, y = 1396, z = 15}, {x = 1789, y = 1504, z = 15}, {x = 1789, y = 1612, z = 15} }, pokemons = {"Elder Zubat", "Elder Rattata", "Shiny Golbat", "Shiny Raticate"}, spawnCount = 64 } } -- Função para verificar se o local é walkable function isPositionWalkable(pos) local tile = Tile(pos) return tile and not tile:hasFlag(TILESTATE_PROTECTIONZONE) and not tile:getCreatureCount() > 0 end -- Função para spawnar Pokémons na área correta function spawnPokemons(area, pokemons, spawnCount) 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} -- Verifica se a posição é "walkable" if isPositionWalkable(position) then local chosenPokemon = pokemons[math.random(1, #pokemons)] doCreateMonster(chosenPokemon, position) else i = i - 1 -- Se a posição não for válida, tenta novamente end end 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, 2154600, 1) doPlayerRemoveItem(cid, cfg.chave, cfg.count) addEvent(doTeleportFinish2, 15 * 60 * 1000, cid) doSendPlayerExtendedOpcode(cid, 133, 899) -- Spawna os Pokémons spawnPokemons(area, cfg.pokemons, cfg.spawnCount) return true end end doPlayerSendCancel(cid, "Nao tem Zonas disponiveis no momento, tente mais tarde!") else doPlayerSendCancel(cid, "Você precisa de uma Bronze Dimensional Key para acessar essa Dungeon.") end return true end Validação de Local Walkable: Foi adicionada a função isPositionWalkable para garantir que o Pokémon não seja criado em locais inacessíveis (como paredes). Identificação da Sala: Cada sala tem uma área e um ponto de teleporte definidos. A função percorre as áreas (cfg.areas) e verifica se há jogadores. Se não houver, o jogador é teleportado e os Pokémons são gerados nessa área. Loop para Encontrar Área Livre: O script agora percorre todas as áreas da configuração e tenta encontrar uma disponível para o jogador entrar. Novo Teleporte e Spawn para Cada Sala: Cada área tem seu próprio teleporte, e os Pokémons são gerados na área correspondente. Esse ajuste deve resolver os problemas de criação em áreas incorretas e o erro de geração em paredes.
  24. function onKill(cid, target) if isPlayer(cid) and isPlayer(target) then local targetPosition = getCreaturePosition(target) if targetPosition then doSendAnimatedText(targetPosition, "[OWNED!]", TEXTCOLOR_RED) -- Usando uma cor padrão de texto end end return true end
  25. O problema está nos parâmetros passados para getPathTo, onde os parâmetros que controlam a passagem por obstáculos estão definidos como false. Isso permite que a criatura atravesse elementos bloqueantes. Além disso, podemos ajustar alguns detalhes para garantir um movimento mais seguro e fluido. Script Ajustado function pokemonWalk(summon, position, maxDistance, extra) -- Tenta encontrar um caminho para a posição desejada local path = summon:getPathTo(position, 0, maxDistance, true, false, 15) -- O terceiro parâmetro (true) indica que a criatura não pode atravessar bloqueios (como paredes). -- O quarto parâmetro (false) indica que a criatura pode atravessar outros monstros. if not path or #path == 0 then return false end setCreatureIdle(summon:getId(), #path * 500 + 10000) 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 if creature:getCondition(CONDITION_MOVING) == nil then return true end local dir = path[count] creature:move(dir) count = count + 1 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 local condition = Condition(CONDITION_MOVING) condition:setParameter(CONDITION_PARAM_TICKS, time) creature:addCondition(condition) end Mudanças Feitas: Parâmetro de Caminho: getPathTo(position, 0, maxDistance, true, false, 15) O terceiro parâmetro (true) agora assegura que a criatura não atravessará obstáculos sólidos como paredes ou itens que bloqueiam a passagem. Verificação de Caminho: Agora verificamos se path é válido e se contém direções antes de continuar com a função walkToPosition. Execução Recursiva de Movimento: A função walkToPosition só continua se houver mais direções a seguir no caminho (count <= #path). Como Funciona Agora: O Pokémon vai calcular um caminho válido para a posição alvo, evitando obstáculos como paredes. O movimento é executado passo a passo, verificando se há condições que podem interromper o movimento (como uma condição de movimento já existente). O movimento continua até que o Pokémon tenha atingido a posição final, sem atravessar paredes ou objetos intransponíveis.
  • Quem Está Navegando   0 membros estão online

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