Ir para conteúdo
  • Cadastre-se

Posts Recomendados

  • 1 month later...
  • 3 months later...
  • 2 months later...
  • 1 month later...
  • 1 month later...
  • 4 months later...
  • 1 month later...
  • 7 months later...

Participe da conversa

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

Visitante
Responder

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.


  • Conteúdo Similar

    • Por chateadoagr
      Atualização v1.7.0

      Chance de Spawn de Monstro: Ao matar vários monstros conhecidos existe a chance de invocar um monstro, por exemplo ao matar uma aranha gigante existe a chance da Velha Viúva aparecer, essa probabilidade dependendo do monstro foi ajustada para o seguinte,
      Exemplo

      :
      Rotworm, para Ao morrer para invocar uma rainha Rotworm, a probabilidade é de 15%, enquanto uma aranha gigante para invocar a Velha Viúva é de 5%.

      Aqui está uma lista dos monstros :
      Rotworm > Rotworm Queen - 15%
      Cyclops > Cyclops Smith - 15%
      Wolf > War Wolf - 15%
      Dragon > Dragon Lord - 8%
      Giant Spider > The Old Widow - 5%
      Magma Crawler > Weeper - 5%
      Serpent Spawn > Medusa - 5%
      Frazzlemaw > Guzzlemaw - 5%
      Midnight Asura > Dawnfire Asura - 5%
      Warlock > Infernalist - 5%
      Sea Serpent > Seacrest Serpent - 5%
      Glooth Anemone > Rustheap Golem - 5%
      Hellspawn > Plaguesmith - 4 %
      Worker Golem > War Golem - 4%
      Demon Outcast > Vexclaw - 4%
      Sight of Surrender > Horadron - 3%

      Azure Portal : Existem agora 4 sites onde portais podem aparecer, o que leva a uma missão.
      Os portais aparecem em:
      Arkeron / Dolwatha / Freewind e Death Valley .
      Para saber as posições veja o arquivo: data/scripts/custom/portal_gates.lua
      Para ver os mapas, abra os mapas localizados em data/world/portals
      Uma vez aberto para ir para a posição, veja o arquivo portal_gates, que indica o exitPosition , marque essa posição e você poderá retocar a porta do portal, se desejar.

      Esses portais levam todos para a nova Caverna Azure, onde encontrarão novos Monstros e um Boss chamado Azure.

      15 Novos Monstros
      3 Novos Bosses

      Combate + Mecânica de Acesso + Boss Combat :
      Eles devem encontrar o caminho para chegar à sala central, na qual deverão usar a pedra azul do santuário para desbloquear o caminho, terão então um certo tempo para correr em direção a ela ... próximo santuário.
      Ao chegar na sala central, você deve destrancar a porta. Aqui, você terá que mudar a posição dos humanos congelados no chão. Ao clicar em todas as estátuas, a porta será removida por um tempo e você poder passar pelo portal.
      Eles se enfrentarão na ordem: Terror Spider (sem loot, sim experiência), que se transformará em Deep Necromancer (Sem loot, sim experiência) que por sua vez se transformará em Azure (Loot + Experience + Rarity Loot), Azure faz não terá muita complicação se ele não conseguir acertar e fazer um aoe bem forte, tome cuidado alguns Azure Guards irão aparecer durante a luta para desequilibrar a luta, aguente firme e desafie o Azure!

      Os monstros possuem novos recursos, esses recursos podem ser vendidos respectivamente para os NPCs (yasir, hana...)
      2 Novos Trajes - Anjo Pequeno / Everblight (Masculino / Feminino - Com Montaria) que são obtidos com a moeda do pesadelo (obtida por matar o chefe Azure)

      4 Novos Conjuntos :
      Seetheras / Varruth: Cavaleiros
      Netherwave: Druidas e Feiticeiros
      Felsinger: Paladinos

      3 Novas Moedas :
      Moeda Ancestral : Permite usá-la e obter Moedas Ancestrais para usar na Loja Ancestral. (Obtido: Azure Portal Monsters (rare loot))
      Nightmare Coin : (Obtido: Boss Azure (Azure Portals)) Usado para obter os 2 novos trajes: Small Angel & Everblight, trocado com o npc Estherya, localizado em frente ao portal Azure.
      Azure Coin : Usado com o Npc: Taerar para comprar os novos conjuntos (Obtido: Boss Azure)
      Taerar Npc: Está localizado na entrada dentro da Azure Cave.

      Adicionado conjunto de gnomo, amuleto de rabo de raposa, anel de borboleta, capa de pena de cisne, frasco de luz estelar, espelho lunar e coletor de sol, que são saqueados de portais Azure (diretamente de monstros) Adicionado Azure e monstros à Tarefa Ancestral (Azure, Tarefa Diária,

      Monstros
      Normal Tarefas) com recompensa Ancestral Coin / Azure Coin e Nightmare Coin.

      Melhorado/Corrigido
      Alterada a primeira letra do arquivo .lua (dentro do xml do NPCS) de maiúscula para minúscula, o que gerava um erro nos sistemas operacionais Ubuntu.
      Cavernas do Pesadelo e do Ceifador dolwatha: Adicionados mais Pesadelos, descendentes do pesadelo e Ceifadores à caverna.
      Corrigido terreno sem bordas na parte externa da caverna.
      Cavernas Glooth em Dolwatha, adicionado mais terreno para evitar ver o preto do mapa (tela 4k)
      Corrigida uma dica de ferramenta na web na parte de mineração da Wikipedia.
                Atualização v1.6.0

      - Criado um novo sistema de Herbalist, com sua habilidade ( SKILL_HERBALIST ) adicionada no cliente, coletar recursos, vendê-los ou criar novas poções.

      - Novas receitas , que serão obtidas de vários monstros (ver site wikipedia)

      - Criadas 6 Novas Poções: Nimble, Hazel e Tumble ( Life & Mana )

      - Uso de poções: jogadores Nimble nível 100, jogadores Hazel nível 150 e jogadores Tumble nível 200.

      - As poções possuem frascos vazios que podem ser vendidos para Alaistar, Asnarus ou Xodet .
      - Poções elaboradas podem ser vendidas no mercado entre jogadores.
       
      Corrigido :
      Visuais :
      Dolwatha do Norte, ciclopes, bordas corrigidas/adicionadas
      Falanaar: Selva, corrigida 1 pedra, 2 águas após a torre azura
      Vale da Morte: Corrigida a entrada do chão para o sono febril
      Arkeron: Corrigida a parte sul de alguns visuais acima da água, grama rochosa deslocada de a pedra "menir"
       
      Área de artesanato ao norte de Dolwatha


      Novo efeito


      Novas Plantas


      Novos recursos


      Novas ferramentas


      Novas receitas e poções
          Atualização v1.5.0

      - Adicionada uma ação de conversação !shop para receber itens da web se eles usarem uma loja.

      Sistema de Masmorras

      O Sistema de Masmorras pode ser ativado através do portal em Mordragor, no momento apenas 1 masmorra está disponível, a Masmorra dos Ossos.
      Esta masmorra tem um cooldown de 30 minutos, caso não o façam dentro desse tempo serão expulsos.
      Só é permitido entrar 1 equipe por vez (Depois vou criar mais, o que vai evitar que fique sempre lotado, também vou organizar para que essa mesma equipe se repita mais caso uma esteja lotada, deixa eu explicar, na mesma masmorra apenas X jogadores podem entrar em equipe, se uma equipe estiver dentro, ninguém mais pode entrar até sair, no caso se repetirmos a masmorra adicionando uma nova linha, 2 equipes podem entrar, com 2 mapas diferentes , mas como dito, virá aos poucos.)
      Novos Monstros com nível, mais dano, mais experiência, mais loot, mais vida.
      Novo Chefe Príncipe Esquelético.
      Novo conjunto de esqueleto (capacete, armadura, pernas, botas), este conjunto é baseado em defesa de terra, sanguessuga de vida / mana e estatísticas de artesanato (habilidade de artesanato, habilidade de mineração e habilidade de corte de lenha, +3 em peças)

      . deve saquear um recurso chamado Enchanted Bone Skull que permitirá acesso à alavanca do chefe. Este recurso pode ser vendido para Yasir.
      Príncipe Esqueleto faz parte da Tarefa Diária como chefe para matar no Sistema Ancestral.
      Alterada a distância em que um monstro pode ver um jogador (10 norte/sul, 15 leste/oeste)   Imagens:
       
       
       
          Atualização v1.4.0


      Criado um Sistema de Tarefas Ancestrais que funciona com o banco de dados (2 novas colunas em jogadores). Os pontos são somados por Jogador e não por conta, posteriormente provavelmente será adicionada uma moeda que lhe permitirá comprá-lo na loja e poder obter pontos de outra forma, no momento é apenas através de tarefas.
      Novo NPC Chamado Armin , esse NPC dá Tarefas para os jogadores completarem, mas também dá tarefas diárias, que podem ser feitas a cada 24 horas.
      As tarefas dão Pontos Ancestrais como recompensa e também Pontos de Classificação Ancestral
      .

      Você pode usar o comando: !ancestral para mostrar informações, pontos, classificação, mas também o status das tarefas que você está realizando .

      Existem várias classificações dependendo dos pontos:
      1 - 40 = "Rookie"
      41 - 100 = "Bronze"
      101 - 250 = "Silver" 251 -
      470 = "Gold"
      471 - 770 = "Platinum"
      771 - 1220 = "Diamante "
      1221 - 1820 = "Ancestral"
      1821 - 2820 = "Místico"
      2821 - 4320 = "Abissal"
      4321 - 6320 = "Ascendente"
      6321 - 9999 = "Caos"
      10000 - + = "Despertar"

      Podemos ver a classificação de um jogador clicando duas vezes .

      Existem atualmente 10 tarefas normais e 5 tarefas diárias. Os diários em sua maioria são os chefes.
      Eles conversam com o NPC Armin e perguntam sobre a Lista de Tarefas Ancestrais Diárias ou a Lista de Tarefas Ancestrais Normais. Para iniciar uma tarefa você dirá ao NPC o nome da tarefa (Nome da tarefa por exemplo: Dragões de fogo e a tarefa será iniciada automaticamente.

      Graças aos Pontos Ancestrais, você pode adquirir itens em um novo módulo adicionado ao cliente.
      O Ranking Ancestral terá mais significado posteriormente, assim como os pontos.

      Foi adicionada uma loja para poder utilizar Pontos Ancestrais.
       
        Atualização v1.3.0 Foram removidos alguns scripts que estavam duplicados e geravam um erro de evento duplicado. Corrigidos os nomes dos jogadores que eram exibidos incorretamente ao subir em montarias, com asas, etc. A partir de agora eles estão mais elevados e mais centrados.

      Um sistema de Lenhador, baseado em (SKILL_WOODCUTTING) que determina a nova habilidade Lenhador, com novos recursos, que podem ser vendidos em primeiro lugar para o NPC Rostock.
      5 novos tipos de árvores para cortar, cada uma com seu próprio nível de machado, semelhante à mineração.
      Novo NPC Rostock na saída de Falanaar (para encontrá-lo/vá para Rostock), com nova área de Artesanato do Lenhador, saída sudoeste de Falanar.

      Receitas do Loot Woodcutter: (Adicionadas na web wikipedia)
      Grande pedaço de madeira: Aranha Gigante, Filhote de Dragão
      Tábua de Cinza: Pesadelo, Descendente do Pesadelo,
      Tábua de Castanha Gigante de Gelo: Cuspidor, Grimeleech, Ferreiro da Praga
      Tábua de Oliveira: Marid, Devorador de Pedra, Cereja Caiman
      Assassina Prancha: Hellflayer, Death Dragon

      Adicionadas auras e asas.
      Para dar aos jogadores você deve usar um item ao clicar nele ele dará aura de asa ou shader.    
       
       
          Atualização v1.2.0:

      Adicionado:
      - Nova Pasta com CUSTOM_SCRIPTS, esta pasta incluirá scripts ou alterações que NÃO serão incluídas no servidor, o que você questionou, por se tratar de uma customização diferente, os scripts serão adicionados nesta pasta , nesta atualização teremos o script potions.lua com cooldown adicionado.
      Isso não significa que tudo o que você perguntar será adicionado aqui, mas sim que o que achamos que não precisa ser alterado será encontrado aqui.

      Montarias :
      - Devorador da Luz Negra, Espírito da Pureza, Caveira da Perdição, Caveira de Magma, Caveira Fogo de Copr
      Trajes :
      - Discípulo Shadowlotus, Aucar Antigo, Rastreador de Gelo, Arqueiro Blindado, Mago Eterno, Leão da Guerra, Defensor Decadente, Evocador da Luz Negra, Mago Fúria Flamejante -

      Sistema de Waypoints em cada cidade, você pode adicionar um requisito (item, armazenamento, missão, missão)
      https://streamable.com/xe0pjb

       
      Criado um sistema de Mineração com uma nova Habilidade de Mineração ( SKILL_MINING ), efeitos, são 7 pedras diferentes por níveis:
      Bronze, Prata, Safira, Ouro, Rubi, Ametista, Esmeralda, cada pedra é cortada com sua picareta necessária, nível de mineração necessário o suficiente para esmagar a pedra e/ou criar as receitas na Forja de Mineração, ao olhar uma receita, esta dirá para que serve, os itens necessários, o nível de artesanato necessário e se você desbloqueou a receita.
      A Forja de Mineração está localizada ao sul de Mordragor.
      Atualmente, os lingotes são vendidos para o npc Elyotrope na Mining Forge, posteriormente serão usados para diversos artesanatos.
      No site eles têm Wikipedia indicando as informações.

      Crafting , nova barra de habilidades como mineração, adicionada no cliente ( SKILL_CRAFT ), assim como mineração, começa no nível 10. Os servidores existentes terão uma atualização com um arquivo chamado migração, que atualizará o banco de dados com as habilidades necessárias e será adicionado a todas as existentes. jogadoras.


      - A confecção dos Lingotes exige a obtenção da receita, em troca não é necessária a picareta, mas é necessário ter um nível de artesanato quanto aos diferentes lingotes, indicado na Receita ao olhar a receita.

      Receitas de Mineração de Loot (Lingotes) :
      A ordem dos monstros escritos, o primeiro tem mais sorte que o segundo, terceiro, etc.

      Lingote de Bronze Pequeno : Dragão, Ciclope, Bárbaro Bloodwalker, Elfo Arcanista, Escoteiro Lingote de
      Prata Pequeno: Senhor Dragão, Feiticeiro, Serpente do Mar, Hidra
      Lingote de Safira Pequeno: Hellspawn, Destroyer, Grim Reaper
      Lingote de Ouro Pequeno: Wereboar, Vile Grandmaster, Behemoth
      Small Lingote de Ametista : Fúria, Diabólico Diabólico, Lutador do Inferno
      Lingote de Rubi Pequeno : Demônio, Lagarto Escolhido, Wyrms
      Pequeno Lingote de Esmeralda : Golem de Lava, Aranha Gigante, Reaver da Realidade Lingote de
      Bronze Grande : Dawnfire Asura, Serpent Spawn Lingote de
      Prata Grande : Minotauro Amazon, Minotaur Hunter , Worm Priestess
      Big Sapphire Lingote : Rustheap Golem, Hellhound, Ironblight
      Big Gold Lingote : Juggernault, Dark Torturer, Frazzlemaw
      Big Amethyst Lingote : Draken Spellweaver, Draken Elite, Ghastly Dragon
      Big Ruby Lingote : Grimeleech, Retching Horror, Sight of Surrender
      Big Emerald Lingote : Vexclaw, Terrorsono, Deepling Tyrant
       
       
       

      Por precaução, uma revisão das missões:
      Bosses (alavanca/missão):
      Abyssador, Annihilator, Deep Terror, Jaul, Plagirath, Plagueroot, Professor Maxxen, The Welter, Ushuriel.
       
    • Por Dionidi
      Encontrei esse map editor no GitHub, porém estava sem o executável, então procurando mais por aí, acabei achando ele completo. Créditos ao SoyFabi  
       
      Como você já sabe, mais pessoas começam com novos projetos e precisam de um RME para edição de mapas.
      Aqui trago para vocês o RME mais atualizado até hoje.
      Funciona para todas as versões.
      Este RME tem a possibilidade de mostrar a luz em tempo real.
       

      Este é um editor de mapas para servidores de jogos que é derivado do projeto de servidor OpenTibia.
      É uma bifurcação de um Editor de mapas criado por Remere.
       
       
      DOWNLOAD
      https://www.mediafire.com/file/yypyv2x57q7qavr/RME_4.1.0_Upgrade_2023.rar/file SCAN
      https://www.virustotal.com/gui/file/599efc2c86392c7daa009b19d83b35a6d3da26724abf342d7762bdfbaa3e56f7  


    • Por Glacial
      Boa tarde galera, tudo bem?
      Meu nome é Gustavo/Glacial, gostaria de compartilhar com a comunidade meu projeto solo no RME 3.5 /Client 10.98 do Tibia.
      Espero que curtam ai e podem baixar pra colocar no OT de vocês caso queiram.
       
      Download Mapas: https://www.mediafire.com/folder/hz0q694t9nk86/Mapas_Glacial
      versão 1.0 Virus Total: https://www.virustotal.com/gui/file/b4e94903752e24aba63b291f9929f15f6bd7f4feb44d5a1f42ec3d755ee7977e?nocache=1
      versão 2.0 Virus Total: https://www.virustotal.com/gui/file/d88ae087e966bed6e2f2348f31246c1858831c1fb13d4e8613ba98f6ede37503?nocache=1
       
      Fotos e detalhes no post atualizado e continuação do projeto:
       
       
      Obrigado pela atenção!
      Att.
      Gustavo Glacial.
    • Por pota
      Desenvolvi por muito tempo uma base Pokémon do 0 (parti do TFS 1.2 e fui implementando tudo até chegar nessa versão que estou disponibilizando). O resultado é um servidor extremamente leve e estável (já testado com 100+ players e por mais de 1 mês sem cair). Basicamente, ele suporta tranquilamente 1k+ players e não tem nenhum bug conhecido que faça com que ele caia.
       
      Esse servidor ficou no ar por muito tempo (mais de 2 anos) e era conhecido como PokeDash. Acabei ficando sem tempo para administrar o servidor, o que fez com que a maioria dos players parassem de jogar e com que eu fechasse de vez.
       
      Pensei por muito tempo sobre o que fazer com ele, e decidi disponibilizar para a comunidade. Trata-se de algo único (eu ao menos nunca vi um servidor de Pokémon construído a partir do TFS 1.2)!
       
      Como desenvolvi todos os sistemas do 0, tomei cuidado para fazer tudo da melhor maneira possível e para que possa ser facilmente modificado e atualizado. Basicamente, os Pokémons podem ser criados a partir de um único arquivo XML (como monstros do Tibia), e nesse arquivo você pode especificar tudo, desde level máximo e mínimo de spawn, loots, tipos (fogo, agua, etc), se ele pode usar habilidades (surf, fly, etc), moves (quando alguém captura), ataques (quando selvagem), evoluções, chance de catch, etc.
      Exemplo de Pokemon
      Resumo de alguns sistemas (tem muita coisa, então coloquei os principais)
      ✅ Pokemons com level, status e boost. O level do player/boost também influencia no status dos pokes.
      ✅ Sistema de Love (seu poke fica mais forte que os demais quando upa de level matando pokemons mais fortes que ele).
      ✅ Base propria com Shinys e Ancients.
      ✅ Cada player pode conseguir ancient stone para evoluir 1 shiny para ancient através de quest.
      ✅ Moves bar e pokemon bar (troca de pokemon com 1 click).
      ✅ Autoloot agrupando em bags.
      ✅ Ganho de exp ao capturar/dar dex em pokes com um bonus adicional para o primeiro catch de cada poke.
      ✅ Mapa original com mais de 40 quests, incluindo outland com Ancients.
      ✅ Eventos diários automáticos: Futebol todo dia 19:30, arena PVP todo dia 20:00, golden arena aos sabados 17:00, bag premiada aos domingos/feriados 17:00.
      ✅ Profissões (facilmente customizáveis):
      Catcher: 3.5% mais chance de capturar um Pokemon. Hunter: 10% mais status de dano para o seu Pokemon (tanto magico quanto fisico). Blocker: 25% mais vida para seus Pokemons. Healer: 100% mais cura que aplica tanto em potions quando moves dos seus Pokemons. Explorer: 15% mais experiencia para seu personagem durante a caça. ✅ Task diária de catch/loot dando Tokens. Os tokens podem ser trocados por itens raros (dentre eles premier ball e bags personalizadas) além de pagar seu curso com o NPC Job Manager para aprender uma das profissões acima. Uma das maneiras de conseguir tokens é fazendo tasks diárias.
      ✅ Muito mais!
      Screenshots

       

      Download
      Baixe o pack contendo o servidor, cliente, site, editor de mapa e editor de itens clique aqui!. Caso considere minha contribuição interessante para a comunidade, considere realizar uma doação para a chave pix: [email protected]
      GM account: gm/gmgmgm
      O projeto será atualizado em sua homepage: https://pokedashpota.vercel.app/
       
      SCAN
       
      ---EDIT---
      Download sources
      SCAN
       
       Problemas e soluções
      GroupID não existe ao tentar logar no server.
       
      Erros ao importar o schema.sql.
       
      Comando /cb não funcionando:
       
    • Por Codex NG
      Sorry I don't speak spanish so you will have to bare with me.
       
      This is a new way for people to create npc's which use different types of currency, rather than a coming up with different items to trade with the npc or trying to edit the npc modules this method simplifies everything by providing the npc with a npc currency id.
       
      All this npc currency id is, is a storage value.. pretty simple eh?
      If the npc doesn't have a currency id then it will use the normal currency e.g. gold, plat, cc etc..
       
      I originally posted this on otland, but fuck them xD
       
      Using Lailene here you can see she has a currency attribute with id of 123456
      <?xml version="1.0" encoding="UTF-8"?> <npc name="Lailene" currency="123456" script="lailene.lua" walkinterval="2000" floorchange="0" speechbubble="2"> <health now="100" max="100"/> <look type="279" head="114" body="94" legs="113" feet="114" addons="0"/> </npc>  
      Now any player who has a storage value of 123456 can purchase things from her shop provided they have enough value stored within the storage, similar to having money in the bank.
      The money or in this case the storage value is added and removed from the player in real time.
       
      Lets get to the code
       
      game.cpp
      Find this
      bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) Replace the whole function with this.
      bool Game::removeMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) { if (cylinder == nullptr) { return false; } if (money == 0) { return true; } uint32_t currencyId = 0; Player* player; if (Creature* creature = cylinder->getCreature()) { if (Player* p = creature->getPlayer()) { currencyId = p->getNpcCurrencyId(); player = p; } } if (!currencyId) { std::vector<Container*> containers; std::multimap<uint32_t, Item*> moneyMap; uint64_t moneyCount = 0; for (size_t i = cylinder->getFirstIndex(), j = cylinder->getLastIndex(); i < j; ++i) { Thing* thing = cylinder->getThing(i); if (!thing) { continue; } Item* item = thing->getItem(); if (!item) { continue; } Container* container = item->getContainer(); if (container) { containers.push_back(container); } else { const uint32_t worth = item->getWorth(); if (worth != 0) { moneyCount += worth; moneyMap.emplace(worth, item); } } } size_t i = 0; while (i < containers.size()) { Container* container = containers[i++]; for (Item* item : container->getItemList()) { Container* tmpContainer = item->getContainer(); if (tmpContainer) { containers.push_back(tmpContainer); } else { const uint32_t worth = item->getWorth(); if (worth != 0) { moneyCount += worth; moneyMap.emplace(worth, item); } } } } if (moneyCount < money) { return false; } for (const auto& moneyEntry : moneyMap) { Item* item = moneyEntry.second; if (moneyEntry.first < money) { internalRemoveItem(item); money -= moneyEntry.first; } else if (moneyEntry.first > money) { const uint32_t worth = moneyEntry.first / item->getItemCount(); const uint32_t removeCount = (money / worth) + 1; addMoney(cylinder, (worth * removeCount) - money, flags); internalRemoveItem(item, removeCount); break; } else { internalRemoveItem(item); break; } } } else { int32_t value; player->getStorageValue(currencyId, value); if (value < money) { return false; } player->addStorageValue(currencyId, value - money); } return true; } Next find this
      void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) Replace the whole function with this
      void Game::addMoney(Cylinder* cylinder, uint64_t money, uint32_t flags /*= 0*/) { if (money == 0) { return; } if (Creature* creature = cylinder->getCreature()) { if (Player* player = creature->getPlayer()) { if(uint32_t currencyId = player->getNpcCurrencyId()){ int32_t value; player->getStorageValue(currencyId, value); player->addStorageValue(currencyId, value + money); return; } } } uint32_t crystalCoins = money / 10000; money -= crystalCoins * 10000; while (crystalCoins > 0) { const uint16_t count = std::min<uint32_t>(100, crystalCoins); Item* remaindItem = Item::CreateItem(ITEM_CRYSTAL_COIN, count); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT); } crystalCoins -= count; } uint16_t platinumCoins = money / 100; if (platinumCoins != 0) { Item* remaindItem = Item::CreateItem(ITEM_PLATINUM_COIN, platinumCoins); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT); } money -= platinumCoins * 100; } if (money != 0) { Item* remaindItem = Item::CreateItem(ITEM_GOLD_COIN, money); ReturnValue ret = internalAddItem(cylinder, remaindItem, INDEX_WHEREEVER, flags); if (ret != RETURNVALUE_NOERROR) { internalAddItem(cylinder->getTile(), remaindItem, INDEX_WHEREEVER, FLAG_NOLIMIT); } } }  
      npc.cpp
      Look for this
      pugi::xml_attribute attr; if ((attr = npcNode.attribute("speed"))) { baseSpeed = pugi::cast<uint32_t>(attr.value()); } else { baseSpeed = 100; } Right underneath that you are going to place this.
      if ((attr = npcNode.attribute("currency"))) { currency = pugi::cast<uint32_t>(attr.value()); }  
      npc.h
      Look for this
      bool isPushable() const final { return walkTicks > 0; } Place this right underneath
      uint32_t getCurrencyId() const { return currency; } Look for this
      uint32_t walkTicks; Place this right underneath
      uint32_t currency;  
      player.cpp
      Find this
      void Player::openShopWindow(Npc* npc, const std::list<ShopInfo>& shop) Replace that function with this
      void Player::openShopWindow(Npc* npc, const std::list<ShopInfo>& shop) { shopItemList = shop; sendShop(npc); sendSaleItemList(npc); } Next find this
      bool Player::updateSaleShopList(const Item* item) Replace that function with this
      bool Player::updateSaleShopList(const Item* item) { uint16_t itemId = item->getID(); if (itemId != ITEM_GOLD_COIN && itemId != ITEM_PLATINUM_COIN && itemId != ITEM_CRYSTAL_COIN) { auto it = std::find_if(shopItemList.begin(), shopItemList.end(), [itemId](const ShopInfo& shopInfo) { return shopInfo.itemId == itemId && shopInfo.sellPrice != 0; }); if (it == shopItemList.end()) { const Container* container = item->getContainer(); if (!container) { return false; } const auto& items = container->getItemList(); return std::any_of(items.begin(), items.end(), [this](const Item* containerItem) { return updateSaleShopList(containerItem); }); } } if (client) { client->sendSaleItemList(shopOwner, shopItemList); } return true; } Next you are going to look for
      uint64_t Player::getMoney() const Now right underneath that function you are going to place these.
      uint64_t Player::getMoney(Npc* npc) const { uint64_t cash; setNpcCurrencyId(npc); uint32_t currencyId = getNpcCurrencyId(); if (currencyId) { int32_t value; getStorageValue(currencyId, value); cash = (uint64_t)value; } else { cash = getMoney(); } return cash; } void Player::setNpcCurrencyId(Npc* npc) const{ currencyId = npc->getCurrencyId(); } uint32_t Player::getNpcCurrencyId() const { return currencyId; }  
      player.h
      Look for this
      uint64_t getMoney() const; Place this right underneath
      uint64_t getMoney(Npc*) const; void setNpcCurrencyId(Npc*) const; uint32_t getNpcCurrencyId() const; Find this
      void sendShop(Npc* npc) const { if (client) { client->sendShop(npc, shopItemList); } } Place this right underneath
      void sendSaleItemList(Npc* npc) const { if (client) { client->sendSaleItemList(npc, shopItemList); } } Find this
      uint32_t manaMax; Place this right underneath
      mutable uint32_t currencyId;  
      protocolgame.cpp
      Now find this function
      void ProtocolGame::sendSaleItemList(const std::list<ShopInfo>& shop) Place this right underneath
      void ProtocolGame::sendSaleItemList(Npc* npc, const std::list<ShopInfo>& shop) { NetworkMessage msg; msg.addByte(0x7B); msg.add<uint64_t>(player->getMoney(npc)); std::map<uint16_t, uint32_t> saleMap; if (shop.size() <= 5) { // For very small shops it's not worth it to create the complete map for (const ShopInfo& shopInfo : shop) { if (shopInfo.sellPrice == 0) { continue; } int8_t subtype = -1; const ItemType& itemType = Item::items[shopInfo.itemId]; if (itemType.hasSubType() && !itemType.stackable) { subtype = (shopInfo.subType == 0 ? -1 : shopInfo.subType); } uint32_t count = player->getItemTypeCount(shopInfo.itemId, subtype); if (count > 0) { saleMap[shopInfo.itemId] = count; } } } else { // Large shop, it's better to get a cached map of all item counts and use it // We need a temporary map since the finished map should only contain items // available in the shop std::map<uint32_t, uint32_t> tempSaleMap; player->getAllItemTypeCount(tempSaleMap); // We must still check manually for the special items that require subtype matches // (That is, fluids such as potions etc., actually these items are very few since // health potions now use their own ID) for (const ShopInfo& shopInfo : shop) { if (shopInfo.sellPrice == 0) { continue; } int8_t subtype = -1; const ItemType& itemType = Item::items[shopInfo.itemId]; if (itemType.hasSubType() && !itemType.stackable) { subtype = (shopInfo.subType == 0 ? -1 : shopInfo.subType); } if (subtype != -1) { uint32_t count; if (!itemType.isFluidContainer() && !itemType.isSplash()) { count = player->getItemTypeCount(shopInfo.itemId, subtype); // This shop item requires extra checks } else { count = subtype; } if (count > 0) { saleMap[shopInfo.itemId] = count; } } else { std::map<uint32_t, uint32_t>::const_iterator findIt = tempSaleMap.find(shopInfo.itemId); if (findIt != tempSaleMap.end() && findIt->second > 0) { saleMap[shopInfo.itemId] = findIt->second; } } } } uint8_t itemsToSend = std::min<size_t>(saleMap.size(), std::numeric_limits<uint8_t>::max()); msg.addByte(itemsToSend); uint8_t i = 0; for (std::map<uint16_t, uint32_t>::const_iterator it = saleMap.begin(); i < itemsToSend; ++it, ++i) { msg.addItemId(it->first); msg.addByte(std::min<uint32_t>(it->second, std::numeric_limits<uint8_t>::max())); } writeToOutputBuffer(msg); }  
      protocolgame.h
      Find this
      void sendSaleItemList(const std::list<ShopInfo>& shop); Place this right underneath
      void sendSaleItemList(Npc* npc, const std::list<ShopInfo>& shop);  
      luascript.cpp
      Find
      int LuaScriptInterface::luaPlayerAddMoney(lua_State* L) Replace that whole function with this
      int LuaScriptInterface::luaPlayerAddMoney(lua_State* L) { // player:addMoney(money[, currencyId]) uint64_t money = getNumber<uint64_t>(L, 2); uint32_t currencyId = getNumber<uint32_t>(L, 3); Player* player = getUserdata<Player>(L, 1); if (player) { if (currencyId) { int32_t value; player->getStorageValue(currencyId, value); player->addStorageValue(currencyId, value + money); } else { g_game.addMoney(player, money); } pushBoolean(L, true); } else { lua_pushnil(L); } return 1; } Next find this function which should be right below it.
      int LuaScriptInterface::luaPlayerRemoveMoney(lua_State* L) Replace that whole function with this
      int LuaScriptInterface::luaPlayerRemoveMoney(lua_State* L) { // player:removeMoney(money[, currencyId]) Player* player = getUserdata<Player>(L, 1); if (player) { uint64_t money = getNumber<uint64_t>(L, 2); uint32_t currencyId = getNumber<uint32_t>(L, 3); if (currencyId) { int32_t value; player->getStorageValue(currencyId, value); if (value < money) { pushBoolean(L, false); return 1; } player->addStorageValue(currencyId, value - money); pushBoolean(L, true); } else { pushBoolean(L, g_game.removeMoney(player, money)); } } else { lua_pushnil(L); } return 1; }  
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo