Ir para conteúdo
  • Cadastre-se

Git Workflow - Contribuindo com pull requests


KhayrusS

Posts recomendados

Existem diferentes formas de contribuição em projetos open source, sendo uma das principais a contribuição de implementações através do Pull Request. Nesse guia, vou abordar como criar um Pull Request no projeto L2jOrg, mas que poderá ser usado em qualquer projeto que utilize git.

Eu trabalho com git há alguns anos, e durante esse tempo experimentei diversas formas de utilização. Um dos melhores fluxos de trabalho pra utilizar git, na minha opinião, é o modelo "short lived branches" ou "topic branches",  nesse link você pode encontrar mais detalhes.

 

Requisitos para seguir o guia:

 

Obs.: a IDE é opcional, você pode utilizar apenas o cliente git para realizar os passos desse guia, mas por simplicidade será demonstrado apenas com o uso da IDE.

 

1º Passo - Criando um fork do projeto no github

O projeto L2jOrg utiliza submódulos, é necessário realizar o fork de todos os repositórios que pretende fazer contribuições.

A criação de um fork é bastante simples, apenas é necessário estar logado no github, e utilizar o botão fork na página dos repositórios:

 

Vamos criar o fork para o primeiro repositório: https://github.com/L2jOrg/L2JOrg

 

Clique no botão fork no canto superior direito

796191035_Screenshotfrom2021-04-1015-51-13.thumb.png.cd36bf8700e1c87c9f539a637e1cdfb4.png

 

Caso participe de alguma organização no github, aparecerá uma tela para escolher onde será criado o fork

1718636624_Screenshotfrom2021-04-1015-51-54.thumb.png.6225065a05d2c613c308af002c9ea9d5.png

 

Agora faça o mesmo processo para o repositório do Datapack: https://github.com/L2jOrg/Datapack.

Após feito o fork dos dois repositórios,  você terá uma cópia dos repositórios.

 

254715370_Screenshotfrom2021-04-1015-59-00.thumb.png.307f9fd71968c31a155caa167c6f2038.png

 

2º Passo - Clonando  seu repositório

Antes de seguir esse passo, é necessário ter o git instalado.

Após a criação do fork,  iremos fazer o clone dos seus repositório. Esse clone nada mais é do que fazer uma cópia do seu repositório remoto, que está no github, para sua máquina. Assim, podemos modificar os arquivos com mais facilidade.

 

Para realizar o clone, precisamos saber qual o endereço dos nossos repositórios. Podemos encontrar essa informação no github:

Aqui teremos duas opções de url. Utilizando ssh ou https. Eu particulamente utilizo a com ssh por achar mais simples, já que utilizando https é necessário fornecer o usuário e senha do github para se comunicar com o repositório remoto. Caso queira utilizar ssh, mas não sabe como configurar, segue a documentação.

 

No botão "code" do github é onde podemos encontrar as urls necessárias para fazer o clone do repositório. Copie a url que iremos utilizar na IDE, no nosso caso no IntelliJ IDEA.

118425190_Screenshotfrom2021-04-1016-18-31.thumb.png.3e6283a1ea89a1ef52d1eb201316b75e.png

 

A primeira vez que o IntelliJ é aberto, é apresentada uma tela de "Bem Vindo". Apartir dessa tela já podemos realizar o clone do repositório, utilizando o botão "Get from VCS".

1452838153_Screenshotfrom2021-04-1016-24-02.png.938d6562b8d4cf21f25132bfcc68e494.png

 

Se no seu caso, ele já abriu algum projeto que você não queira fechar, é só utlizar o menu "File" -> "New" -> "Project from Version Control"

1609200508_Screenshotfrom2021-04-1016-28-46.thumb.png.2af4e4cb90f0cb87d4246d8138285fe9.png

 

Irá aparecer uma janela para colocar a url do projeto, após adicionar a url e escolher onde seu projeto vai ficar é só clicar em "clone".

