-
[PokéTibia / OTClient] Fly com sombra e botões de subir/descer — source + Lua
modules https://www.mediafire.com/file/11jl3ug04rp091p/Fly-Com-Sombra.zip/file
-
-
[PokéTibia / TFS 0.3.6] Nurse Joy com janela — Curar, Registrar e Fechar
Download: Nurse-Joy.zip (MediaFire)Nurse Joy com janela: Curar, Registrar e Fechar — PokéTibia / TFS 0.3.6Compartilhando a Nurse Joy da minha base com dialogo no OTClient. A janela mostra o nome e outfit da Nurse, mensagem e botoes Curar/Registrar/Fechar. Cura o treinador, Pokemon solto quando permitido, Ball do slot 8 e Balls da mochila; restaura HP, cooldowns move1..move15, felicidade e fome conforme a configuracao da base. O registro libera uma cidade no sistema de Teleport existente. Nao implementa o Teleport completo. E uma aplicacao do sistema de dialogo por clique esquerdo que compartilhei antes. O pacote abaixo inclui os arquivos das duas pontas, para nao depender de baixar outro topico. Edicao publica adaptada: JSON no transporte, registro explicitamente configurado no XML e verificacao de mochila valida. A base em uso nao foi alterada. A imagem de demonstracao corresponde a base original; na edicao publica a fonte usa verdana-11px-rounded e pode mudar ligeiramente a aparencia. O fundo window.png do modulo foi mantido. DEPENDENCIAS: OTClient com extended opcodes, json.decode do corelib, UICreature, estilos Button/Label/ScrollablePanel e fonte verdana-11px-rounded. TFS 0.3.6 / PokexGeneration com NpcSystem, FocusModule, doSendPlayerExtendedOpcode e os helpers/tabelas da sua base. Nao funciona somente copiando heal.lua num TFS puro. Servidor: copie os arquivos server/data para as mesmas pastas de data. A biblioteca npcdialog_lib.lua deve carregar tambem no ambiente dos NPCs. Nurse.xml aponta para heal.lua; se sua Nurse tem outro XML, preserve seu look/nome e altere apenas script e parametros. Configure/coloque a Nurse no mapa/spawn como de costume. O lookType 532 pertence a esta base; use um ID valido no seu DAT. Faça backup antes de substituir heal.lua: todas as Nurses que o usam receberao a mudanca. Registro de cidade: ajuste no XML <parameter key="teleportStorage" value="0"/>. Zero deixa o registro desativado. Use a storage que seu menu de Teleport realmente consulta para aquela cidade; exemplo: 897530 SOMENTE se seu Teleport usa esse numero. Registrar grava 1 nessa storage; nao teleporta, nao muda automaticamente townId e nao adiciona destinos ao menu. Nurses de cidades diferentes devem usar storages diferentes. Na edicao publica, Curar nao cadastra cidade automaticamente. Coordenadas particulares e a busca automatica do templo mais proximo foram retiradas para evitar registrar cidade errada em outro mapa. Cliente: copie os arquivos client/modules/game_npcdialog para modules/game_npcdialog e carregue o modulo depois de corelib/game_interface. Se ja instalou a edicao JSON do meu topico anterior, atualize somente o OTUI/fundo para esta aparencia e use os scripts Nurse do servidor; nao registre o opcode duas vezes. Nao misture o servidor JSON com cliente antigo que usa loadstring/table.serialize. Clique esquerdo: o bloco client/clique_esquerdo.lua vai DENTRO de processMouseAction em game_interface/gameinterface.lua, logo depois de local keyboardModifiers = g_keyboard.getModifiers(). Preserve o restante do arquivo. Ele manda hi quando o clique esquerdo sem modificadores identifica um NPC. NpcSystem cuida do foco/distancia; com dois NPCs juntos o hi pode escolher outro NPC proximo. Use classificacao isNpc correta no protocolo. O jogador tambem pode cumprimentar pela fala. Opcode 80 reservado ao dialogo servidor->cliente: se ja usado nessa direcao, altere nas duas pontas. O modulo fecha ao andar, sair do jogo ou pressionar Escape. Fechar libera o foco no servidor. Botoes usam hifen como separador; nao use hifen dentro do nome de uma opcao. Configuracao de cura: a base precisa definir nurseHealsOnlyInPZ, nurseHealsPokemonOut, baseNurseryHappiness, baseNurseryHunger e pokeballs (entradas all/on). Tambem usa exhaustion.get/set, isPokeball, getPokeballsInContainer, setCD, doCureStatus e opcionalmente doUpdateMoves quando useKpdoDlls=true. Flags false/nil desativam suas respectivas exigencias, mas fome/felicidade precisam de valores numericos. Nao sobrescreva configuration.lua inteira. Exaustao: storage 9211 por 5 segundos; duelo: storage 52480; Fly/Ride/Surf: 17000/17001/63215. Confira conflitos. O HP da Ball e fracao: hp=1 significa cheia. IDs on das Balls precisam ser os seus. Outros atributos como boost, level, held e nick nao sao zerados por este script. Validacao: Lua 5.1/XML e testes simulados de foco, abrir/voltar/fechar, registrar/repetir/desativado, bloqueio em duelo/PZ/exaustao, Pokemon solto proibido, cura de treinador/slot/mochila e mochila ausente. O transporte JSON e clique foram verificados no pacote anterior. Nao foi feito novo teste visual/end-to-end desta edicao no cliente, nem teste de todas as combinacoes de Balls. Teste em copia da base antes de producao. Creditos: modulo original game_npcdialog identificado como Gengo, modificado por Biel; OTClient team e autores do fork; autores do NpcSystem e do sistema de cura/PokéTibia preexistente. Raul compartilha sua integracao, organizada com auxilio do Codex. Nao reivindico autoria de todos os componentes. Nao acompanha executavel, cliente completo, sprites, banco ou mapa. Arquivos completos abaixo. Salve cada bloco no caminho indicado. client/clique_esquerdo.lua -- OTPokemon-style NPC interaction: a plain left click greets the NPC and -- lets the server open the dialog window through the NPC dialog opcode. local clickedNpc = nil if creatureThing and creatureThing:isNpc() then clickedNpc = creatureThing elseif attackCreature and attackCreature:isNpc() then clickedNpc = attackCreature elseif lookThing and lookThing:isCreature() and lookThing:isNpc() then clickedNpc = lookThing end if mouseButton == MouseLeftButton and keyboardModifiers == KeyboardNoModifier and clickedNpc then local player = g_game.getLocalPlayer() if player then player:stopAutoWalk() end g_game.cancelAttack() g_game.talkChannel(MessageModes.NpcTo, 0, 'hi') return true end client/modules/game_npcdialog/npcdialog.lua-- ui widgets local windowDialog local buttonHolder local labelTitle local outfitBox local panelMessage local scrollPanel local labelMessage -- variables local OpcodeDialog = 80 local Actions = { open = 1, closed = 2 } function init() connect(g_game, { onGameEnd = closeDialog }) connect(LocalPlayer, { onPositionChange = onPositionChange }) ProtocolGame.registerExtendedOpcode(OpcodeDialog, function(protocol, opcode, buffer) if type(buffer) ~= 'string' or #buffer > 60000 then return end local ok, result = pcall(json.decode, buffer) if not ok or type(result) ~= 'table' then return end if result.action == Actions.closed then closeDialog() elseif result.action == Actions.open and type(result.data) == 'table' then local data = result.data if type(data.npcId) == 'number' and type(data.message) == 'string' and (data.options == nil or type(data.options) == 'string') then createDialog(data) end end end) windowDialog = g_ui.displayUI('npcdialog') buttonHolder = windowDialog:getChildById('buttonHolder') labelTitle = windowDialog:getChildById('labelTitle') scrollPanel = windowDialog:getChildById('scrollPanel') panelMessage = windowDialog:getChildById('panelMessage') outfitBox = windowDialog:getChildById('outfitBox') labelMessage = g_ui.createWidget('LabelText', panelMessage) end function terminate() disconnect(g_game, { onGameEnd = closeDialog }) disconnect(LocalPlayer, { onPositionChange = onPositionChange }) ProtocolGame.unregisterExtendedOpcode(OpcodeDialog) windowDialog:destroy() end function closeDialog() windowDialog:hide() end function onPositionChange(creature, newPos, oldPos) if creature:isLocalPlayer() then windowDialog:hide() end end function openDialog() windowDialog:raise() windowDialog:show() end function createDialog(value) local Npc = g_map.getCreatureById(value.npcId) if not Npc then return error("game_npcdialog/npcdialog.lua: NPC nao encontrado no mapa visivel.") end labelTitle:setText(Npc:getName()) outfitBox:setOutfit(Npc:getOutfit()) labelMessage:clearText() labelMessage:setText(value.message) -- Evita erro se o limitText não estiver configurado no .otui local limit = panelMessage.limitText or 100 scrollPanel:setVisible(labelMessage:getTextSize().height > limit) buttonHolder:destroyChildren() if value.options and value.options ~= '' then -- Divide os botões pelo caractere '-' vindo do script do NPC local options = {} for option in value.options:gmatch('[^-]+') do table.insert(options, option) end for i = 1, #options do local button = g_ui.createWidget('OptionButton', buttonHolder) button:setText(tr(options[i])) button.onClick = function() g_game.talkChannel(MessageModes.NpcTo, 0, options[i]) end end buttonHolder:setHeight(#options > 6 and 48 or 25) end openDialog() end client/modules/game_npcdialog/npcdialog.otmodModule name: game_npcdialog description: Game NpcDialog author: Gengo Modificado por Biel scripts: [ npcdialog ] sandboxed: true autoload: true autoload-priority: 1001 @onLoad: init() @onUnload: terminate() client/modules/game_npcdialog/npcdialog.otuiLabelText < Label padding-bottom: 5 font: verdana-11px-rounded color: #FFFFFF text-wrap: true text-auto-resize: true OptionButton < Button margin: 3 0 0 2 width: 80 color: #FFFFFF UIWindow size: 620 231 visible: false image-source: window image-border: 12 anchors.centerIn: parent @onEscape: modules.game_npcdialog.closeDialog() Label id: labelTitle font: verdana-11px-rounded anchors.top: parent.top anchors.left: parent.left !text: tr('Title') margin: 18 0 5 25 color: #FFFFFF text-auto-resize: true UICreature id: outfitBox size: 75 75 anchors.top: prev.bottom anchors.left: parent.left margin: 20 0 5 34 VerticalScrollBar id: scrollPanel height: 65 anchors.top: panelMessage.top anchors.left: panelMessage.right anchors.bottom: panelMessage.bottom margin-left: 5 visible: false pixels-scroll: true step: 14 ScrollablePanel id: panelMessage size: 0 120 anchors.top: labelTitle.bottom anchors.left: outfitBox.right anchors.right: parent.right margin: 8 30 10 25 vertical-scrollbar: scrollPanel layout: verticalBox &limitText: 80 ScrollablePanel id: buttonHolder size: 0 24 anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right margin: 15 10 8 10 layout: type: grid cell-size: 99 22 flow: trueserver/data/lib/npcdialog_lib.lua-- Public JSON variant. Use the matching client module; old Lua-table payloads differ. local OpcodeDialog = 80 local function quote(value) return '"' .. value:gsub('[%z\1-\31\\"]', function(c) if c == '"' then return '\\"' end if c == '\\' then return '\\\\' end return string.format('\\u%04x', string.byte(c)) end) .. '"' end function doSendDialogNpc(cid, npc, msg, opc) if type(npc) ~= 'number' or type(msg) ~= 'string' then return false end local buffer = '{"action":1,"data":{"npcId":' .. tostring(npc) .. ',"message":' .. quote(msg) .. ',"options":' .. quote(opc or '') .. '}}' return doSendPlayerExtendedOpcode(cid, OpcodeDialog, buffer) end function doSendDialogNpcClose(cid) return doSendPlayerExtendedOpcode(cid, OpcodeDialog, '{"action":2}') end server/data/npc/Nurse.xml<?xml version="1.0" encoding="UTF-8"?> <npc name="Nurse Joy" script="heal.lua" walkinterval="350000" floorchange="0" speed="0"> <health now="150" max="150"/> <look type="532" head="91" body="102" legs="83" feet="0"/> <parameters> <!-- 0 disables registration. Set your Teleport destination storage. --> <parameter key="teleportStorage" value="0"/> <!-- As mensagens foram movidas para o script em Lua para o sistema de dialogo funcionar corretamente --> <parameter key="message_idletimeout" value="Ate mais treinador!"/> <parameter key="message_walkaway" value="Ate mais treinador!"/> </parameters> </npc> server/data/npc/scripts/heal.lua-- Public adaptation: explicit teleportStorage per NPC; no private map coordinates. local keywordHandler = KeywordHandler:new() local npcHandler = NpcHandler:new(keywordHandler) NpcSystem.parseParameters(npcHandler) local talkState = {} function onThingMove(creature, thing, oldpos, oldstackpos) end function onCreatureAppear(creature) npcHandler:onCreatureAppear(creature) end function onCreatureDisappear(cid) if isPlayer(cid) then doSendDialogNpcClose(cid) end npcHandler:onCreatureDisappear(cid) end function onCreatureTurn(creature) end function msgcontains(txt, str) return (string.find(txt, str) and not string.find(txt, '(%w+)' .. str) and not string.find(txt, str .. '(%w+)')) end function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg:lower()) end function onThink() npcHandler:onThink() end function greetCallback(cid) doSendDialogNpc(cid, getNpcId(), "Ola treinador! Bem-vindo ao Centro Pokemon.\nComo posso ajudar voce e seus Pokemons hoje?", "Curar-Registrar-Fechar") return true end function creatureSayCallback(cid, type, msg) if(not npcHandler:isFocused(cid)) then return false end local msg = string.lower(msg) local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid for a, b in pairs(gobackmsgs or {}) do local gm = string.gsub(b.go, "doka!", "") local bm = string.gsub(b.back, "doka!", "") if string.find(string.lower(msg), string.lower(gm)) or string.find(string.lower(msg), string.lower(bm)) then return true end end -- REGISTRAR CIDADE PARA O SISTEMA DE TELEPORT if msgcontains(msg, 'registrar') or msgcontains(msg, 'registra') then local registeredStorage = tonumber(getNpcParameter("teleportStorage")) if registeredStorage and (registeredStorage <= 0 or registeredStorage ~= math.floor(registeredStorage)) then registeredStorage = nil end if not registeredStorage then doSendDialogNpc(cid, getNpcId(), "Esta Nurse ainda nao possui uma cidade configurada para o Teleport.", "Voltar-Fechar") return true end if getPlayerStorageValue(cid, registeredStorage) >= 1 then doSendDialogNpc(cid, getNpcId(), "Esta cidade ja esta registrada no seu Teleport!", "Curar-Fechar") return true end setPlayerStorageValue(cid, registeredStorage, 1) doSendMagicEffect(getThingPos(cid), CONST_ME_MAGIC_GREEN) doSendDialogNpc(cid, getNpcId(), "Cidade registrada com sucesso! Agora voce pode voltar para ca usando um Pokemon com Teleport.", "Curar-Fechar") return true end -- 1. GATILHO: CLICOU EM CURAR OU FALOU "HEAL/HELP/CURAR" if msgcontains(msg, 'curar') or msgcontains(msg, 'heal') or msgcontains(msg, 'help') then if exhaustion.get(cid, 9211) then selfSay('Por favor, aguarde alguns instantes antes de pedir para curar seus pokemons novamente!', cid) return true end if not getTileInfo(getThingPos(cid)).protection and nurseHealsOnlyInPZ then selfSay("Por favor, entre no centro pokemon para curar seus pokemons!", cid) return true end if getPlayerStorageValue(cid, 52480) >= 1 then selfSay("Voce nao pode fazer isso enquanto estiver em um Duelo!", cid) return true end -- Reject before applying healing/exhaustion when summons must be recalled. if #getCreatureSummons(cid) >= 1 and not nurseHealsPokemonOut then selfSay("Por favor, coloque seu pokemon de volta na bola!", cid) return true end -- Aplica a exaustao e cura o treinador exhaustion.set(cid, 9211, 5) doCreatureAddHealth(cid, getCreatureMaxHealth(cid)-getCreatureHealth(cid)) doCureStatus(cid, "all", true) doSendMagicEffect(getThingPos(cid), 14) local mypb = getPlayerSlotItem(cid, 8) -- Cura Pokemon para fora da bola if #getCreatureSummons(cid) >= 1 then if not nurseHealsPokemonOut then selfSay("Por favor, coloque seu pokemon de volta na bola!", cid) return true end local s = getCreatureSummons(cid)[1] doCreatureAddHealth(s, getCreatureMaxHealth(s)) doSendMagicEffect(getThingPos(s), 14) doCureStatus(s, "all", false) if getPlayerStorageValue(s, 1008) < baseNurseryHappiness then setPlayerStorageValue(s, 1008, baseNurseryHappiness) end if getPlayerStorageValue(s, 1009) > baseNurseryHunger then setPlayerStorageValue(s, 1009, baseNurseryHunger) end else -- Cura o slot principal (Slot 8) if mypb and mypb.uid > 0 and mypb.itemid ~= 0 and isPokeball(mypb.itemid) then doItemSetAttribute(mypb.uid, "hp", 1) if getItemAttribute(mypb.uid, "hunger") and getItemAttribute(mypb.uid, "hunger") > baseNurseryHunger then doItemSetAttribute(mypb.uid, "hunger", baseNurseryHunger) end for c = 1, 15 do local str = "move"..c setCD(mypb.uid, str, 0) end if getItemAttribute(mypb.uid, "happy") and getItemAttribute(mypb.uid, "happy") < baseNurseryHappiness then doItemSetAttribute(mypb.uid, "happy", baseNurseryHappiness) end if getPlayerStorageValue(cid, 17000) <= 0 and getPlayerStorageValue(cid, 17001) <= 0 and getPlayerStorageValue(cid, 63215) <= 0 then for a, b in pairs (pokeballs) do if isInArray(b.all, mypb.itemid) then doTransformItem(mypb.uid, b.on) end end end end end -- Varre a mochila e cura todas as outras pokebolas guardadas local bp = getPlayerSlotItem(cid, CONST_SLOT_BACKPACK) local balls = {} if bp and bp.uid > 0 and isContainer(bp.uid) then balls = getPokeballsInContainer(bp.uid) or {} end if #balls >= 1 then for _, uid in ipairs(balls) do doItemSetAttribute(uid, "hp", 1) for c = 1, 15 do local str = "move"..c setCD(uid, str, 0) end if getItemAttribute(uid, "hunger") and getItemAttribute(uid, "hunger") > baseNurseryHunger then doItemSetAttribute(uid, "hunger", baseNurseryHunger) end if getItemAttribute(uid, "happy") and getItemAttribute(uid, "happy") < baseNurseryHappiness then doItemSetAttribute(uid, "happy", baseNurseryHappiness) end local this = getThing(uid) for a, b in pairs (pokeballs) do if isInArray(b.all, this.itemid) then doTransformItem(uid, b.on) end end end end -- Fecha a janela de dialogo apos a cura concluida com sucesso doSendDialogNpcClose(cid) selfSay('Prontinho! Voce e seus pokemons estao saudaveis novamente.', cid) if useKpdoDlls then doUpdateMoves(cid) end if npcHandler.unGreet then npcHandler:unGreet(cid) else npcHandler:resetNpc(cid) end npcHandler:releaseFocus(cid) return true elseif msgcontains(msg, "voltar") then doSendDialogNpc(cid, getNpcId(), "Ola treinador! Bem-vindo ao Centro Pokemon.\nComo posso ajudar voce e seus Pokemons hoje?", "Curar-Registrar-Fechar") return true -- 2. GATILHO: CLICOU EM FECHAR OU FALOU "SAIR/BYE/FECHAR" elseif msgcontains(msg, "fechar") or msgcontains(msg, 'sair') or msgcontains(msg, 'bye') then doSendDialogNpcClose(cid) selfSay('Ate mais treinador!', cid) if npcHandler.unGreet then npcHandler:unGreet(cid) else npcHandler:resetNpc(cid) end npcHandler:releaseFocus(cid) return true end return true end npcHandler:setCallback(CALLBACK_GREET, greetCallback) npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback) npcHandler:addModule(FocusModule:new()) Fundo window.png — recriar sem anexoNa pasta modules/game_npcdialog do cliente, abra PowerShell e execute o bloco abaixo. Ele grava somente window.png nessa pasta. Se preferir outro fundo, ajuste image-source no OTUI. [System.IO.File]::WriteAllBytes((Join-Path (Get-Location) 'window.png'), [Convert]::FromBase64String('iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAACVUlEQVR4nO3dv07yUBiA8bcNXICzW3cTEyMX4O4d6aR35N5dCMTEWTZnZ0MEB77iaVMK8WvNk/D8NnOwad6H0z8TWfwzKfJNJKbLdRYazL5559Xi89tX5z+oP13zzg4NvipnoP9z7BxHhw5UHeDq+qafMztZ5VFf6FFExMPFbevi/etTRGxjzGdlX2d2ktIZds17FBHxuVi0H2X8c6Dlx/hlmFM9EbPysppl17x317W71Xlt7XH8boyeFWerXZS2eU+X62z3aNu82RhjGGmUVHXTr71rpDdwYwynGSV958ubHzbG8JYf45f5rGx9cq1dsozxt9KdUntTF4dBYAwCYxAYg8AYBMYgMAaBMQiMQWAMAmMQGIPAGATGIDAGgTEIjEFgDAJjEBiDwBgExiAwBoExCIxBYAwCYxAYg8AYBMYgMAaBMQiMQWAMAmMQGIPAGATGIDAGgTEIjEFgDAJjEBiDwBgExiAwBoExCIxBYAwCYxAYg8AYBMYgMAaBMQiMQWAMAmMQGIPAGATGIDAGgTEIjEFgDAJjEBiDwBgExiAwBoExCIxBYAwCYxAYg8AYBMYgMFn6h7+p/nfafks9omWHzGdlXF3fRHG2uvzbUzwdaYymXZlJkW/SBXfKMPbFqHZJHrGN8fz2VfuAO6V/aYzmvKsNkTV3RpM7pR9dl6nUwSARP1H0e8fOMJsU+ebh4rZ18f71qXZA/V4ao2veo4iIz8Wi/SjjSB7JyoM7Sd2my3U2KfJN17yziO0N5W51Xlt7HL/Xno/Vn655733sNcaw9s37G4DX+20+pJNdAAAAAElFTkSuQmCC'))
-
[PokéTibia / OTClient] Fly com sombra e botões de subir/descer — source + Lua
Download: Fly-Com-Sombra.zip (MediaFire)Leia as instruções de instalação do pacote.Fly com sombra e botoes — PokéTibia / OTClient Compartilhando os trechos que uso na minha base TFS 0.3.6 / PokexGeneration e no meu fork de OTClient. O jogador montado no Fly recebe uma sombra preta deslocada, e o painel oferece Subir/Descer. A criatura voando e desenhada apos os objetos do andar; a sombra fica no passe do chao. Nao e shader nem sistema completo de montar Fly. Precisa da source do CLIENTE com g_drawQueue, g_adaptiveRenderer, g_sprites.getOffsetFactor e a assinatura de Outfit::draw mostrada no patch. Nao e compativel automaticamente com OTClient classico, v8, Redemption ou qualquer fork. O TFS precisa de extended opcodes e de um sistema Fly existente com storage 17000 e outfits/tiles de voo. Nao substitua order.lua nem login.lua completos. Instalacao: salve o patch como fly_client.patch na raiz da source do cliente. Use git apply --check --ignore-space-change fly_client.patch antes de git apply --ignore-space-change fly_client.patch. Se houver contexto diferente, adapte manualmente os trechos. Nao aplique duas vezes se setFlying/drawShadow ja existem. Recompile o cliente. Copie os tres arquivos de game_fly para modules/game_fly e carregue o modulo depois de game_interface (no bootstrap ou em load-later de interface.otmod). Esta edicao publica usa botoes com texto para nao depender das imagens das setas. Servidor: copie flyup.lua e flydown.lua para data/talkactions/scripts e registre dentro de <talkactions>: <talkaction words="h1" case-sensitive="no" event="script" value="flyup.lua"/> <talkaction words="h2" case-sensitive="no" event="script" value="flydown.lua"/>Integre show/hide nos pontos de montar, desmontar e login conforme o bloco de integracao abaixo. O modulo envia h1/h2 pelo chat; nao envia up/down pelo opcode. O opcode 115 apenas informa show/hide do servidor ao cliente. Se 115 estiver ocupado, troque em todos os locais. Os scripts h1/h2 usam tiles 11675/11676/11677, storage 17000, markPosEff e canWalkOnPos desta familia de bases. Confira seus IDs e helpers; nao sao recursos do TFS puro. Eles mantem as restricoes de teto, obstaculos/PZ e altura desta base (z de 1 a 7). O item de voo deve ser removido pelo movement/sistema existente; nao copie esses IDs para uma base sem os tiles e a limpeza correspondentes. Limites: esta implementacao marca somente o jogador local como flying; outros jogadores nao recebem a sombra automaticamente. Nao modifica pathfinding nem cria voo para qualquer Pokemon. O deslocamento da sombra e 60 * offsetFactor nos dois eixos; ajuste em Creature::drawShadow. O patch foi extraido dos arquivos locais, nao de uma release universal. Revisao de codigo e testes Lua com simulacao realizados; nao foi feita nova compilacao nem teste visual nesta publicacao. Teste montando/desmontando, andando em todas as direcoes, mudando andar, reconectando e com GameMapDrawGroundFirst ligado/desligado antes de usar em producao. Creditos: OTClient team e autores do fork, mantendo a licenca MIT do OTClient. Modulo game_fly identificado como autor raul. Organizacao da edicao publica com auxilio do Codex. Nao reivindico autoria dos sistemas de Fly preexistentes da base. Nao distribuo executavel, sprites, banco, mapa ou configuracoes particulares. client\modules\game_fly\game_fly.luaflyWindow = nil FLY_OPCODE = 115 -- Certifique-se de que nenhum outro modulo use este mesmo numero function init() connect(g_game, { onGameStart = online, onGameEnd = offline }) -- Registra a escuta do Opcode vindo do servidor ProtocolGame.registerExtendedOpcode(FLY_OPCODE, onExtendedOpcode) if g_game.isOnline() then online() end end function terminate() disconnect(g_game, { onGameStart = online, onGameEnd = offline }) ProtocolGame.unregisterExtendedOpcode(FLY_OPCODE) offline() end function online() if not flyWindow then local gameMap = modules.game_interface.getMapPanel() flyWindow = g_ui.displayUI('game_fly.otui', gameMap) end -- Inicia escondido. O servidor vai mandar o comando para exibir ao subir no Fly flyWindow:hide() end function offline() local player = g_game.getLocalPlayer() if player then player:setFlying(false) end if flyWindow then flyWindow:destroy() flyWindow = nil end end -- Funcao que recebe o comando do servidor para ocultar/mostrar function onExtendedOpcode(protocol, opcode, buffer) if not flyWindow then return end if buffer == "show" then local player = g_game.getLocalPlayer() if player then player:setFlying(true) end flyWindow:show() flyWindow:raise() elseif buffer == "hide" then local player = g_game.getLocalPlayer() if player then player:setFlying(false) end flyWindow:hide() end end function flyUp() if g_game.isOnline() then g_game.talk("h1") end end function flyDown() if g_game.isOnline() then g_game.talk("h2") end end client\modules\game_fly\game_fly.otmodModule name: game_fly description: Painel de Fly com botoes de seta estilo OtPokemon author: raul sandboxed: true scripts: [ game_fly ] @onLoad: init() @onUnload: terminate() client\modules\game_fly\game_fly.otuiUIWindow id: flyWindow size: 64 128 anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter focusable: false &draggable: false UIButton id: buttonUp size: 58 32 anchors.top: parent.top anchors.horizontalCenter: parent.horizontalCenter margin-top: -20 text: 'Subir' focusable: false &phantom: false @onClick: modules.game_fly.flyUp() UIButton id: buttonDown size: 58 32 anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter text: 'Descer' focusable: false &phantom: false @onClick: modules.game_fly.flyDown() fly_client.patch--- a/src/client/creature.h +++ b/src/client/creature.h @@ -47,6 +47,7 @@ virtual ~Creature(); virtual void draw(const Point& dest, bool animate = true, LightView* lightView = nullptr); + void drawShadow(const Point& dest, bool animate = true); virtual void drawOutfit(const Rect& destRect, Otc::Direction direction = Otc::InvalidDirection, const Color& color = Color::white, bool animate = false, bool ui = false, bool oldScaling = false); void drawInformation(const Point& point, bool useGray, const Rect& parentRect, int drawFlags); @@ -74,6 +75,8 @@ void setTypeTexture(const std::string& filename); void setIconTexture(const std::string& filename); void setPassable(bool passable) { m_passable = passable; } + void setFlying(bool flying) { m_flying = flying; } + bool isFlying() { return m_flying; } void setSpeedFormula(double speedA, double speedB, double speedC); void addTimedSquare(uint8 color); @@ -232,6 +235,7 @@ stdext::boolean<true> m_showShieldTexture; stdext::boolean<false> m_shieldBlink; stdext::boolean<false> m_passable; + bool m_flying = false; Color m_timedSquareColor; Color m_staticSquareColor; Color m_nameColor; --- a/src/client/creature.cpp +++ b/src/client/creature.cpp @@ -135,6 +135,23 @@ lightView->addLight(creatureCenter, light); } +void Creature::drawShadow(const Point& dest, bool animate) +{ + if (!m_flying || !canBeSeen()) + return; + + Point animationOffset = animate ? m_walkOffset : Point(0, 0); + if (m_outfit.getCategory() != ThingCategoryCreature) + animationOffset -= getDisplacement(); + + const Point jumpOffset(m_jumpOffset.x, m_jumpOffset.y); + const Point shadowOffset(60 * g_sprites.getOffsetFactor(), 60 * g_sprites.getOffsetFactor()); + const size_t shadowQueueStart = g_drawQueue->size(); + m_outfit.draw(dest - jumpOffset + animationOffset + shadowOffset, + m_walking ? m_walkDirection : m_direction, + m_walkAnimationPhase, true, nullptr); + g_drawQueue->setMark(shadowQueueStart, Color(0, 0, 0, 255)); +} void Creature::drawOutfit(const Rect& destRect, Otc::Direction direction, const Color& color, bool animate, bool ui, bool oldScaling) { --- a/src/client/tile.h +++ b/src/client/tile.h @@ -67,7 +67,9 @@ void drawGround(const Point& dest, LightView* lightView = nullptr); void drawBottom(const Point& dest, LightView* lightView = nullptr); + void drawCreatureShadows(const Point& dest); void drawCreatures(const Point& dest, LightView* lightView = nullptr); + void drawFlyingCreatures(const Point& dest, LightView* lightView = nullptr); void drawTop(const Point& dest, LightView* lightView = nullptr); void drawTexts(Point dest); void drawWidget(Point dest); --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -120,6 +120,31 @@ } } +void Tile::drawCreatureShadows(const Point& dest) +{ + if (m_fill != Color::alpha || m_topDraws < m_topCorrection) + return; + + for (const CreaturePtr& creature : m_walkingCreatures) { + if (creature->isHidden()) + continue; + Point creatureDest(dest.x + ((creature->getPrewalkingPosition().x - m_position.x) * g_sprites.spriteSize() - m_drawElevation * g_sprites.getOffsetFactor()), + dest.y + ((creature->getPrewalkingPosition().y - m_position.y) * g_sprites.spriteSize() - m_drawElevation * g_sprites.getOffsetFactor())); + creature->drawShadow(creatureDest, true); + } + + int limit = g_adaptiveRenderer.creaturesLimit(); + for (auto& thing : m_things) { + if (!thing->isCreature() || thing->isHidden()) + continue; + if (limit-- <= 0) + break; + CreaturePtr creature = thing->static_self_cast<Creature>(); + if (!creature || creature->isWalking()) + continue; + creature->drawShadow(dest - m_drawElevation * g_sprites.getOffsetFactor(), true); + } +} void Tile::drawCreatures(const Point& dest, LightView* lightView) { @@ -130,7 +155,7 @@ // walking creatures for (const CreaturePtr& creature : m_walkingCreatures) { - if (creature->isHidden()) + if (creature->isHidden() || creature->isFlying()) continue; Point creatureDest(dest.x + ((creature->getPrewalkingPosition().x - m_position.x) * g_sprites.spriteSize() - m_drawElevation * g_sprites.getOffsetFactor()), dest.y + ((creature->getPrewalkingPosition().y - m_position.y) * g_sprites.spriteSize() - m_drawElevation * g_sprites.getOffsetFactor())); @@ -146,12 +171,37 @@ if (limit-- <= 0) break; CreaturePtr creature = thing->static_self_cast<Creature>(); - if (!creature || creature->isWalking()) + if (!creature || creature->isWalking() || creature->isFlying()) continue; creature->draw(dest - m_drawElevation * g_sprites.getOffsetFactor(), true, lightView); } } +void Tile::drawFlyingCreatures(const Point& dest, LightView* lightView) +{ + if (m_fill != Color::alpha || m_topDraws < m_topCorrection) + return; + + for (const CreaturePtr& creature : m_walkingCreatures) { + if (creature->isHidden() || !creature->isFlying() || creature->getPrewalkingPosition() != m_position) + continue; + Point creatureDest(dest.x + ((creature->getPrewalkingPosition().x - m_position.x) * g_sprites.spriteSize() - m_drawElevation * g_sprites.getOffsetFactor()), + dest.y + ((creature->getPrewalkingPosition().y - m_position.y) * g_sprites.spriteSize() - m_drawElevation * g_sprites.getOffsetFactor())); + creature->draw(creatureDest, true, lightView); + } + + int limit = g_adaptiveRenderer.creaturesLimit(); + for (auto& thing : m_things) { + if (!thing->isCreature() || thing->isHidden()) + continue; + if (limit-- <= 0) + break; + CreaturePtr creature = thing->static_self_cast<Creature>(); + if (!creature || creature->isWalking() || !creature->isFlying() || creature->getPosition() != m_position) + continue; + creature->draw(dest - m_drawElevation * g_sprites.getOffsetFactor(), true, lightView); + } +} void Tile::drawTop(const Point& dest, LightView* lightView) { --- a/src/client/mapview.cpp +++ b/src/client/mapview.cpp @@ -177,6 +177,11 @@ Point tileDrawPos = transformPositionTo2D(tile->getPosition(), cameraPosition); tile->drawGround(tileDrawPos, m_lightView.get()); } + // Flying shadows stay on the ground and are covered by walls and top items. + for (auto& tile : tiles) { + Point tileDrawPos = transformPositionTo2D(tile->getPosition(), cameraPosition); + tile->drawCreatureShadows(tileDrawPos); + } // bottom, creatures, top for (auto& tile : tiles) { Point tileDrawPos = transformPositionTo2D(tile->getPosition(), cameraPosition); @@ -205,6 +210,7 @@ } tile->drawGround(tileDrawPos, m_lightView.get()); + tile->drawCreatureShadows(tileDrawPos); tile->drawBottom(tileDrawPos, m_lightView.get()); @@ -218,6 +224,11 @@ } } + // Flying creatures remain visible above mountains and other top objects. + for (auto& tile : tiles) { + Point tileDrawPos = transformPositionTo2D(tile->getPosition(), cameraPosition); + tile->drawFlyingCreatures(tileDrawPos, m_lightView.get()); + } for (const MissilePtr& missile : g_map.getFloorMissiles(floor)) { missile->draw(transformPositionTo2D(missile->getPosition(), cameraPosition), true, m_lightView.get()); --- a/src/client/luafunctions_client.cpp +++ b/src/client/luafunctions_client.cpp @@ -509,6 +509,8 @@ g_lua.bindClassMemberFunction<Creature>("setSpeed", &Creature::setSpeed); g_lua.bindClassMemberFunction<Creature>("getBaseSpeed", &Creature::getBaseSpeed); g_lua.bindClassMemberFunction<Creature>("setBaseSpeed", &Creature::setBaseSpeed); + g_lua.bindClassMemberFunction<Creature>("setFlying", &Creature::setFlying); + g_lua.bindClassMemberFunction<Creature>("isFlying", &Creature::isFlying); g_lua.bindClassMemberFunction<Creature>("getSkull", &Creature::getSkull); g_lua.bindClassMemberFunction<Creature>("getShield", &Creature::getShield); g_lua.bindClassMemberFunction<Creature>("getEmblem", &Creature::getEmblem); server\data\talkactions\scripts\flydown.lualocal lower = {460, 11675, 11676, 11677} -- Corrigido para números para evitar falhas de leitura local houses = {'919', '1015', '1590', '1591', '1592', '1593', '1582', '1584', '1586', '1588', '5248', '5189'} local function refreshFlyOutfit(cid, flyOutfit) addEvent(function() if not isCreature(cid) then return end doCreatureChangeOutfit(cid, flyOutfit) end, 80) end function onSay(cid, words, param) if param ~= "" then return false end if getPlayerStorageValue(cid, 17000) <= 0 then return true end -- Impede de descer abaixo do nível do chão (Z=7) if getThingPos(cid).z >= 7 then doPlayerSendCancel(cid, "Voce nao pode descer mais!") return true end local currentTile = getTileInfo(getThingPos(cid)).itemid if currentTile == 11677 then doPlayerSendCancel(cid, "Desculpe, nao e possivel descer mais por aqui.") return true end if currentTile >= 2 and not isInArray(lower, currentTile) then doPlayerSendCancel(cid, "Voce nao pode descer aqui.") return true end local pos = getThingPos(cid) pos.z = pos.z + 1 pos.stackpos = 0 if getTileThingByPos(pos).itemid >= 1 then -- Impede o jogador de descer voando dentro de uma Zone de Proteção (PZ), como um CP if getTilePzInfo(pos) == true then doPlayerSendCancel(cid, "Voce nao pode descer aqui (Zona de Protecao).") return true end -- Impede de descer se houver um obstáculo sólido embaixo (paredes, montanhas, etc.) if not canWalkOnPos(pos, true, true, false, false, true) then doPlayerSendCancel(cid, "Voce nao pode descer aqui, o caminho esta bloqueado.") return true end local flyOutfit = getCreatureOutfit(cid) doTeleportThing(cid, pos) refreshFlyOutfit(cid, flyOutfit) if getCreatureOutfit(cid).lookType == 667 or getCreatureOutfit(cid).lookType == 999 then markPosEff(cid, getThingPos(cid)) end else local flyOutfit = getCreatureOutfit(cid) doCombatAreaHealth(cid, 0, pos, 0, 0, 0, CONST_ME_NONE) doCreateItem(11675, 1, pos) doTeleportThing(cid, pos) refreshFlyOutfit(cid, flyOutfit) if getCreatureOutfit(cid).lookType == 667 or getCreatureOutfit(cid).lookType == 999 then markPosEff(cid, getThingPos(cid)) --edited porygon fly sistem end end return true end server\data\talkactions\scripts\flyup.lualocal function refreshFlyOutfit(cid, flyOutfit) addEvent(function() if not isCreature(cid) then return end doCreatureChangeOutfit(cid, flyOutfit) end, 80) end function onSay(cid, words, param) if param ~= "" then return false end if getPlayerStorageValue(cid, 17000) <= 0 then return true end -- Altere para 0 se o seu mapa suportar o andar 0 sem travar o movimento do Pokémon. local andar_maximo_permitido = 1 if getThingPos(cid).z <= andar_maximo_permitido then doPlayerSendCancel(cid, "Voce ja esta na altura maxima permitida de Fly!") return true end local pos = getThingPos(cid) pos.z = pos.z - 1 pos.stackpos = 0 -- Impede de subir se houver um teto, telhado ou construção sólida logo acima if getTileThingByPos(pos).itemid >= 1 or getTileItemById(getThingPos(cid), 1386).itemid >= 1 then doPlayerSendCancel(cid, "Voce nao pode voar atraves de construcoes.") return true end local flyOutfit = getCreatureOutfit(cid) doCombatAreaHealth(cid, 0, pos, 0, 0, 0, CONST_ME_NONE) doCreateItem(11676, 1, pos) doTeleportThing(cid, pos) refreshFlyOutfit(cid, flyOutfit) if getCreatureOutfit(cid).lookType == 667 or getCreatureOutfit(cid).lookType == 999 then markPosEff(cid, getThingPos(cid)) --edited porygon fly sistem end return true end server\integracao.lua-- Inserir apenas nos pontos correspondentes do sistema de Fly existente. -- Depois de montar e ativar storage 17000: doSendPlayerExtendedOpcode(cid, 115, "show") -- Depois de desmontar e desativar storage 17000: doSendPlayerExtendedOpcode(cid, 115, "hide") -- No login, depois de restaurar o estado de Fly: if getPlayerStorageValue(cid, 17000) > 0 then doSendPlayerExtendedOpcode(cid, 115, "show") else doSendPlayerExtendedOpcode(cid, 115, "hide") end
-
-
-
-
-
novas ball poketibia
alguem podeeria me ajuda meu servidor de poketibia nao contabiliza a pokebolas se tenho 100 e uso 1 ela nao desce para 99 magu ball yumo poderia me ajuda catch do actions local ballcatch = { --id normal, id da ball shiny [2394] = {cr = 40, on = 24, off = 23, ball = {11826, 11737}, send = 47, typeee = "normal"}, [2391] = {cr = 45, on = 198, off = 197, ball = {11832, 11740}, send = 48, typeee = "great"}, [2393] = {cr = 50, on = 202, off = 201, ball = {11835, 11743}, send = 46, typeee = "super"}, [2392] = {cr = 55, on = 200, off = 199, ball = {11829, 11746}, send = 49, typeee = "ultra"}, [16458] = {cr = 55, on = 258, off = 259, ball = {16459, 16462}, send = 58, typeee = "magu"}, [16465] = {cr = 55, on = 261, off = 262, ball = {16466, 16469}, send = 59, typeee = "sora"}, [16472] = {cr = 55, on = 264, off = 265, ball = {16473, 16476}, send = 60, typeee = "yume"}, -- CORRIGIDO: Invertido de (16476, 16473) para (Normal, Shiny) [16479] = {cr = 55, on = 267, off = 268, ball = {16480, 16483}, send = 61, typeee = "dusk"}, -- CORRIGIDO: Invertido de (16483, 16480) para (Normal, Shiny) [16486] = {cr = 55, on = 270, off = 271, ball = {16487, 16490}, send = 62, typeee = "fast"}, -- CORRIGIDO: Invertido de (16490, 16487) para (Normal, Shiny) [16493] = {cr = 55, on = 273, off = 274, ball = {16494, 16497}, send = 63, typeee = "heavy"}, [16500] = {cr = 55, on = 276, off = 277, ball = {16501, 16504}, send = 64, typeee = "tale"}, -- CORRIGIDO: Invertido de (16504, 16501) para (Normal, Shiny) [16507] = {cr = 55, on = 279, off = 280, ball = {16508, 16511}, send = 65, typeee = "moon"}, -- CORRIGIDO: Invertido de (16508, 16511) para (Normal, Shiny) [16514] = {cr = 55, on = 282, off = 283, ball = {16515, 16518}, send = 66, typeee = "net"}, -- CORRIGIDO: Invertido de (16518, 16515) para (Normal, Shiny) [16521] = {cr = 55, on = 282, off = 283, ball = {16522, 16525}, send = 67, typeee = "janguru"}, -- CORRIGIDO: "Janguru" minúsculo para bater com a configuration.lua [16528] = {cr = 55, on = 288, off = 289, ball = {16529, 16532}, send = 68, typeee = "premier"}, -- CORRIGIDO: Invertido de (16532, 16529) para (Normal, Shiny) [16535] = {cr = 55, on = 291, off = 292, ball = {16536, 16539}, send = 69, typeee = "tinker"}, -- CORRIGIDO: Invertido de (16539, 16536) para (Normal, Shiny) [16542] = {cr = 55, on = 294, off = 294, ball = {16543, 16546}, send = 70, typeee = "master"}, -- CORRIGIDO: Invertido de (16546, 16543) para (Normal, Shiny) [16549] = {cr = 55, on = 296, off = 298, ball = {16550, 16553}, send = 71, typeee = "saffari"}, -- CORRIGIDO: Invertido de (16553, 16550) para (Normal, Shiny) } function onUse(cid, item, frompos, item3, topos) local item2 = getTopCorpse(topos) if item2 == null then return true end if getItemAttribute(item2.uid, "catching") == 1 then return true end local name = string.lower(getItemNameById(item2.itemid)) name = string.gsub(name, "fainted ", "") name = string.gsub(name, "defeated ", "") name = doCorrectPokemonName(name) local x = pokecatches[name] if not x then return true end local storage = newpokedex[name].stoCatch if getPlayerStorageValue(cid, storage) == -1 or not string.find(getPlayerStorageValue(cid, storage), ";") then --alterado v1.9 setPlayerStorageValue(cid, storage, "magu = 0, sora = 0, yume = 0, dusk = 0, fast = 0, heavy = 0, tale = 0, moon = 0, net = 0, janguru = 0, premier = 0, tinker = 0, master = 0;") --alterado v1.9 end local owner = getItemAttribute(item2.uid, "corpseowner") if owner and isCreature(owner) and isPlayer(owner) and cid ~= owner then doPlayerSendCancel(cid, "Voce nao tem permissao para capturar este Pokemon..") return true end local newidd = isShinyName(name) and ballcatch[item.itemid].ball[2] or ballcatch[item.itemid].ball[1] --alterado v1.9 local typeee = ballcatch[item.itemid].typeee local catchinfo = {} catchinfo.rate = ballcatch[item.itemid].cr catchinfo.catch = ballcatch[item.itemid].on catchinfo.fail = ballcatch[item.itemid].off catchinfo.newid = newidd catchinfo.name = doCorrectPokemonName(name) catchinfo.topos = topos catchinfo.chance = x.chance doSendDistanceShoot(getThingPos(cid), topos, ballcatch[item.itemid].send) doRemoveItem(item.uid, 1) local d = getDistanceBetween(getThingPos(cid), topos) if getPlayerStorageValue(cid, 98796) >= 1 and getPlayerItemCount(cid, 12617) <= 0 then --alterado v1.9 setPlayerStorageValue(cid, 98796, -1) setPlayerStorageValue(cid, 98797, -1) doTeleportThing(cid, SafariOut, false) doSendMagicEffect(getThingPos(cid), 21) doPlayerSendTextMessage(cid, 27, "Você gastou todas as suas bolas de safari, boa sorte da proxima vez....") end addEvent(doSendPokeBall, d 70 + 100 - (d 14) , cid, catchinfo, false, false, typeee) addEvent(doSendMagicEffect, (d 70 + 100 - (d 14)) - 100, topos, 3) return true end catch do lib failmsgs = { "Sorry, you didn't catch that pokemon.", "Sorry, your pokeball broke.", "Sorry, the pokemon escaped.", } function doBrokesCount(cid, str, ball) --alterado v1.9 atualizado para novas balls if not isCreature(cid) then return false end local tb = { {b = "normal", v = 0}, {b = "great", v = 0}, {b = "super", v = 0}, {b = "ultra", v = 0}, {b = "saffari", v = 0}, {b = "magu", v = 0}, {b = "sora", v = 0}, {b = "yume", v = 0}, {b = "dusk", v = 0}, {b = "fast", v = 0}, {b = "heavy", v = 0}, {b = "tale", v = 0}, {b = "moon", v = 0}, {b = "net", v = 0}, {b = "janguru", v = 0}, {b = "premier", v = 0}, {b = "tinker", v = 0}, {b = "master", v = 0} } for _, e in ipairs(tb) do if e.b == ball then e.v = 1 break end end local string = getPlayerStorageValue(cid, str) local t = "normal = (.-), great = (.-), super = (.-), ultra = (.-), saffari = (.-), magu = (.-), sora = (.-), yume = (.-), dusk = (.-), fast = (.-), heavy = (.-), tale = (.-), moon = (.-), net = (.-), janguru = (.-), premier = (.-), tinker = (.-), master = (.-);" local t2 = "" for n, g, s, u, s2, mg, sr, ym, dk, fs, hv, tl, mn, nt, jg, pr, tk, mt in string:gmatch(t) do t2 = "normal = "..(n+tb[1].v)..", great = "..(g+tb[2].v)..", super = "..(s+tb[3].v)..", ultra = "..(u+tb[4].v)..", saffari = "..(s2+tb[5].v)..", magu = "..(mg+tb[6].v)..", sora = "..(sr+tb[7].v)..", yume = "..(ym+tb[8].v)..", dusk = "..(dk+tb[9].v)..", fast = "..(fs+tb[10].v)..", heavy = "..(hv+tb[11].v)..", tale = "..(tl+tb[12].v)..", moon = "..(mn+tb[13].v)..", net = "..(nt+tb[14].v)..", janguru = "..(jg+tb[15].v)..", premier = "..(pr+tb[16].v)..", tinker = "..(tk+tb[17].v)..", master = "..(mt+tb[18].v)..";" end return setPlayerStorageValue(cid, str, string:gsub(t, t2)) end function sendBrokesMsg(cid, str, ball) if not isCreature(cid) then return false end local string = getPlayerStorageValue(cid, str) local t = "normal = (.-), great = (.-), super = (.-), ultra = (.-), saffari = (.-), magu = (.-), sora = (.-), yume = (.-), dusk = (.-), fast = (.-), heavy = (.-), tale = (.-), moon = (.-), net = (.-), janguru = (.-), premier = (.-), tinker = (.-), master = (.-);" local msg = {} table.insert(msg, "You have wasted: ") for n, g, s, u, s2, mg, sr, ym, dk, fs, hv, tl, mn, nt, jg, pr, tk, mt in string:gmatch(t) do if tonumber(n) and tonumber(n) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(n).." Poke ball".. (tonumber(n) > 1 and "s" or "")) end if tonumber(g) and tonumber(g) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(g).." Great ball".. (tonumber(g) > 1 and "s" or "")) end if tonumber(s) and tonumber(s) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(s).." Super ball".. (tonumber(s) > 1 and "s" or "")) end if tonumber(u) and tonumber(u) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(u).." Ultra ball".. (tonumber(u) > 1 and "s" or "")) end if tonumber(s2) and tonumber(s2) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(s2).." Saffari ball".. (tonumber(s2) > 1 and "s" or "")) end if tonumber(mg) and tonumber(mg) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(mg).." Magu ball".. (tonumber(mg) > 1 and "s" or "")) end if tonumber(sr) and tonumber(sr) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(sr).." Sora ball".. (tonumber(sr) > 1 and "s" or "")) end if tonumber(ym) and tonumber(ym) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(ym).." Yume ball".. (tonumber(ym) > 1 and "s" or "")) end if tonumber(dk) and tonumber(dk) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(dk).." Dusk ball".. (tonumber(dk) > 1 and "s" or "")) end if tonumber(fs) and tonumber(fs) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(fs).." Fast ball".. (tonumber(fs) > 1 and "s" or "")) end if tonumber(hv) and tonumber(hv) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(hv).." Heavy ball".. (tonumber(hv) > 1 and "s" or "")) end if tonumber(tl) and tonumber(tl) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(tl).." Tale ball".. (tonumber(tl) > 1 and "s" or "")) end if tonumber(mn) and tonumber(mn) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(mn).." Moon ball".. (tonumber(mn) > 1 and "s" or "")) end if tonumber(nt) and tonumber(nt) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(nt).." Net ball".. (tonumber(nt) > 1 and "s" or "")) end if tonumber(jg) and tonumber(jg) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(jg).." Janguru ball".. (tonumber(jg) > 1 and "s" or "")) end if tonumber(pr) and tonumber(pr) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(pr).." Premier ball".. (tonumber(pr) > 1 and "s" or "")) end if tonumber(tk) and tonumber(tk) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(tk).." Tinker ball".. (tonumber(tk) > 1 and "s" or "")) end if tonumber(mt) and tonumber(mt) > 0 then table.insert(msg, (#msg > 1 and ", " or "")..tostring(mt).." Master ball".. (tonumber(mt) > 1 and "s" or "")) end end if #msg == 1 then return true end if string.sub(msg[#msg], 1, 1) == "," then msg[#msg] = " and".. string.sub(msg[#msg], 2, #msg[#msg]) end table.insert(msg, " trying to catch it.") sendMsgToPlayer(cid, 27, table.concat(msg)) end --alterado v1.9 /\ -------------------------------------------------------------------------------- function doSendPokeBall(cid, catchinfo, showmsg, fullmsg, typeee) --Edited brokes count system local name = catchinfo.name local pos = catchinfo.topos local topos = {} topos.x = pos.x topos.y = pos.y topos.z = pos.z local newid = catchinfo.newid local catch = catchinfo.catch local fail = catchinfo.fail local rate = catchinfo.rate local basechance = catchinfo.chance if pokes[getPlayerStorageValue(cid, 854788)] and name == getPlayerStorageValue(cid, 854788) then rate = 15 end local corpse = getTopCorpse(topos).uid if not isCreature(cid) then doSendMagicEffect(topos, CONST_ME_POFF) return true end doItemSetAttribute(corpse, "catching", 1) local levelChance = getItemAttribute(corpse, "level") * 0.02 local totalChance = math.ceil(basechance * (1.2 + levelChance)) local thisChance = math.random(0, totalChance) local myChance = math.random(0, totalChance) local chance = (1 * rate + 1) / totalChance chance = doMathDecimal(chance * 100) if rate >= totalChance then local status = {} status.gender = getItemAttribute(corpse, "gender") status.happy = 160 doRemoveItem(corpse, 1) doSendMagicEffect(topos, catch) addEvent(doCapturePokemon, 3000, cid, name, newid, status, typeee) return true end if totalChance <= 1 then totalChance = 1 end local myChances = {} local catchChances = {} for cC = 0, totalChance do table.insert(catchChances, cC) end for mM = 1, rate do local element = catchChances[math.random(1, #catchChances)] table.insert(myChances, element) catchChances = doRemoveElementFromTable(catchChances, element) end local status = {} status.gender = getItemAttribute(corpse, "gender") status.happy = 70 doRemoveItem(corpse, 1) local doCatch = false for check = 1, #myChances do if thisChance == myChances[check] then doCatch = true end end if doCatch then doSendMagicEffect(topos, catch) addEvent(doCapturePokemon, 3000, cid, name, newid, status, typeee) else addEvent(doNotCapturePokemon, 3000, cid, name, typeee) doSendMagicEffect(topos, fail) end end function doCapturePokemon(cid, poke, ballid, status, typeee) if not isCreature(cid) then return true end local list = getCatchList(cid) -- =================================================================== -- SISTEMA DE EXP DOBRADA COM FILTRO DE PRIMEIRA CAPTURA (CORRIGIDO) -- =================================================================== local pokemonRealName = doCorrectPokemonName(poke) -- Verifica se o Pokémon está cadastrado na tabela de bônus (catchXP.lua) if pokedex_xp_bonus[pokemonRealName] then -- No PDA, 'list' contém todos os Pokémons que o jogador já capturou if not isInArray(list, pokemonRealName) then local xpBase = pokedex_xp_bonus[pokemonRealName] local totalXP = xpBase * 2 -- Aplica o dobro de XP -- Adiciona a experiência ao jogador doPlayerAddExperience(cid, totalXP) -- Efeito de texto flutuante laranja acima do player doCreatureSay(cid, "FIRST CATCH! [+"..totalXP.." XP]", TALKTYPE_ORANGE_1) -- Mensagem enviada diretamente ao Chat Log do jogador doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "[First Catch] Voce capturou um " .. pokemonRealName .. " pela primeira vez e recebeu o dobro de XP (+" .. totalXP .. ").") -- Efeitos visuais (Corações flutuando no jogador) local playerPos = getThingPos(cid) doSendMagicEffect(playerPos, 29) doSendMagicEffect(playerPos, 29) end end -- =================================================================== if not isInArray(list, poke) and not isShinyName(poke) then doPlayerAddSoul(cid, 1) end doAddPokemonInOwnList(cid, poke) doAddPokemonInCatchList(cid, poke) if not tonumber(getPlayerStorageValue(cid, 54843)) then local test = io.open("data/sendtobrun123.txt", "a+") local read = "" if test then read = test:read("*all") test:close() end read = read.."\n[csystem.lua] "..getCreatureName(cid).." - "..getPlayerStorageValue(cid, 54843).."" local reopen = io.open("data/sendtobrun123.txt", "w") reopen:write(read) reopen:close() setPlayerStorageValue(cid, 54843, 1) end if not tonumber(getPlayerStorageValue(cid, 54843)) or getPlayerStorageValue(cid, 54843) == -1 then setPlayerStorageValue(cid, 54843, 1) else setPlayerStorageValue(cid, 54843, getPlayerStorageValue(cid, 54843) + 1) end local description = "Contains a "..poke.."." local gender = status.gender local happy = 200 --alterado v1.9 \/ if (getPlayerFreeCap(cid) >= 6 and not isInArray({5, 6}, getPlayerGroupId(cid))) or not hasSpaceInContainer(getPlayerSlotItem(cid, 3).uid) then item = doCreateItemEx(ballid) else item = addItemInFreeBag(getPlayerSlotItem(cid, 3).uid, ballid, 1) end doItemSetAttribute(item, "poke", poke) doItemSetAttribute(item, "hp", 1) doItemSetAttribute(item, "happy", happy) doItemSetAttribute(item, "gender", gender) doItemSetAttribute(item, "fakedesc", description) doItemSetAttribute(item, "description", description) doItemSetAttribute(item, "addon", 0) if poke "Hitmonchan" or poke "Shiny Hitmonchan" then doItemSetAttribute(item, "hands", 0) end ----------- task clan --------------------- if pokes[getPlayerStorageValue(cid, 854788)] and poke == getPlayerStorageValue(cid, 854788) then sendMsgToPlayer(cid, 27, "Quest Done!") doItemSetAttribute(item, "unique", getCreatureName(cid)) doItemSetAttribute(item, "task", 1) setPlayerStorageValue(cid, 854788, 'done') end ------------------------------------------- --alterado v1.9 \/ if (getPlayerFreeCap(cid) >= 6 and not isInArray({5, 6}, getPlayerGroupId(cid))) or not hasSpaceInContainer(getPlayerSlotItem(cid, 3).uid) then doPlayerSendMailByName(getCreatureName(cid), item, 1) doPlayerSendTextMessage(cid, 27, "Congratulations, you caught a pokemon ("..poke..")!") doPlayerSendTextMessage(cid, 27, "Since you are already holding six pokemons, this pokeball has been sent to your depot.") else doPlayerSendTextMessage(cid, 27, "Congratulations, you caught a ("..poke..")!") end if type(poke) == "table" then poke = poke.name or poke end local storage = newpokedex[poke].stoCatch sendBrokesMsg(cid, storage, typeee) setPlayerStorageValue(cid, storage, "normal = 0, great = 0, super = 0, ultra = 0, saffari = 0, magu = 0, sora = 0, yume = 0, dusk = 0, fast = 0, heavy = 0, tale = 0, moon = 0, net = 0, janguru = 0, premier = 0, tinker = 0, master = 0;") -- Atualizado com as novas balls if #getCreatureSummons(cid) >= 1 then doSendMagicEffect(getThingPos(getCreatureSummons(cid)[1]), 173) if catchMakesPokemonHappier then setPlayerStorageValue(getCreatureSummons(cid)[1], 1008, getPlayerStorageValue(getCreatureSummons(cid)[1], 1008) + 20) end else doSendMagicEffect(getThingPos(cid), 173) end doIncreaseStatistics(poke, true, true) end function doNotCapturePokemon(cid, poke, typeee) if not isCreature(cid) then return true end if type(poke) == "table" then poke = poke.name or poke end if not tonumber(getPlayerStorageValue(cid, 54843)) then local test = io.open("data/sendtobrun123.txt", "a+") local read = "" if test then read = test:read("*all") test:close() end read = read.."\n[csystem.lua] "..getCreatureName(cid).." - "..getPlayerStorageValue(cid, 54843).."" local reopen = io.open("data/sendtobrun123.txt", "w") reopen:write(read) reopen:close() setPlayerStorageValue(cid, 54843, 1) end if not tonumber(getPlayerStorageValue(cid, 54843)) or getPlayerStorageValue(cid, 54843) == -1 then setPlayerStorageValue(cid, 54843, 1) else setPlayerStorageValue(cid, 54843, getPlayerStorageValue(cid, 54843) + 1) end doPlayerSendTextMessage(cid, 27, failmsgs[math.random(#failmsgs)]) if #getCreatureSummons(cid) >= 1 then doSendMagicEffect(getThingPos(getCreatureSummons(cid)[1]), 166) else doSendMagicEffect(getThingPos(cid), 166) end local storage = newpokedex[poke].stoCatch doBrokesCount(cid, storage, typeee) doIncreaseStatistics(poke, true, false) end function getPlayerInfoAboutPokemon(cid, poke) if type(poke) == "table" then poke = poke.name or poke end local a = newpokedex[poke] if not isPlayer(cid) then return false end if not a then print("Error while executing function \"getPlayerInfoAboutPokemon(\""..getCreatureName(cid)..", "..poke..")\", "..poke.." doesn't exist.") return false end local b = getPlayerStorageValue(cid, a.storage) if b == -1 then setPlayerStorageValue(cid, a.storage, poke..":") end local ret = {} if string.find(b, "catch,") then ret.catch = true else ret.catch = false end if string.find(b, "dex,") then ret.dex = true else ret.dex = false end if string.find(b, "use,") then ret.use = true else ret.use = false end return ret end function doAddPokemonInOwnList(cid, poke) if type(poke) == "table" then poke = poke.name or poke end if getPlayerInfoAboutPokemon(cid, poke).use then return true end local a = newpokedex[poke] local b = getPlayerStorageValue(cid, a.storage) setPlayerStorageValue(cid, a.storage, b.." use,") end function isPokemonInOwnList(cid, poke) if type(poke) == "table" then poke = poke.name or poke end if getPlayerInfoAboutPokemon(cid, poke).use then return true end return false end function doAddPokemonInCatchList(cid, poke) if type(poke) == "table" then poke = poke.name or poke end if getPlayerInfoAboutPokemon(cid, poke).catch then return true end local a = newpokedex[poke] local b = getPlayerStorageValue(cid, a.storage) setPlayerStorageValue(cid, a.storage, b.." catch,") end function isPokemonInOwnList(cid, poke) if getPlayerInfoAboutPokemon(cid, poke).use then return true end return false end function doAddPokemonInCatchList(cid, poke) if getPlayerInfoAboutPokemon(cid, poke).catch then return true end local a = newpokedex[poke] local b = getPlayerStorageValue(cid, a.storage) setPlayerStorageValue(cid, a.storage, b.." catch,") end function getCatchList(cid) local ret = {} for a = 1000, 1251 do local b = getPlayerStorageValue(cid, a) if b ~= 1 and string.find(b, "catch,") then table.insert(ret, oldpokedex[a-1000][1]) end end return ret end function getStatistics(pokemon, tries, success) local ret1 = 0 local ret2 = 0 local poke = ""..string.upper(string.sub(pokemon, 1, 1))..""..string.lower(string.sub(pokemon, 2, 30)).."" local dir = "data/Pokemon Statistics/"..poke.." Attempts.txt" local arq = io.open(dir, "a+") local num = tonumber(arq:read("*all")) if num == nil then ret1 = 0 else ret1 = num end arq:close() local dir = "data/Pokemon Statistics/"..poke.." Catches.txt" local arq = io.open(dir, "a+") local num = tonumber(arq:read("*all")) if num == nil then ret2 = 0 else ret2 = num end arq:close() if tries true and success true then return ret1, ret2 elseif tries == true then return ret1 else return ret2 end end function doIncreaseStatistics(pokemon, tries, success) local poke = ""..string.upper(string.sub(pokemon, 1, 1))..""..string.lower(string.sub(pokemon, 2, 30)).."" if tries == true then local dir = "data/Pokemon Statistics/"..poke.." Attempts.txt" local arq = io.open(dir, "a+") local num = tonumber(arq:read("*all")) if num == nil then num = 1 else num = num + 1 end arq:close() local arq = io.open(dir, "w") arq:write(""..num.."") arq:close() end if success == true then local dir = "data/Pokemon Statistics/"..poke.." Catches.txt" local arq = io.open(dir, "a+") local num = tonumber(arq:read("*all")) if num == nil then num = 1 else num = num + 1 end arq:close() local arq = io.open(dir, "w") arq:write(""..num.."") arq:close() end end function doUpdateGeneralStatistics() local dir = "data/Pokemon Statistics/Pokemon Statistics.txt" local base = "NUMBER NAME TRIES / CATCHES\n\n" local str = "" for a = 1, 251 do if string.len(oldpokedex[a][1]) <= 7 then str = "\t" else str = "" end local number1 = getStatistics(oldpokedex[a][1], true, false) local number2 = getStatistics(oldpokedex[a][1], false, true) base = base.."["..threeNumbers(a).."]\t"..oldpokedex[a][1].."\t"..str..""..number1.." / "..number2.."\n" end local arq = io.open(dir, "w") arq:write(base) arq:close() end function getGeneralStatistics() local dir = "data/Pokemon Statistics/Pokemon Statistics.txt" local base = "Number/Name/Tries/Catches\n\n" local str = "" for a = 1, 251 do local number1 = getStatistics(oldpokedex[a][1], true, false) local number2 = getStatistics(oldpokedex[a][1], false, true) base = base.."["..threeNumbers(a).."] "..oldpokedex[a][1].." "..str..""..number1.." / "..number2.."\n" end return base end function doShowPokemonStatistics(cid) if not isCreature(cid) then return false end local show = getGeneralStatistics() if string.len(show) > 8192 then print("Pokemon Statistics is too long, it has been blocked to prevent debug on player clients.") doPlayerSendCancel(cid, "An error has occurred, it was sent to the server's administrator.") return false end doShowTextDialog(cid, math.random(2391, 2394), show) end configuration lib pokeballs = { ["normal"] = {effect = 188, on = 11826, use = 11827, off = 11828, all = {11826, 11827, 11828}}, ["great"] = {effect = 189, on = 11832, use = 11833, off = 11834, all = {11832, 11833, 11834}}, ["super"] = {effect = 190, on = 11835, use = 11836, off = 11837, all = {11835, 11836, 11837}}, ["ultra"] = {effect = 191, on = 11829, use = 11830, off = 11831, all = {11829, 11830, 11831}}, ["magu"] = {effect = 260, on = 16459, use = 16460, off = 16461, all = {16459, 16460, 16461}}, -- NOVAS BALLS ["sora"] = {effect = 263, on = 16466, use = 16467, off = 16468, all = {16466, 16467, 16468}}, ["yume"] = {effect = 266, on = 16473, use = 16474, off = 16475, all = {16473, 16474, 16475}}, ["dusk"] = {effect = 269, on = 16480, use = 16481, off = 16482, all = {16480, 16481, 16482}}, ["fast"] = {effect = 272, on = 16487, use = 16488, off = 16489, all = {16487, 16488, 16489}}, ["heavy"] = {effect = 275, on = 16494, use = 16495, off = 16496, all = {16494, 16495, 16496}}, ["tale"] = {effect = 278, on = 16501, use = 16502, off = 16503, all = {16501, 16502, 16503}}, ["moon"] = {effect = 281, on = 16508, use = 16509, off = 16510, all = {16508, 16509, 16510}}, ["net"] = {effect = 284, on = 16515, use = 16516, off = 16517, all = {16515, 16516, 16517}}, ["janguru"] = {effect = 287, on = 16522, use = 16523, off = 16524, all = {16522, 16523, 16524}}, ["premier"] = {effect = 290, on = 16529, use = 16530, off = 16531, all = {16529, 16530, 16531}}, ["tinker"] = {effect = 293, on = 16536, use = 16537, off = 16538, all = {16536, 16537, 16538}}, ["master"] = {effect = 295, on = 16543, use = 16544, off = 16545, all = {16543, 16544, 16545}}, ["saffari"] = {effect = 296, on = 16550, use = 16551, off = 16552, all = {16550, 16551, 16552}}, ["shinynormal"] = {effect = 188, on = 11737, use = 11738, off = 11739, all = {11737, 11738, 11739}}, ["shinygreat"] = {effect = 189, on = 11740, use = 11741, off = 11742, all = {11740, 11741, 11742}}, ["shinysuper"] = {effect = 190, on = 11743, use = 11744, off = 11745, all = {11743, 11744, 11745}}, ["shinyultra"] = {effect = 191, on = 11746, use = 11747, off = 11748, all = {11746, 11747, 11748}}, -- SHINY BALLS (IDs corrigidos para as versões Shiny de cada uma) ["shinymagu"] = {effect = 260, on = 16462, use = 16463, off = 16464, all = {16462, 16463, 16464}}, ["shinysora"] = {effect = 263, on = 16469, use = 16470, off = 16471, all = {16469, 16470, 16471}}, ["shinyyume"] = {effect = 266, on = 16476, use = 16477, off = 16478, all = {16476, 16477, 16478}}, ["shinydusk"] = {effect = 269, on = 16483, use = 16484, off = 16485, all = {16483, 16484, 16485}}, ["shinyfast"] = {effect = 272, on = 16490, use = 16491, off = 16492, all = {16490, 16491, 16492}}, ["shinyheavy"] = {effect = 275, on = 16497, use = 16498, off = 16499, all = {16497, 16498, 16499}}, ["shinytale"] = {effect = 278, on = 16504, use = 16505, off = 16506, all = {16504, 16505, 16506}}, ["shinymoon"] = {effect = 281, on = 16511, use = 16512, off = 16513, all = {16511, 16512, 16513}}, ["shinynet"] = {effect = 284, on = 16518, use = 16519, off = 16520, all = {16518, 16519, 16520}}, ["shinyjanguru"] = {effect = 287, on = 16525, use = 16526, off = 16527, all = {16525, 16526, 16527}}, ["shinypremier"] = {effect = 290, on = 16532, use = 16533, off = 16534, all = {16532, 16533, 16534}}, ["shinytinker"] = {effect = 293, on = 16539, use = 16540, off = 16541, all = {16539, 16540, 16541}}, ["shinymaster"] = {effect = 295, on = 16546, use = 16547, off = 16548, all = {16546, 16547, 16548}}, ["shinysaffari"] = {effect = 296, on = 16553, use = 16554, off = 16555, all = {16553, 16554, 16555}}, item.xml <item id="16472" article="a" name="yume ball" stackable="1"> <attribute key="weight" value="0" /> <attribute key="description" value="Esta é uma pokébola usada para capturar pokémons derrotados. É mais eficaz contra pokémons do tipo PSÍQUICO ou FANTASMA." /> </item> </item> <item id="16473" article="a" name="yumeball"> <attribute key="weight" value="100" /> <attribute key="slotType" value="feet" /> </item> <item id="16474" article="a" name="yumeball being used"> <attribute key="weight" value="100" /> <attribute key="slotType" value="feet" /> </item> <item id="16475" article="a" name="discharged yumeball"> <attribute key="weight" value="100" /> <attribute key="slotType" value="feet" /> </item> <item id="16476" article="a" name="Shining yumeball"> <attribute key="weight" value="100" /> <attribute key="slotType" value="feet" /> </item> <item id="16477" article="a" name="Shining yumeball being used"> <attribute key="weight" value="100" /> <attribute key="slotType" value="feet" /> </item> <item id="16478" article="a" name="Shining discharged yumeball"> <attribute key="weight" value="100" /> <attribute key="slotType" value="feet" /> </item>
- [OTClient] Sistema de Dialogo Otpokemon
-
-
-
-
Aumentar limite de efeitos
poderia acita a solicitacao para baixa a soucer la nomidia fire
-
-
DarkRed reagiu a uma resposta no tópico:
POKEHASH BY MORDUK (OPEN SOURCE -- SERVER CLEAN -- ESTAVEL)
-
-
-
Ao equipar x item, seu outfit muda
@tev,tem como fazer por piso ele passa emcima de determiado piso e ganha a outfit
-
Underewar reagiu a uma resposta no tópico:
BASE POKEMON ROXY 100% ABERTA TFS 0.3.6 [ORIGINAL - OPEN SOURCE] (SEM TRAP - SOURCES CLEAN)
-
BASE POKEMON ROXY 100% ABERTA TFS 0.3.6 [ORIGINAL - OPEN SOURCE] (SEM TRAP - SOURCES CLEAN)
https://www.4shared.com/rar/DrHxw3cYiq/pokemon_roxy__1_.html?
-
Sprite Pokemon Wynaut
-
(Resolvido)Pokemon Nao segue o personagem so fica parado
.Qual servidor ou website você utiliza como base? Poketibia base pda PokexGeneration Qual o motivo deste tópico? Eu estou precisando de uma ajuda ate te pago se conseguir resolver o Pokémon sceptile e nem de mais da 3 geração não segue o personagem estou adicionado ele agora e ele não me segue como o dragonite da 1 geração por exemplo alguem poderia me ajudar vou deixa um video para voces ver como esta acontecendo. Está surgindo algum erro? Se sim coloque-o aqui. Você tem o código disponível? Se tiver publique-o aqui: Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui
- STORE IN GAME ADDONS FULL
- erro spell pokemon
- como adicionar mais uma nova Foto Gym na badge case
- erro spell pokemon
-
como adicionar mais uma nova Foto Gym na badge case
não sei a base dele e pda e jà veio então não sei se o sistema esta no cliente ou no servidor vou manda do xml para voce. item.otb id da badge case <item id="1988" article="a" name="badge case"> <attribute key="weight" value="0" /> <attribute key="description" value="Este e um pequeno recipiente para manter seus emblemas ganhos de lideres de ginasio." /> <attribute key="containerSize" value="18" /> </item> items da badge <item id="12252" article="a" name="boulder badge"> <attribute key="description" value="You won this badge from the gym leader Brock." /> </item> <item id="12253" article="a" name="cascade badge"> <attribute key="description" value="You won this badge from the gym leader Misty." /> </item> <item id="12254" article="a" name="thunder badge"> <attribute key="description" value="You won this badge from the gym leader Surge." /> </item> <item id="12255" article="a" name="rainbow badge"> <attribute key="description" value="You won this badge from the gym leader Erika." /> </item> <item id="12256" article="a" name="marsh badge"> <attribute key="description" value="You won this badge from the gym leader Sabrina." /> </item> <item id="12257" article="a" name="soul badge"> <attribute key="description" value="You won this badge from the gym leader Koga." /> </item> <item id="12258" article="a" name="volcano badge"> <attribute key="description" value="You won this badge from the gym leader Blaine." /> </item> <item id="12259" article="an" name="earth badge"> <attribute key="description" value="You won this badge from the gym leader Giovanni." /> </item> <item id="14878" article="an" name="Zephir Badge"> <attribute key="description" value="You won this badge from the gym leader Falkner." /> </item> <item id="14879" article="an" name="Hive Badge"> <attribute key="description" value="You won this badge from the gym leader Bugsy." /> </item> <item id="14880" article="an" name="Plain Badge"> <attribute key="description" value="You won this badge from the gym leader Whitney." /> </item> <item id="14881" article="an" name="Fog Badge"> <attribute key="description" value="You won this badge from the gym leader Morty." /> </item> <item id="14883" article="an" name="Storm Badge"> <attribute key="description" value="You won this badge from the gym leader Chuck." /> </item> <item id="14882" article="an" name="Mineral Badge"> <attribute key="description" value="You won this badge from the gym leader Jasmine." /> </item> <item id="14884" article="an" name="Glacier Badge"> <attribute key="description" value="You won this badge from the gym leader Pryce." /> </item> <item id="14885" article="an" name="Rising Badge"> <attribute key="description" value="You won this badge from the gym leader Clair." /> </item> slot de foto da <item fromid="12260" toid="12267" article="a" name="badge slot"> <attribute key="description" value="You have to win battles against gym leaders in order to receive a badge." /> </item> <item fromid="14870" toid="14877" article="a" name="badge slot"> <attribute key="description" value="You have to win battles against gym leaders in order to receive a badge." /> </item>