71388547_Screenshotfrom2021-04-1016-31-57.png.544efb7b9fa3bdcb2adb37340f30f1a5.png

 

Ao finalizar o clone, o IntelliJ abre a janela com o arquivos do projeto:

Algo que vale à pena mencionar é que mesmo sem ter feito o clone do Datapack, o Intellij realizou o clone automaticamente. Isso ocorre devido ao projeto utlizar submodules. Para mais detalhes veja esse artigo!

263227896_Screenshotfrom2021-04-1016-42-56.thumb.png.452dd59d9d46f483e02190fea5fd179f.png

 

Vemos verificar o conteúdo dos repositório, para isso clique no nome da branch "development" no canto inferior direito.  Aqui é mostrado as branches existentes no repositório.

Nesse caso, o Datapack está em um estado que chamamos de "detached head". Rudemente falando, esse estado indica que fizemos o checkout de um commit específico ao ínves de uma branch. Aqui você encontra mais detalhes!

1439534362_Screenshotfrom2021-04-1017-31-19.thumb.png.cdd1b67e291d498efed189026682b766.png

 

Vamos "corrigir" esse estado fazendo o checkout da branch development. Clique em origin/development e checkout:

1824912423_Screenshotfrom2021-04-1017-34-41.thumb.png.79d85a9ac657fd8779a5644c162384ac.png

 

3º Passo - Configurando Remotes

Agora vamos para uma das mais importantes partes desse guia. Uma das maiores dificuldades que algumas pessoas têm ao se trabalhar com o modelo colaborativo do git, é manter seu repositório atualizado com o repositório oficial.

Quando realizamos um clone de um repositório fork, para o git aquele repositório é o principal. Mas no modelo colaborativo, é necessário configurar o git para reconhecer o repositório oficial também. Isso nos ajudará a manter o repositório atualizado com o oficial.

Para isso vamos configurar "os  Remotes" do git.

 

Vá no menu "Git" -> "Manage Remotes"

1557915069_Screenshotfrom2021-04-1017-00-32.thumb.png.72e35bfae5cd92294a7690c1b6b05648.png

 

Irá aparecer uma janela para configurar os remotes. Note que já temos dois remotes configurados, um para o Core e outro para o Datapack. O remote do core está correto, mas o Datapack está configurado para o repositório oficial. Isso ocorre devido ao arquivo de configuração responsável pelo submodule.

590154545_Screenshotfrom2021-04-1017-02-53.png.95b16b58ad4ebcedf1df06a54c457a10.png

 

Vamos corrigir o Datapack e adicionar mais dois remotes. Para isso vamos pegar a url dos repositórios oficiais. Após a configuração os remotes ficaram assim:

993996063_Screenshotfrom2021-04-1017-18-46.png.145ddd695acc0fee8d79811081a24e8b.png

 

Após a configuração, vamos atualizar o repositório com o conteúdo dos novos remotes, para isso vá no menu  "Git" -> Fetch.

Vamos acessar a tab git do IntelliJ, por padrão fica no canto inferior esquerdo, para vermos com mais detalhes o conteúdo do repositório. Aqui podemos ver os conteúdo tanto do repositório fork quanto do oficial.

1879961155_Screenshotfrom2021-04-1017-42-18.thumb.png.5c9b0cebce7b4647a8224c22e72f2293.png

 

4º Passo - Realizando mudanças

Vamos realizar um mudança simples, apenas para demonstrar como o workflow funciona.

A primeira coisa a fazer antes de realizar a mudança é criar uma nova branch.

Clique na branch development, canto inferior direito, depois "New Branch".

256859805_Screenshotfrom2021-04-1018-27-15.thumb.png.8a593db2a0b51d72597a2fc6ff92eca8.png

 

Der um nome sugestivo para a branch, de forma a dar uma ideia o que aquela branch vai corrigir ou modificar.

1800874391_Screenshotfrom2021-04-1018-28-11.png.5c6cfd7807c6a5b8eacfb4d330688943.png

 

Agora podemos realizar a mudança desejada. Após realizar a mudança, vamos abrir a aba "commit" que fica do lado esquerdo. Nessa janela  podemos selecionar quais os arquivos que fazem parte da mudança, para enviar a modificação para o repositório.

Após selecionar os arquivos necessários, preenchemos a mensagem do commit com uma algo que descreva o que está sendo mudado. O ideal é que se utilize poucas palavras para descrever a mudança.

Em casos em que é necessário algo mais detalhado, escreva na primeira uma descrição breve, e após uma linha escreva a descrição completa.

Agora podemos fazer o commit e o push das mudanças.

Commit -> realiza a mudança no seu repositório local

Push -> envia a mudança para o respositório remoto ( github)

2053807983_Screenshotfrom2021-04-1018-32-30.thumb.png.81ada6149a33e4bf577e4a8049ed9a04.png

 

Abrirar uma tela para alterar alguma opção do push, se necessário. Aqui podemos ver que será criada uma nova branch no repositório remoto, sinalizado pelo label "new" após o nome da branch. Após verificar que está tudo correto, clique no "push".

*Lembrando que o remote origin é o repositório fork, então a mudança vai para esse repositório e não para o oficial.

585174907_Screenshotfrom2021-04-1018-33-33.thumb.png.9e4cf240e73423c19670d7fac3d636c5.png

 

Após o push, vamos olhar como ficou o repositório no github. 

Podemos ver que ao entrar no github ele já nos mostra que foi realizado um push recentemente no repositório. E finalmente fornece um botão para realizarmos o pull request.

1454279744_Screenshotfrom2021-04-1018-38-03.thumb.png.967fcd0a2b63b0c2e1c30eaa7b2b0de0.png

 

Clique no botão "compare & pull request".

O github abrirá a página de pull request do repositório oficial, automaticamente preencherar algumas informações com a mensagem que colocamos no commit.

Nessa página, podemos configurar para qual branch o pull request será feito. Por padrão ele fará o pull request na branch "development", caso o pull request seja para outra branch você pode alterá-la.

2139080951_Screenshotfrom2021-04-1018-42-33.thumb.png.5a0996e4d61f7d4fbaafe7c458b0ed4c.png

 

 

Clique no botão "Create pull request". Ao criar o pull request a mudança vai passar por algumas checagens automáticas, e ficará aberto para alguém da equipe analisar o que foi mudado.

Essa é fase que chamamos de code review, aqui fazemos uma verificação geral da mudança.

Algumas das coisas que verificamos aqui:

  • A qualidade do código;
  • Se a mudança faz sentido;
  • Se a mudança é necessária;
  • Se o código faz o que supostamente deveria fazer;
  • Se não existe código malicioso;
  • entre outras coisas;

2083348948_Screenshotfrom2021-04-1018-47-11.thumb.png.7ee5bc2e2a04d11d73eafd477830da77.png

 

Alguma pessoa do time irá realizar o review do código, podendo aprovar, pedir mudanças ou apenas não aceitar o pull request

1923958431_Screenshotfrom2021-04-1018-54-07.thumb.png.c7772544ab0c7dd5fa74e420322a06df.png

 

5º Passo - Atualizando o repositório com o conteúdo do repositório oficial

Após o pull request ser aceito, ele é incorporado ao repositório oficial. Então é necessário que o repositório fork e o local seja sempre atualizado também. 

Para isso, vamos voltar ao IntelliJ. A primeira coisa a fazer é retornar para nossa branch padrão "development". Vamos fazer o checkout dela.

1060789626_Screenshotfrom2021-04-1019-01-15.thumb.png.c7c1d852b12eabf7a5863a0d9b7300db.png

 

Agora vamos fazer o pull (copiar) das alterações realizados no repositório oficial. Você pode clicar com o botão direito em algum arquivo do projeto -> Git -> Pull...

 

1140346783_Screenshotfrom2021-04-1019-02-33.thumb.png.9b16e174d00a85d8fdf3dc1ec36b7e5b.png

 

Vamos configurar de onde queremos receber as atualizações, nesse caso queremos atualizar a nossa branch com o repositório oficial e branch development, que foi a que submetemos o pull request.

1953352083_Screenshotfrom2021-04-1019-02-59.thumb.png.64139b83b645c56253d8cd26d8ab238a.png

 

Podemos ver que nossa branch local está atualizada com a mudança que fizemos no pull request:

1902614028_Screenshotfrom2021-04-1019-07-02.thumb.png.d97b6ab43d05170e9b62822fba841035.png

 

Após realizar o pull dessas alterações, você pode fazer push para o seu repositório fork, para mantê-lo sempre atualizado.

 

Esse processo pode parecer um pouco complicado, ou até mesmo com vários passos. Mas é uma forma de coloboração bastante eficaz que permite a fácil utilização de múltiplos repositórios, sem muitas complicações de merge. Mas isso já é uma outra história.

O importante é sempre lembrar:

  • Antes de fazer qualquer mudança crie uma nova branch sempre a partir da branch padrão, nesse caso "development"
  • Se seu pull request não foi aprovado ainda, e você precisa fazer uma alteração diferente, volte para branch padrão, crie uma nova branch apartir dela e só então comece a realizar a próxima mudança
  • Lembre-se de manter seu repositório sempre atualizado com o oficial
  • De vez em quando faça uma limpeza, delete as branchs que foram criadas e as mudanças já foram aprovadas. Lembre-se o modelo é "short lived branch" então elas tem vida curta mesmo.

[]'s

 

 

 

Editado por KhayrusS
Link para o comentário
Compartilhar em outros sites


Irmão do ceu eu curto de mais seus trampo. seus topicos então e inpecavel.

cara tudo que voce souber sobre essa engine ai IDE pode postar por favor eu amo comer conhecimento. Tou preso la traz no Eclipes mais uso o mais atual e essa Engine deixa as coisa escritas muito mais simples e besta qual quer bobo consegue. pelo fato de linguagem de maquina fico facil de mais ai Nessa IDE. 

solta um Spoler dos Atalhos mais usados. pelo Veterano....
 

Editado por BAN - L2JDev
Link para o comentário
Compartilhar em outros sites

7 horas atrás, BAN - L2JDev disse:

Irmão do ceu eu curto de mais seus trampo. seus topicos então e inpecavel.

cara tudo que voce souber sobre essa engine ai IDE pode postar por favor eu amo comer conhecimento. Tou preso la traz no Eclipes mais uso o mais atual e essa Engine deixa as coisa escritas muito mais simples e besta qual quer bobo consegue. pelo fato de linguagem de maquina fico facil de mais ai Nessa IDE. 

solta um Spoler dos Atalhos mais usados. pelo Veterano....
 

Quando sair do Eclipse para um intellij da vida, nunca mais tu volta para o eclipse xD

600-150RETURN.png

Link para o comentário
Compartilhar em outros sites

  • 3 weeks later...
Em 11/04/2021 at 07:27, BAN - L2JDev disse:

Irmão do ceu eu curto de mais seus trampo. seus topicos então e inpecavel.

cara tudo que voce souber sobre essa engine ai IDE pode postar por favor eu amo comer conhecimento. Tou preso la traz no Eclipes mais uso o mais atual e essa Engine deixa as coisa escritas muito mais simples e besta qual quer bobo consegue. pelo fato de linguagem de maquina fico facil de mais ai Nessa IDE. 

solta um Spoler dos Atalhos mais usados. pelo Veterano....
 

Ultimamente meu tempo é tão curto que é difícil produzir algum tipo de conteúdo. Vou ver se consigo algum tempo pra fazer algo desse tipo.

Uma dica que posso dar, para facilitar a migração do eclipse para IDEA, é que você pode configurá-lo para utilizar os mesmo atalhos do eclipse. Ainda vai ter algumas dificuldades, mas já é uma ajuda para ir se acostumando.

Link para o comentário
Compartilhar em outros sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Visitante
Responder

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

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Processando...
  • Registre-se

    Faça parte da maior e  mais antigas comunidades sobre Lineage2 da América Latina.





  • Patrocinadores

  • Quem Está Navegando

    • Nenhum usuário registrado visualizando esta página.
  • Conteúdo Similar

  • Posts

    • Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?     Teria como fazer do dusk shield e do zombie shield dessa maneira?    
    • muchas gracias muy lindos NPC 🙂
    • relaxa jovem gafanhoto, testa as quests. e posTa os erros indesejaveis.  
    • Se alguém pudesse me ensinar como codificar as missões, eu ficaria feliz em fazer isso sozinho ou pelo menos ajudar. Eu realmente quero jogar em um servidor onde todas as quests funcionem bem e melhor ainda se você puder fazer quests customizadas!
    • mas no interlude, nem todas as quests de class,  vai mostrar onde tem que ir, ate o reborn nao mostrava quando era interlude, só mostrou depois que eles colocaram client classic pra rodar, e ficou melhor ainda quando virou hellbound em diante, mas ha sim alguma chance de modificar isso direto no script para fazer igualmente, só basta te um pouco de paciencia e persistencia exato
    • 408_PathToElvenwizard dá Orion eu tive que mexer tbm, até modifiquei e consegui deixar ela igual do Classic, com a seta e a marcação no mapa. (não retail IL) Dá pra importar py de várias revs, o foda é que não da regular as quest py através do debug em tempo real, pelo menos eu não consegui rsrs
    • Hasta el momento todas las QUESTS son completables si te guias con un tutorial de youtube. El problema es que tienen bugs de locacion y de subquests que no avanzan o no te marcan correctamente a donde ir en el mapa, cosa que en Retail si se ve como corresponde.
    • estranho, mas pelo menos a galera nunca reclamo das quests quando tinha aberto 5x, geral fez class primeira e segunda job, poucos que compraram a class
    • en RUSaCis-3.5 data pack, las Quests estan en formato .java y son diferentes a como estan redactadas en jOrion y jFrozen 1.5 (ProyectX) package net.sf.l2j.gameserver.scripting.quest; import net.sf.l2j.commons.random.Rnd; import net.sf.l2j.gameserver.enums.Paperdoll; import net.sf.l2j.gameserver.enums.QuestStatus; import net.sf.l2j.gameserver.enums.actors.ClassId; import net.sf.l2j.gameserver.model.actor.Creature; import net.sf.l2j.gameserver.model.actor.Npc; import net.sf.l2j.gameserver.model.actor.Player; import net.sf.l2j.gameserver.network.serverpackets.SocialAction; import net.sf.l2j.gameserver.scripting.QuestState; public class Q224_TestOfSagittarius extends SecondClassQuest { private static final String QUEST_NAME = "Q224_TestOfSagittarius"; // Items private static final int BERNARD_INTRODUCTION = 3294; private static final int HAMIL_LETTER_1 = 3295; private static final int HAMIL_LETTER_2 = 3296; private static final int HAMIL_LETTER_3 = 3297; private static final int HUNTER_RUNE_1 = 3298; private static final int HUNTER_RUNE_2 = 3299; private static final int TALISMAN_OF_KADESH = 3300; private static final int TALISMAN_OF_SNAKE = 3301; private static final int MITHRIL_CLIP = 3302; private static final int STAKATO_CHITIN = 3303; private static final int REINFORCED_BOWSTRING = 3304; private static final int MANASHEN_HORN = 3305; private static final int BLOOD_OF_LIZARDMAN = 3306; private static final int CRESCENT_MOON_BOW = 3028; private static final int WOODEN_ARROW = 17; // Rewards private static final int MARK_OF_SAGITTARIUS = 3293; // NPCs private static final int BERNARD = 30702; private static final int HAMIL = 30626; private static final int SIR_ARON_TANFORD = 30653; private static final int VOKIAN = 30514; private static final int GAUEN = 30717; // Monsters private static final int ANT = 20079; private static final int ANT_CAPTAIN = 20080; private static final int ANT_OVERSEER = 20081; private static final int ANT_RECRUIT = 20082; private static final int ANT_PATROL = 20084; private static final int ANT_GUARD = 20086; private static final int NOBLE_ANT = 20089; private static final int NOBLE_ANT_LEADER = 20090; private static final int BREKA_ORC_SHAMAN = 20269; private static final int BREKA_ORC_OVERLORD = 20270; private static final int MARSH_STAKATO_WORKER = 20230; private static final int MARSH_STAKATO_SOLDIER = 20232; private static final int MARSH_STAKATO_DRONE = 20234; private static final int MARSH_SPIDER = 20233; private static final int ROAD_SCAVENGER = 20551; private static final int MANASHEN_GARGOYLE = 20563; private static final int LETO_LIZARDMAN = 20577; private static final int LETO_LIZARDMAN_ARCHER = 20578; private static final int LETO_LIZARDMAN_SOLDIER = 20579; private static final int LETO_LIZARDMAN_WARRIOR = 20580; private static final int LETO_LIZARDMAN_SHAMAN = 20581; private static final int LETO_LIZARDMAN_OVERLORD = 20582; private static final int SERPENT_DEMON_KADESH = 27090; public Q224_TestOfSagittarius() { super(224, "Test Of Sagittarius"); setItemsIds(BERNARD_INTRODUCTION, HAMIL_LETTER_1, HAMIL_LETTER_2, HAMIL_LETTER_3, HUNTER_RUNE_1, HUNTER_RUNE_2, TALISMAN_OF_KADESH, TALISMAN_OF_SNAKE, MITHRIL_CLIP, STAKATO_CHITIN, REINFORCED_BOWSTRING, MANASHEN_HORN, BLOOD_OF_LIZARDMAN, CRESCENT_MOON_BOW); addQuestStart(BERNARD); addTalkId(BERNARD, HAMIL, SIR_ARON_TANFORD, VOKIAN, GAUEN); addMyDying(ANT, ANT_CAPTAIN, ANT_OVERSEER, ANT_RECRUIT, ANT_PATROL, ANT_GUARD, NOBLE_ANT, NOBLE_ANT_LEADER, BREKA_ORC_SHAMAN, BREKA_ORC_OVERLORD, MARSH_STAKATO_WORKER, MARSH_STAKATO_SOLDIER, MARSH_STAKATO_DRONE, MARSH_SPIDER, ROAD_SCAVENGER, MANASHEN_GARGOYLE, LETO_LIZARDMAN, LETO_LIZARDMAN_ARCHER, LETO_LIZARDMAN_SOLDIER, LETO_LIZARDMAN_WARRIOR, LETO_LIZARDMAN_SHAMAN, LETO_LIZARDMAN_OVERLORD, SERPENT_DEMON_KADESH); } @Override public String onAdvEvent(String event, Npc npc, Player player) { String htmltext = event; QuestState st = player.getQuestList().getQuestState(QUEST_NAME); if (st == null) return htmltext; // BERNARD if (event.equalsIgnoreCase("30702-04.htm")) { st.setState(QuestStatus.STARTED); st.setCond(1); playSound(player, SOUND_ACCEPT); giveItems(player, BERNARD_INTRODUCTION, 1); if (giveDimensionalDiamonds39(player)) htmltext = "30702-04a.htm"; } // HAMIL else if (event.equalsIgnoreCase("30626-03.htm")) { st.setCond(2); playSound(player, SOUND_MIDDLE); takeItems(player, BERNARD_INTRODUCTION, 1); giveItems(player, HAMIL_LETTER_1, 1); } else if (event.equalsIgnoreCase("30626-07.htm")) { st.setCond(5); playSound(player, SOUND_MIDDLE); takeItems(player, HUNTER_RUNE_1, 10); giveItems(player, HAMIL_LETTER_2, 1); } // SIR_ARON_TANFORD else if (event.equalsIgnoreCase("30653-02.htm")) { st.setCond(3); playSound(player, SOUND_MIDDLE); takeItems(player, HAMIL_LETTER_1, 1); } // VOKIAN else if (event.equalsIgnoreCase("30514-02.htm")) { st.setCond(6); playSound(player, SOUND_MIDDLE); takeItems(player, HAMIL_LETTER_2, 1); } return htmltext; } @Override public String onTalk(Npc npc, Player player) { String htmltext = getNoQuestMsg(); QuestState st = player.getQuestList().getQuestState(QUEST_NAME); if (st == null) return htmltext; switch (st.getState()) { case CREATED: if (player.getClassId() != ClassId.ROGUE && player.getClassId() != ClassId.ELVEN_SCOUT && player.getClassId() != ClassId.ASSASSIN) htmltext = "30702-02.htm"; else if (player.getStatus().getLevel() < 39) htmltext = "30702-01.htm"; else htmltext = "30702-03.htm"; break; case STARTED: int cond = st.getCond(); switch (npc.getNpcId()) { case BERNARD: htmltext = "30702-05.htm"; break; case HAMIL: if (cond == 1) htmltext = "30626-01.htm"; else if (cond == 2 || cond == 3) htmltext = "30626-04.htm"; else if (cond == 4) htmltext = "30626-05.htm"; else if (cond > 4 && cond < 8) htmltext = "30626-08.htm"; else if (cond == 8) { htmltext = "30626-09.htm"; st.setCond(9); playSound(player, SOUND_MIDDLE); takeItems(player, HUNTER_RUNE_2, 10); giveItems(player, HAMIL_LETTER_3, 1); } else if (cond > 8 && cond < 12) htmltext = "30626-10.htm"; else if (cond == 12) { htmltext = "30626-11.htm"; st.setCond(13); playSound(player, SOUND_MIDDLE); } else if (cond == 13) htmltext = "30626-12.htm"; else if (cond == 14) { htmltext = "30626-13.htm"; takeItems(player, BLOOD_OF_LIZARDMAN, -1); takeItems(player, CRESCENT_MOON_BOW, 1); takeItems(player, TALISMAN_OF_KADESH, 1); giveItems(player, MARK_OF_SAGITTARIUS, 1); rewardExpAndSp(player, 54726, 20250); player.broadcastPacket(new SocialAction(player, 3)); playSound(player, SOUND_FINISH); st.exitQuest(false); } break; case SIR_ARON_TANFORD: if (cond == 2) htmltext = "30653-01.htm"; else if (cond > 2) htmltext = "30653-03.htm"; break; case VOKIAN: if (cond == 5) htmltext = "30514-01.htm"; else if (cond == 6) htmltext = "30514-03.htm"; else if (cond == 7) { htmltext = "30514-04.htm"; st.setCond(8); playSound(player, SOUND_MIDDLE); takeItems(player, TALISMAN_OF_SNAKE, 1); } else if (cond > 7) htmltext = "30514-05.htm"; break; case GAUEN: if (cond == 9) { htmltext = "30717-01.htm"; st.setCond(10); playSound(player, SOUND_MIDDLE); takeItems(player, HAMIL_LETTER_3, 1); } else if (cond == 10) htmltext = "30717-03.htm"; else if (cond == 11) { htmltext = "30717-02.htm"; st.setCond(12); playSound(player, SOUND_MIDDLE); takeItems(player, MANASHEN_HORN, 1); takeItems(player, MITHRIL_CLIP, 1); takeItems(player, REINFORCED_BOWSTRING, 1); takeItems(player, STAKATO_CHITIN, 1); giveItems(player, CRESCENT_MOON_BOW, 1); giveItems(player, WOODEN_ARROW, 10); } else if (cond > 11) htmltext = "30717-04.htm"; break; } break; case COMPLETED: htmltext = getAlreadyCompletedMsg(); break; } return htmltext; } @Override public void onMyDying(Npc npc, Creature killer) { final Player player = killer.getActingPlayer(); final QuestState st = checkPlayerState(player, npc, QuestStatus.STARTED); if (st == null) return; switch (npc.getNpcId()) { case ANT: case ANT_CAPTAIN: case ANT_OVERSEER: case ANT_RECRUIT: case ANT_PATROL: case ANT_GUARD: case NOBLE_ANT: case NOBLE_ANT_LEADER: if (st.getCond() == 3 && dropItems(player, HUNTER_RUNE_1, 1, 10, 500000)) st.setCond(4); break; case BREKA_ORC_SHAMAN: case BREKA_ORC_OVERLORD: if (st.getCond() == 6 && dropItems(player, HUNTER_RUNE_2, 1, 10, 500000)) { st.setCond(7); giveItems(player, TALISMAN_OF_SNAKE, 1); } break; case MARSH_STAKATO_WORKER: case MARSH_STAKATO_SOLDIER: case MARSH_STAKATO_DRONE: if (st.getCond() == 10 && dropItems(player, STAKATO_CHITIN, 1, 1, 100000) && player.getInventory().hasItems(MANASHEN_HORN, MITHRIL_CLIP, REINFORCED_BOWSTRING)) st.setCond(11); break; case MARSH_SPIDER: if (st.getCond() == 10 && dropItems(player, REINFORCED_BOWSTRING, 1, 1, 100000) && player.getInventory().hasItems(MANASHEN_HORN, MITHRIL_CLIP, STAKATO_CHITIN)) st.setCond(11); break; case ROAD_SCAVENGER: if (st.getCond() == 10 && dropItems(player, MITHRIL_CLIP, 1, 1, 100000) && player.getInventory().hasItems(MANASHEN_HORN, REINFORCED_BOWSTRING, STAKATO_CHITIN)) st.setCond(11); break; case MANASHEN_GARGOYLE: if (st.getCond() == 10 && dropItems(player, MANASHEN_HORN, 1, 1, 100000) && player.getInventory().hasItems(REINFORCED_BOWSTRING, MITHRIL_CLIP, STAKATO_CHITIN)) st.setCond(11); break; case LETO_LIZARDMAN: case LETO_LIZARDMAN_ARCHER: case LETO_LIZARDMAN_SOLDIER: case LETO_LIZARDMAN_WARRIOR: case LETO_LIZARDMAN_SHAMAN: case LETO_LIZARDMAN_OVERLORD: if (st.getCond() == 13) { if (((player.getInventory().getItemCount(BLOOD_OF_LIZARDMAN) - 120) * 5) > Rnd.get(100)) { playSound(player, SOUND_BEFORE_BATTLE); takeItems(player, BLOOD_OF_LIZARDMAN, -1); addSpawn(SERPENT_DEMON_KADESH, player, false, 300000, true); } else dropItemsAlways(player, BLOOD_OF_LIZARDMAN, 1, 0); } break; case SERPENT_DEMON_KADESH: if (st.getCond() == 13) { if (player.getInventory().getItemIdFrom(Paperdoll.RHAND) == CRESCENT_MOON_BOW) { st.setCond(14); playSound(player, SOUND_MIDDLE); giveItems(player, TALISMAN_OF_KADESH, 1); } else addSpawn(SERPENT_DEMON_KADESH, player, false, 300000, true); } break; } } }  
×
×
  • Criar Novo...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.