ZURSULUS L2

Saga of the Shillien Templar

ID
97
Название
Saga of the Shillien Templar
start_npcs_json
[]
npc_ids_json
[]
constants_json
{}
Статус разбора
metadata_only; dynamic Java conditions/rewards retained in source; unresolved starts: []
Источник
game/data/scripts/quests/Q00097_SagaOfTheShillienTemplar/Q00097_SagaOfTheShillienTemplar.java

NPC квеста

Записей нет.

Условия уровней: выражения из Java

if (player.getLevel() < 76)
if (player.getLevel() < 76)
if (player.getLevel() >= 76)

Выдача предметов, адены и опыта: выражения из Java

giveItems(player, _items[10], 1);
addExpAndSp(player, 2299404, 0);
giveAdena(player, 5000000, true);
giveItems(player, 6622, 1);
giveItems(player, _items[1], 1);
giveItems(player, _items[4], 1);
giveItems(player, _items[7], 1);
giveItems(player, _items[9], 1);
giveItems(player, _items[9], 1);
giveItems(player, _items[8], 1);
giveItems(player, _items[5], 1);
giveItems(player, _items[6], 1);
giveItems(player, _items[8], 1);
addExpAndSp(player, 2299404, 0);
giveAdena(player, 5000000, true);
giveItems(player, 6622, 1); // XXX rewardItems?
giveItems(player, _items[3], getRandom(1, 4));

Квесты содержат динамические условия Java. Выражения выдачи включают промежуточные предметы, варианты и случайные награды; это не гарантированная награда. Константы приведены выше. Полные условия — в исходнике.

Тексты квеста

[0-01.htm] Master Galadrid: So you've been chosen? Are you up to it? We're stretched to our limits, but I have a plan. "What is it?" [0-010.htm] Master Galadrid: You've already approached a higher level of knowledge than the other knights, but your ability hasn't reached the level of knowledge. Therefore, I can't give the title of Shillien Templar to you yet. Come back again after growing your ability more. (Only a character of level 76 or above can become a Shillien Templar. Be careful. You cannot change occupation if you stop Quest!) [0-02.htm] Master Galadrid: Keep honing your skills for a while. (This quest may only be undertaken by a Shillien Knight of level 76 or above.) [0-03.htm] Master Galadrid: Meet with Samael of Goddard Castle Town to find out what to do next. You should know that nobody has succeeded in this mission before. Beware, Shiken may try to stop you! Oh, I have a letter for you. [0-04.htm] Master Galadrid: You must complete this mission before you move on. Meet with Samael of Goddard Castle Town! [0-05.htm] Master Galadrid: Samael of Goddard Castle Town has deciphered the ancient text on the relic. Will you conduct an investigation based on his translation? "Yes!" [0-06.htm] Master Galadrid: You uncovered the secrets of the ancient relic! What did Shiken have to say? "He wanted to fight." [0-07.htm] Master Galadrid: That sounds like Shiken, alright! You've proven yourself a worthy Knight. I bestow upon you the title of Shillien Templar! [0-08.htm] Master Galadrid: Then, if so, there's nothing I can say to you. You've already approached a higher level of knowledge than the other knights. However, your ability hasn't reached the level of knowledge. Therefore, I can't give the title of Shillien Templar to you yet. Come back again after growing your ability more. (Only a character of level 76 or above can become a Shillien Templar. Be careful. You cannot change occupation if you stop Quest!) [0-09.htm] Master Galadrid: Your abilities finally match your understanding. I bestow upon you the title of Shillien Templar! [1-01.htm] Information Broker Bavarin: What brings you here? I'm on break! My neuralgia has flared up lately. Unless it's very important, please leave me alone! "I need to borrow your Ancient Language Dictionary." [1-02.htm] Information Broker Bavarin: I have the dictionary, but, as I said, you must bring me an ice crystal before you can have it. Now go see Jeremy. [1-03.htm] Information Broker Bavarin: Have you brought me an ice crystal? Give it to me! Hurry, before the pain comes back! Oh, I guess you want the dictionary, eh? "You can't have the ice crystal until you give me the dictionary." [1-04.htm] Information Broker Bavarin: Didn't I already give it to you? You have no more business here! Please, let me rest! Why don't you take the dictionary to Elena? [1-05.htm] Information Broker Bavarin: Ancient Language Dictionary? Why do you want that old book? It won't be helpful to you at all! Samael wants to borrow it? Hmm. What a pain! Very well, I'll get it. But you need to do something for me, first! Bring me an ice crystal to soothe my neuralgia. Jeremy knows to find them. Please bring one to me. [1-06.htm] Information Broker Bavarin: Ha! You've had a rough life, eh? Well, here's the dictionary. Now, give me the ice crystal. Aaah... yes! I feel better already! Our business is over. Please tell Samael that I'll pick up the dictionary later. [10-01.htm] Tablet of Vision: The tablet is slightly vibrating. Someone with the Stone of Commune must be nearby. Examine the area carefully. [10-02.htm] Tablet of Vision: Someone approaches threateningly from the distant corner. Could it be...? [10-03.htm] Tablet of Vision: Further communion with this tablet would be pointless at this time. Get the Stone of Commune from Shiken! [10-04.htm] Tablet of Vision: There's a disturbance nearby. Don't get involved. Wait and see what happens. [10-05.htm] Tablet of Vision: The tablet responds as you draw near with the Stone of Commune. Touch the tablet with the Stone of Commune. [10-06.htm] Tablet of Vision: This time, the flood of knowledge was painless! Now I understand why the power was kept from us! I've received some amazing knowledge! [10-07.htm] Tablet of Vision: The tablet goes still and dark as if nothing had happened. The communion is complete. Return to Galadrid. [11-01.htm] Grand Master Samael: Welcome! How is your work going? Hmm, a different reaction this time, eh? Something seemed to be inhibiting the reaction. Wait a moment. Ah yes, here is the method of getting the next Stone of Commune and the location of the next tablet. "Quick, tell me!" [11-02.htm] Grand Master Samael: The Archon of Halisha has the next Stone of Commune. You can find the Archon inside the Four Sepulchers in the Imperial Tomb. You mustn't enter that dreadful place alone! If you're unable to form a party for some reason, massacre the Archon's minions in the Shrine of the Loyal. Kill enough of them, say around 700, and he will appear. His minions are called Grave Scarabs, Scavenger Scarabs, Grave Ants, Scavenger Ants, Shrine Knights and Shrine Guards. The Tablet of Vision that you seek can be found on the road to Goddard from the Wall of Argos. [11-03.htm] Grand Master Samael: Don't be so hasty! If you look carefully at the inscriptions on the relics, you'll discover how to find the Stone of Commune. The Archon of Halisha has the next Stone of Commune. You can find the Archon inside the Four Sepulchers in the Imperial Tomb. You mustn't enter that dreadful place alone! If you're unable to form a party for some reason, massacre the Archon's minions in the Shrine of the Loyal. Kill enough of them, say around 700, and he will appear. His minions are called Grave Scarabs, Scavenger Scarabs, Grave Ants, Scavenger Ants, Shrine Knights and Shrine Guards. The Tablet of Vision that you seek can be found on the road to Goddard from the Wall of Argos. [2-01.htm] Grand Master Samael: Why are you here? Galadrid told you to come, didn't he? You're here for that thing, aren't you?! But, there's a problem. I can't decipher some of the passages because there are some odd characters in the middle. "How can I help?" [2-02.htm] Grand Master Samael: You haven't meet Bavarin yet? I need the "Ancient Language Dictionary" to decipher the passages! [2-03.htm] Grand Master Samael: Did you get the dictionary? Wait a minute... Here! I've deciphered part of the text! I can't read everything yet, but there's something you can do. The text says that you can obtain the ancient knowledge if you take this Stone of Commune to the Tablet of Vision. Please, go there immediately! "Is there anything else?" [2-04.htm] Grand Master Samael: You haven't forgotten your task, have you? Find the Tablet of Vision south of the Tower of Insolence. [2-05.htm] Grand Master Samael: First you must help me decipher the text on this ancient object. I must have the "Ancient Language Dictionary"! I've heard that Bavarin has it, and he's coming to the hot springs for a vacation! Will you go see him and borrow the dictionary for me? [2-06.htm] Grand Master Samael: Now you must go to the Tablet of Vision and attain the knowledge by using the Stone of Commune. This Stone of Commune is the only way to get the information, so you must be very careful with it! The Tablet of Vision is south of the Tower of Insolence. Hurry there! [3-01.htm] Grand Master Samael: Welcome back! Tell me, what have you learned? The forbidden knowledge is truly passed on to the one who holds the Stone of Commune. Good job! But, why did you come back? The Stone of Commune? You mean this? Actually, there were several fragments attached to the tablet. I gave you the analyzed one. This may be the one that you're looking for now. Unfortunately, it's incomplete. You must find another fragment! In fact, I know where the fragment is, but haven't been able to get it yet, as it will be quite difficult. Will you get it for me? "What do I need to do?" [3-02.htm] Grand Master Samael: You must gain the trust of the Ketra Orcs. Gain the trust of their messenger, Wahkan. He's their highest ranking chieftain, and will give you their Divine Stone of Wisdom. If you have a bad time with the Ketras, you can go to the Varka Silenos and get their stone instead. [3-03.htm] Grand Master Samael: First, you must gain the trust of Naran Ashanuk, the messenger of the Varka Silenos. Eventually, you can get their Divine Stone of Wisdom from Soul Guide Udan Mardui, their highest-ranking shaman. If you have a bad time with the Varkas, you can go to the Ketra Orcs and get their stone instead. [3-04.htm] Grand Master Samael: You know what to do, don't you? Go to the Varka Silenos or Ketra Orcs and bring me a Divine Stone of Wisdom. Go to Ketra's Messenger Wahkan or Varka's Messenger Naran Ashanuk. [3-05.htm] Grand Master Samael: Did you bring the Divine Stone of Wisdom? Even though it's quite difficult to gain the trust of their highest-ranking shaman, you made it look very easy! Can I have the stone? "Here it is." [3-06.htm] Grand Master Samael: What are you doing? You must finish your job! Find the Tablet of Vision immediately! You can find it north of the Varka Silenos barracks. [3-07.htm] Grand Master Samael: I need the Divine Stone of Wisdom that's held by Asefa, the highest-ranking shaman of the Ketra Orcs, or Soul Guide Udan Mardui, the highest-ranking shaman of the Varka Silenos. You must gain the trust of the highest-ranking shaman of either tribe in order to get the stone. Which tribe do you wish to approach? "I'll approach the Ketra Orcs." "I'll approach the Varka Silenos." [3-08.htm] Grand Master Samael: Wait a minute. Here is the Stone of Commune that you need. Let me know if you have any problems with it. You know where the tablet is, right? It's north of the Varka Silenos barracks. I marked it on your Map. You must be very careful! You never know what kind of danger awaits you around the next corner! [4-01.htm] Shiken Gloomdrake: That wretch is aiming for you! Don't just stand there, fight! [4-010.htm] Shiken Gloomdrake: This is the Stone of Commune you came all this way for. I'll give you a free tip. Don't rely on Galadrid too much, but don't fear him either. A Shillien Knight should know what to do. Maybe we'll meet again. Such a baby. "Wait!" [4-011.htm] Shikken Gloomdrake: Nothing is worse than forgetting your special purpose. Take the Stone of Commune, you've come this far for it. [4-02.htm] Shiken Gloomdrake: This isn't your fight! Stand back! [4-03.htm] Shiken Gloomdrake: You're not strong enough to fight me, so stand back. Normally assassins don't run so easily. Don't worry, you'll get your turn. [4-04.htm] Shiken Gloomdrake: Go dig your grave if you want a rest. Now it's time to fight! [4-05.htm] Shiken Gloomdrake: Scram! This is my fight, not yours. [4-06.htm] Shiken Gloomdrake: Who would bestow the title of Shillien Knight on someone so careless? Letting an assassin get so close! You couldn't beat a golem without my help. Galadrid would be upset. "Are you trying to pick a fight?" [4-07.htm] Shiken Gloomdrake: A blind girl falls in love with a silly wizard and flees, and what's more, there's a clumsy assassin and a Shillien Knight who doesn't know his mission! Who needs a comedy club! "What's that you have there?" [4-08.htm] Shiken Gloomdrake: Shame, shame. They call you an assassin? Hey you, commune with the tablet already! [4-09.htm] Shiken Gloomdrake: What do you think the Stone of Commune is for? The Tablet of Vision that's right under your nose! Get it? [5-01.htm] Tablet of Vision: A rough tablet appears before you. It emits a faint hum similar to the Stone of Commune as you approach. Touch the Stone of Commune to the Tablet of Vision. [5-02.htm] Tablet of Vision: Countless thoughts beyond comprehension sear painfully into your brain. You suddenly realize that this isn't the only Stone of Commune nor Tablet of Vision, and the knowledge contained within these tablets could change the world! As the pain subsides, a strange vision appears before you. A creature with four white wings, flying above the Valley of Saints, carrying the Stone of Commune! In a moment, the vision fades... The tablet goes still and dark, as if nothing had happened. Go to the south of the Valley of Saints and find the Tablet of Vision! [5-03.htm] Tablet of Vision: The tablet goes still and dark, as if nothing had happened. Go to the south of the Valley of Saints and find the next Stone of Commune! [6-01.htm] Tablet of Vision: You must have the Stone of Commune to access the Tablet of Vision. The Stone of Commune is held by a creature with four wings. [6-02.htm] Tablet of Vision: The tablet begins to tremble and emit a faint light as the Stone of Commune draws near. Touch the Tablet of Vision with the Stone of Commune. [6-03.htm] Tablet of Vision: Suddenly, huge amounts of knowledge are painfully seared into your brain. The cascade of brief images is unintelligible atfirst... But then, the next tablet comes into view! It looks to be located in the area northeast of the Ketra Orc Outpost! It's surrounded by golems! One of those filthy creatures has the Stone of Commune! And then the vision fades... The tablet goes still and dark, as if nothing had happened. Now go to the northeast of the Ketra Orc Outpost and get the Stone of Commune. [6-04.htm] Tablet of Vision: Communing further with this tablet would be futile. Go to the northeast of the Ketra Orc Outpost and get the Stone of Commune. [7-01.htm] Tablet of Vision: The tablet begins to shake slightly. Someone or something nearby has the Stone of Commune! Examine the area carefully. [7-02.htm] Tablet of Vision: A huge golem appears! He's the one that was featured in the guild bulletin I got from Galadrid! I must be very careful! [7-03.htm] Tablet of Vision: You must get the Stone of Commune from that golem! [7-04.htm] Tablet of Vision: There's fight going on over there. Let's wait here for a moment until the fighting finishes. [7-05.htm] Tablet of Vision: The tablet begins to buzz as the Stone of Commune draws near. Touch the Stone of Commune to the Tablet of Vision. [7-06.htm] Tablet of Vision: Countless thoughts beyond comprehension sear painfully into your brain. The secrets of the tablet start to be revealed. As the pain subsides, a vision appears... It's Samael! And then the vision fades... Find Samael! He has the Stone of Commune! [7-07.htm] Tablet of Vision: The tablet goes still and quiet, as if nothing had ever happened. Find Samael and get the Stone of Commune from him. [8-01.htm] Tablet of Vision: You feel the tablet resonate with the Stone of Commune. Touch the Stone of Commune to the Tablet of Vision. [8-02.htm] Tablet of Vision: Thoughts beyond understanding are seared painfully into your brain. After the pain subsides and the communion is finished, you find that you don't know where the next Stone of Commune is. Speak with Samael again. [8-03.htm] Tablet of Vision: The tablet goes still and dark as if nothing had happened. Visit Samael and find out what to do next. [9-01.htm] Tablet of Vision: The tablet is useless without a Stone of Commune. As Samael said, you can get the Stone of Commune from the Archon of Halisha. [9-02.htm] Tablet of Vision: The tablet buzzes as you approach with the Stone of Commune. Touch the Stone of Commune to the tablet. [9-03.htm] Tablet of Vision: Once again, incomprehensible thoughts are painfully seared into your brain. As the pain subsides, a vision appears! There's a tablet much like this one, and it appears to be southeast of Hunters Village. There's a man standing by the tablet holding a Stone of Commune! Find him! [9-04.htm] Tablet of Vision: The tablet goes still and dark as if nothing had happened. The next Stone of Commune is southeast of Hunters Village. Go there!
Исходник условий и наград (Java)
/*
 * This file is part of the L2J Mobius project.
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package quests.Q00097_SagaOfTheShillienTemplar;

import quests.AbstractSagaQuest;

/**
 * Saga of the Shillien Templar (97)
 * @author Emperorc
 */
public class Q00097_SagaOfTheShillienTemplar extends AbstractSagaQuest
{
	public Q00097_SagaOfTheShillienTemplar()
	{
		super(97, "Saga of the Shillien Templar");
		_npc = new int[]
		{
			31580,
			31623,
			31285,
			31285,
			31610,
			31646,
			31648,
			31652,
			31654,
			31655,
			31659,
			31285
		};
		_items = new int[]
		{
			7080,
			7526,
			7081,
			7512,
			7295,
			7326,
			7357,
			7388,
			7419,
			7450,
			7091,
			0
		};
		_mob = new int[]
		{
			27271,
			27246,
			27273
		};
		_classId = new int[]
		{
			106
		};
		_prevClass = new int[]
		{
			0x21
		};
		_x = new int[]
		{
			161719,
			124355,
			124376
		};
		_y = new int[]
		{
			-92823,
			82155,
			82127
		};
		_z = new int[]
		{
			-1893,
			-2803,
			-2796
		};
		_text = new String[]
		{
			"PLAYERNAME! Pursued to here! However, I jumped out of the Banshouren boundaries! You look at the giant as the sign of power!",
			"... Oh ... good! So it was ... let's begin!",
			"I do not have the patience ..! I have been a giant force ...! Cough chatter ah ah ah!",
			"Paying homage to those who disrupt the orderly will be PLAYERNAME's death!",
			"Now, my soul freed from the shackles of the millennium, Halixia, to the back side I come ...",
			"Why do you interfere others' battles?",
			"This is a waste of time.. Say goodbye...!",
			"...That is the enemy",
			"...Goodness! PLAYERNAME you are still looking?",
			"PLAYERNAME ... Not just to whom the victory. Only personnel involved in the fighting are eligible to share in the victory.",
			"Your sword is not an ornament. Don't you think, PLAYERNAME?",
			"Goodness! I no longer sense a battle there now.",
			"let...",
			"Only engaged in the battle to bar their choice. Perhaps you should regret.",
			"The human nation was foolish to try and fight a giant's strength.",
			"Must...Retreat... Too...Strong.",
			"PLAYERNAME. Defeat...by...retaining...and...Mo...Hacker",
			"....! Fight...Defeat...It...Fight...Defeat...It..."
		};
		registerNPCs();
	}
}


// Shared quest dependency: AbstractSagaQuest.java
/*
 * Copyright (c) 2013 L2jMobius
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
package quests;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.l2jmobius.gameserver.config.PlayerConfig;
import org.l2jmobius.gameserver.entity.World;
import org.l2jmobius.gameserver.entity.WorldObject;
import org.l2jmobius.gameserver.entity.actor.Creature;
import org.l2jmobius.gameserver.entity.actor.Npc;
import org.l2jmobius.gameserver.entity.actor.Player;
import org.l2jmobius.gameserver.entity.groups.Party;
import org.l2jmobius.gameserver.mechanics.script.Quest;
import org.l2jmobius.gameserver.mechanics.script.QuestState;
import org.l2jmobius.gameserver.mechanics.skill.Skill;
import org.l2jmobius.gameserver.network.enums.ChatType;
import org.l2jmobius.gameserver.network.serverpackets.MagicSkillUse;
import org.l2jmobius.gameserver.network.serverpackets.NpcSay;

public abstract class AbstractSagaQuest extends Quest
{
	protected int[] _npc = {};
	protected int[] _items = {};
	protected int[] _mob = {};
	protected int[] _classId = {};
	protected int[] _prevClass = {};
	protected int[] _x = {};
	protected int[] _y = {};
	protected int[] _z = {};
	protected String[] _text = {};
	private static final Map<Npc, Integer> SPAWN_LIST = new HashMap<>();
	// @formatter:off
	private static final int[][] QUEST_CLASSES =
	{
		{ 0x7f }, { 0x80, 0x81 }, { 0x82 }, { 0x05 }, { 0x14 }, { 0x15 },
		{ 0x02 }, { 0x03 }, { 0x2e }, { 0x30 }, { 0x33 }, { 0x34 }, { 0x08 },
		{ 0x17 }, { 0x24 }, { 0x09 }, { 0x18 }, { 0x25 }, { 0x10 }, { 0x11 },
		{ 0x1e }, { 0x0c }, { 0x1b }, { 0x28 }, { 0x0e }, { 0x1c }, { 0x29 },
		{ 0x0d }, { 0x06 }, { 0x22 }, { 0x21 }, { 0x2b }, { 0x37 }, { 0x39 }
	};
	// @formatter:on
	private static final int[] ARCHON_HALISHA_NORM =
	{
		18212,
		18214,
		18215,
		18216,
		18218
	};
	
	public AbstractSagaQuest(int questId, String description)
	{
		super(questId, description);
	}
	
	public void registerNPCs()
	{
		addStartNpc(_npc[0]);
		addAttackId(_mob[2]);
		addAttackId(_mob[1]);
		addSkillSeeId(_mob[1]);
		addFirstTalkId(_npc[4]);
		addTalkId(_npc);
		addKillId(_mob);
		final int[] questItemIds = _items.clone();
		questItemIds[0] = 0;
		questItemIds[2] = 0; // remove Ice Crystal and Divine Stone of Wisdom
		registerQuestItems(questItemIds);
		for (int archonMinion = 21646; archonMinion < 21652; archonMinion++)
		{
			addKillId(archonMinion);
		}
		
		addKillId(ARCHON_HALISHA_NORM);
		for (int guardianAngel = 27214; guardianAngel < 27217; guardianAngel++)
		{
			addKillId(guardianAngel);
		}
	}
	
	@Override
	public String onEvent(String event, Npc npc, Player player)
	{
		final QuestState st = getQuestState(player, false);
		if (st == null)
		{
			return null;
		}
		
		String htmltext = null;
		switch (event)
		{
			case "0-011.htm":
			case "0-012.htm":
			case "0-013.htm":
			case "0-014.htm":
			case "0-015.htm":
			{
				htmltext = event;
				break;
			}
			case "accept":
			{
				st.startQuest();
				giveItems(player, _items[10], 1);
				htmltext = "0-03.htm";
				break;
			}
			case "0-1":
			{
				if (player.getLevel() < 76)
				{
					htmltext = "0-02.htm";
					if (st.isCreated())
					{
						st.exitQuest(true);
					}
				}
				else
				{
					htmltext = "0-05.htm";
				}
				break;
			}
			case "0-2":
			{
				if (player.getLevel() < 76)
				{
					takeItems(player, _items[10], -1);
					st.setCond(20, true);
					htmltext = "0-08.htm";
				}
				else
				{
					takeItems(player, _items[10], -1);
					addExpAndSp(player, 2299404, 0);
					giveAdena(player, 5000000, true);
					giveItems(player, 6622, 1);
					final int playerClass = getPlayerClass(player);
					final int prevClass = getPrevClass(player);
					player.setPlayerClass(playerClass);
					if (!player.isSubClassActive() && (player.getBaseClass() == prevClass))
					{
						player.setBaseClass(playerClass);
					}
					
					player.broadcastUserInfo();
					cast(npc, player, 4339, 1);
					st.exitQuest(false);
					htmltext = "0-07.htm";
				}
				break;
			}
			case "1-3":
			{
				st.setCond(3);
				htmltext = "1-05.htm";
				break;
			}
			case "1-4":
			{
				st.setCond(4);
				takeItems(player, _items[0], 1);
				if (_items[11] != 0)
				{
					takeItems(player, _items[11], 1);
				}
				
				giveItems(player, _items[1], 1);
				htmltext = "1-06.htm";
				break;
			}
			case "2-1":
			{
				st.setCond(2);
				htmltext = "2-05.htm";
				break;
			}
			case "2-2":
			{
				st.setCond(5);
				takeItems(player, _items[1], 1);
				giveItems(player, _items[4], 1);
				htmltext = "2-06.htm";
				break;
			}
			case "3-5":
			{
				htmltext = "3-07.htm";
				break;
			}
			case "3-6":
			{
				st.setCond(11);
				htmltext = "3-02.htm";
				break;
			}
			case "3-7":
			{
				st.setCond(12);
				htmltext = "3-03.htm";
				break;
			}
			case "3-8":
			{
				st.setCond(13);
				takeItems(player, _items[2], 1);
				giveItems(player, _items[7], 1);
				htmltext = "3-08.htm";
				break;
			}
			case "4-1":
			{
				htmltext = "4-010.htm";
				break;
			}
			case "4-2":
			{
				giveItems(player, _items[9], 1);
				st.setCond(18, true);
				htmltext = "4-011.htm";
				break;
			}
			case "4-3":
			{
				giveItems(player, _items[9], 1);
				st.setCond(18, true);
				autoChat(npc, _text[13].replace("PLAYERNAME", player.getName()));
				st.set("Quest0", "0");
				cancelQuestTimer("Mob_2 has despawned", npc, player);
				deleteSpawn(npc);
				return null;
			}
			case "5-1":
			{
				st.setCond(6, true);
				takeItems(player, _items[4], 1);
				cast(npc, player, 4546, 1);
				htmltext = "5-02.htm";
				break;
			}
			case "6-1":
			{
				st.setCond(8, true);
				st.set("spawned", "0");
				takeItems(player, _items[5], 1);
				cast(npc, player, 4546, 1);
				htmltext = "6-03.htm";
				break;
			}
			case "7-1":
			{
				if (st.getInt("spawned") == 1)
				{
					htmltext = "7-03.htm";
				}
				else if (st.getInt("spawned") == 0)
				{
					final Npc mob1 = addSpawn(_mob[0], _x[0], _y[0], _z[0], -1);
					st.set("spawned", "1");
					startQuestTimer("Mob_1 Timer 1", 500, mob1, player);
					startQuestTimer("Mob_1 has despawned", 300000, mob1, player);
					addSpawn(st, mob1);
					htmltext = "7-02.htm";
				}
				else
				{
					htmltext = "7-04.htm";
				}
				break;
			}
			case "7-2":
			{
				st.setCond(10, true);
				takeItems(player, _items[6], 1);
				cast(npc, player, 4546, 1);
				htmltext = "7-06.htm";
				break;
			}
			case "8-1":
			{
				st.setCond(14, true);
				takeItems(player, _items[7], 1);
				cast(npc, player, 4546, 1);
				htmltext = "8-02.htm";
				break;
			}
			case "9-1":
			{
				st.setCond(17, true);
				st.set("Quest0", "0");
				st.set("Tab", "0");
				takeItems(player, _items[8], 1);
				cast(npc, player, 4546, 1);
				htmltext = "9-03.htm";
				break;
			}
			case "10-1":
			{
				if (st.getInt("Quest0") == 0)
				{
					final Npc mob3 = addSpawn(_mob[2], _x[1], _y[1], _z[1], -1);
					final Npc mob2 = addSpawn(_npc[4], _x[2], _y[2], _z[2], -1);
					addSpawn(st, mob3);
					addSpawn(st, mob2);
					st.set("Mob_2", String.valueOf(mob2.getObjectId()));
					st.set("Quest0", "1");
					st.set("Quest1", "45");
					startQuestTimer("Mob_3 Timer 1", 500, mob3, player, true);
					startQuestTimer("Mob_3 has despawned", 59000, mob3, player);
					startQuestTimer("Mob_2 Timer 1", 500, mob2, player);
					startQuestTimer("Mob_2 has despawned", 60000, mob2, player);
					htmltext = "10-02.htm";
				}
				else if (st.getInt("Quest1") == 45)
				{
					htmltext = "10-03.htm";
				}
				else
				{
					htmltext = "10-04.htm";
				}
				break;
			}
			case "10-2":
			{
				st.setCond(19, true);
				takeItems(player, _items[9], 1);
				cast(npc, player, 4546, 1);
				htmltext = "10-06.htm";
				break;
			}
			case "11-9":
			{
				st.setCond(15);
				htmltext = "11-03.htm";
				break;
			}
			case "Mob_1 Timer 1":
			{
				autoChat(npc, _text[0].replace("PLAYERNAME", player.getName()));
				return null;
			}
			case "Mob_1 has despawned":
			{
				autoChat(npc, _text[1].replace("PLAYERNAME", player.getName()));
				st.set("spawned", "0");
				deleteSpawn(npc);
				return null;
			}
			case "Archon Hellisha has despawned":
			{
				autoChat(npc, _text[6].replace("PLAYERNAME", player.getName()));
				st.set("spawned", "0");
				deleteSpawn(npc);
				return null;
			}
			case "Mob_3 Timer 1":
			{
				final Npc mob2 = findSpawn(player, World.findObject(st.getInt("Mob_2")).asNpc());
				if ((World.getFirstVisibleObject(npc, Npc.class, it -> it == mob2) != null))
				{
					npc.asAttackable().addDamageHate(mob2, 0, 99999);
					npc.getAI().setIntentionAttack(mob2);
					mob2.getAI().setIntentionAttack(npc);
					autoChat(npc, _text[14].replace("PLAYERNAME", player.getName()));
					cancelQuestTimer("Mob_3 Timer 1", npc, player);
				}
				
				return null;
			}
			case "Mob_3 has despawned":
			{
				autoChat(npc, _text[15].replace("PLAYERNAME", player.getName()));
				st.set("Quest0", "2");
				deleteSpawn(npc);
				return null;
			}
			case "Mob_2 Timer 1":
			{
				autoChat(npc, _text[7].replace("PLAYERNAME", player.getName()));
				startQuestTimer("Mob_2 Timer 2", 1500, npc, player);
				if (st.getInt("Quest1") == 45)
				{
					st.set("Quest1", "0");
				}
				
				return null;
			}
			case "Mob_2 Timer 2":
			{
				autoChat(npc, _text[8].replace("PLAYERNAME", player.getName()));
				startQuestTimer("Mob_2 Timer 3", 10000, npc, player);
				return null;
			}
			case "Mob_2 Timer 3":
			{
				if (st.getInt("Quest0") == 0)
				{
					startQuestTimer("Mob_2 Timer 3", 13000, npc, player);
					if (getRandomBoolean())
					{
						autoChat(npc, _text[9].replace("PLAYERNAME", player.getName()));
					}
					else
					{
						autoChat(npc, _text[10].replace("PLAYERNAME", player.getName()));
					}
				}
				
				return null;
			}
			case "Mob_2 has despawned":
			{
				st.set("Quest1", String.valueOf(st.getInt("Quest1") + 1));
				if ((st.getInt("Quest0") == 1) || (st.getInt("Quest0") == 2) || (st.getInt("Quest1") > 3))
				{
					st.set("Quest0", "0");
					
					// TODO: This "if" will never be true.
					if (st.getInt("Quest0") == 1)
					{
						autoChat(npc, _text[11].replace("PLAYERNAME", player.getName()));
					}
					else
					{
						autoChat(npc, _text[12].replace("PLAYERNAME", player.getName()));
					}
					
					deleteSpawn(npc);
				}
				else
				{
					startQuestTimer("Mob_2 has despawned", 1000, npc, player);
				}
				
				return null;
			}
		}
		
		return htmltext;
	}
	
	@Override
	public void onAttack(Npc npc, Player player, int damage, boolean isSummon)
	{
		final QuestState st2 = findRightState(npc);
		if (st2 != null)
		{
			final int cond = st2.getCond();
			final QuestState st = getQuestState(player, false);
			final int npcId = npc.getId();
			if ((npcId == _mob[2]) && (st == st2) && (cond == 17))
			{
				int quest0 = st.getInt("Quest0") + 1;
				if (quest0 == 1)
				{
					autoChat(npc, _text[16].replace("PLAYERNAME", player.getName()));
				}
				
				if (quest0 > 15)
				{
					quest0 = 1;
					autoChat(npc, _text[17].replace("PLAYERNAME", player.getName()));
					cancelQuestTimer("Mob_3 has despawned", npc, st2.getPlayer());
					st.set("Tab", "1");
					deleteSpawn(npc);
				}
				
				st.set("Quest0", Integer.toString(quest0));
			}
			else if ((npcId == _mob[1]) && (cond == 15) && ((st != st2) || player.isInParty()))
			{
				autoChat(npc, _text[5].replace("PLAYERNAME", player.getName()));
				cancelQuestTimer("Archon Hellisha has despawned", npc, st2.getPlayer());
				st2.set("spawned", "0");
				deleteSpawn(npc);
			}
		}
	}
	
	@Override
	public String onFirstTalk(Npc npc, Player player)
	{
		String htmltext = "";
		final QuestState st = getQuestState(player, false);
		final int npcId = npc.getId();
		if ((st != null) && (npcId == _npc[4]))
		{
			final int cond = st.getCond();
			if (cond == 17)
			{
				final QuestState st2 = findRightState(npc);
				if (st2 != null)
				{
					player.setLastQuestNpcObject(npc.getObjectId());
					final int tab = st.getInt("Tab");
					final int quest0 = st.getInt("Quest0");
					if (st == st2)
					{
						if (tab == 1)
						{
							if (quest0 == 0)
							{
								htmltext = "4-04.htm";
							}
							else if (quest0 == 1)
							{
								htmltext = "4-06.htm";
							}
						}
						else if (quest0 == 0)
						{
							htmltext = "4-01.htm";
						}
						else if (quest0 == 1)
						{
							htmltext = "4-03.htm";
						}
					}
					else if (tab == 1)
					{
						if (quest0 == 0)
						{
							htmltext = "4-05.htm";
						}
						else if (quest0 == 1)
						{
							htmltext = "4-07.htm";
						}
					}
					else if (quest0 == 0)
					{
						htmltext = "4-02.htm";
					}
				}
			}
			else if (cond == 18)
			{
				htmltext = "4-08.htm";
			}
		}
		
		if (htmltext.isEmpty())
		{
			npc.showChatWindow(player);
		}
		
		return htmltext;
	}
	
	@Override
	public void onKill(Npc npc, Player player, boolean isSummon)
	{
		final int npcId = npc.getId();
		QuestState st = getQuestState(player, false);
		for (int archonMinion = 21646; archonMinion < 21652; archonMinion++)
		{
			if (npcId == archonMinion)
			{
				final Party party = player.getParty();
				if (party != null)
				{
					final List<QuestState> partyQuestMembers = new ArrayList<>();
					for (Player player1 : party.getMembers())
					{
						final QuestState st1 = findQuest(player1);
						if ((st1 != null) && st1.isCond(15) && player1.isInsideRadius2D(player, PlayerConfig.ALT_PARTY_RANGE))
						{
							partyQuestMembers.add(st1);
						}
					}
					
					if (!partyQuestMembers.isEmpty())
					{
						final QuestState st2 = partyQuestMembers.get(getRandom(partyQuestMembers.size()));
						giveHalishaMark(st2);
					}
				}
				else
				{
					final QuestState st1 = findQuest(player);
					if ((st1 != null) && st1.isCond(15))
					{
						giveHalishaMark(st1);
					}
				}
				return;
			}
		}
		
		for (int element : ARCHON_HALISHA_NORM)
		{
			if (npcId == element)
			{
				final QuestState st1 = findQuest(player);
				if ((st1 != null) && st1.isCond(15))
				{
					// This is just a guess....not really sure what it actually says, if anything
					autoChat(npc, _text[4].replace("PLAYERNAME", st1.getPlayer().getName()));
					giveItems(player, _items[8], 1);
					takeItems(player, _items[3], -1);
					st1.setCond(16, true);
				}
				return;
			}
		}
		
		for (int guardianAngel = 27214; guardianAngel < 27217; guardianAngel++)
		{
			if (npcId == guardianAngel)
			{
				final QuestState st1 = findQuest(player);
				if ((st1 != null) && st1.isCond(6))
				{
					final int kills = st1.getInt("kills");
					if (kills < 9)
					{
						st1.set("kills", Integer.toString(kills + 1));
					}
					else
					{
						giveItems(player, _items[5], 1);
						st.setCond(7, true);
					}
				}
				return;
			}
		}
		
		if ((st != null) && (npcId != _mob[2]))
		{
			final QuestState st2 = findRightState(npc);
			if (st2 != null)
			{
				final int cond = st.getCond();
				if ((npcId == _mob[0]) && (cond == 8))
				{
					if (!player.isInParty() && (st == st2))
					{
						autoChat(npc, _text[12].replace("PLAYERNAME", player.getName()));
						giveItems(player, _items[6], 1);
						st.setCond(9, true);
					}
					
					cancelQuestTimer("Mob_1 has despawned", npc, st2.getPlayer());
					st2.set("spawned", "0");
					deleteSpawn(npc);
				}
				else if ((npcId == _mob[1]) && (cond == 15))
				{
					if (!player.isInParty())
					{
						if (st == st2)
						{
							autoChat(npc, _text[4].replace("PLAYERNAME", player.getName()));
							giveItems(player, _items[8], 1);
							takeItems(player, _items[3], -1);
							st.setCond(16, true);
						}
						else
						{
							autoChat(npc, _text[5].replace("PLAYERNAME", player.getName()));
						}
					}
					
					cancelQuestTimer("Archon Hellisha has despawned", npc, st2.getPlayer());
					st2.set("spawned", "0");
					deleteSpawn(npc);
				}
			}
		}
		else if (npcId == _mob[0])
		{
			st = findRightState(npc);
			if (st != null)
			{
				cancelQuestTimer("Mob_1 has despawned", npc, st.getPlayer());
				st.set("spawned", "0");
				deleteSpawn(npc);
			}
		}
		else if (npcId == _mob[1])
		{
			st = findRightState(npc);
			if (st != null)
			{
				cancelQuestTimer("Archon Hellisha has despawned", npc, st.getPlayer());
				st.set("spawned", "0");
				deleteSpawn(npc);
			}
		}
		else if (npcId == _mob[2])
		{
			st = findRightState(npc);
			if (st != null)
			{
				st.setCond(18, true);
				autoChat(npc, _text[13].replace("PLAYERNAME", player.getName()));
				st.set("Quest0", "0");
				cancelQuestTimer("Mob_2 has despawned", npc, player);
				deleteSpawn(npc);
			}
		}
	}
	
	@Override
	public void onSkillSee(Npc npc, Player player, Skill skill, List<WorldObject> targets, boolean isSummon)
	{
		if (SPAWN_LIST.containsKey(npc) && (SPAWN_LIST.get(npc) != player.getObjectId()))
		{
			final Player questPlayer = World.findObject(SPAWN_LIST.get(npc)).asPlayer();
			if (questPlayer == null)
			{
				return;
			}
			
			for (WorldObject obj : targets)
			{
				if ((obj == questPlayer) || (obj == npc))
				{
					final QuestState st2 = findRightState(npc);
					if (st2 == null)
					{
						return;
					}
					
					autoChat(npc, _text[5].replace("PLAYERNAME", player.getName()));
					cancelQuestTimer("Archon Hellisha has despawned", npc, st2.getPlayer());
					st2.set("spawned", "0");
					deleteSpawn(npc);
				}
			}
		}
	}
	
	@Override
	public String onTalk(Npc npc, Player player)
	{
		final QuestState st = getQuestState(player, true);
		String htmltext = getNoQuestMsg(player);
		final int npcId = npc.getId();
		if ((npcId == _npc[0]) && st.isCompleted())
		{
			htmltext = getAlreadyCompletedMsg(player);
		}
		else if (player.getPlayerClass().getId() == getPrevClass(player))
		{
			switch (st.getCond())
			{
				case 0:
				{
					if (npcId == _npc[0])
					{
						htmltext = "0-01.htm";
					}
					break;
				}
				case 1:
				{
					if (npcId == _npc[0])
					{
						htmltext = "0-04.htm";
					}
					else if (npcId == _npc[2])
					{
						htmltext = "2-01.htm";
					}
					break;
				}
				case 2:
				{
					if (npcId == _npc[2])
					{
						htmltext = "2-02.htm";
					}
					else if (npcId == _npc[1])
					{
						htmltext = "1-01.htm";
					}
					break;
				}
				case 3:
				{
					if ((npcId == _npc[1]) && hasQuestItems(player, _items[0]))
					{
						if ((_items[11] == 0) || hasQuestItems(player, _items[11]))
						{
							htmltext = "1-03.htm";
						}
						else
						{
							htmltext = "1-02.htm";
						}
					}
					break;
				}
				case 4:
				{
					if (npcId == _npc[1])
					{
						htmltext = "1-04.htm";
					}
					else if (npcId == _npc[2])
					{
						htmltext = "2-03.htm";
					}
					break;
				}
				case 5:
				{
					if (npcId == _npc[2])
					{
						htmltext = "2-04.htm";
					}
					else if (npcId == _npc[5])
					{
						htmltext = "5-01.htm";
					}
					break;
				}
				case 6:
				{
					if (npcId == _npc[5])
					{
						htmltext = "5-03.htm";
					}
					else if (npcId == _npc[6])
					{
						htmltext = "6-01.htm";
					}
					break;
				}
				case 7:
				{
					if (npcId == _npc[6])
					{
						htmltext = "6-02.htm";
					}
					break;
				}
				case 8:
				{
					if (npcId == _npc[6])
					{
						htmltext = "6-04.htm";
					}
					else if (npcId == _npc[7])
					{
						htmltext = "7-01.htm";
					}
					break;
				}
				case 9:
				{
					if (npcId == _npc[7])
					{
						htmltext = "7-05.htm";
					}
					break;
				}
				case 10:
				{
					if (npcId == _npc[7])
					{
						htmltext = "7-07.htm";
					}
					else if (npcId == _npc[3])
					{
						htmltext = "3-01.htm";
					}
					break;
				}
				case 11:
				case 12:
				{
					if (npcId == _npc[3])
					{
						if (hasQuestItems(player, _items[2]))
						{
							htmltext = "3-05.htm";
						}
						else
						{
							htmltext = "3-04.htm";
						}
					}
					break;
				}
				case 13:
				{
					if (npcId == _npc[3])
					{
						htmltext = "3-06.htm";
					}
					else if (npcId == _npc[8])
					{
						htmltext = "8-01.htm";
					}
					break;
				}
				case 14:
				{
					if (npcId == _npc[8])
					{
						htmltext = "8-03.htm";
					}
					else if (npcId == _npc[11])
					{
						htmltext = "11-01.htm";
					}
					break;
				}
				case 15:
				{
					if (npcId == _npc[11])
					{
						htmltext = "11-02.htm";
					}
					else if (npcId == _npc[9])
					{
						htmltext = "9-01.htm";
					}
					break;
				}
				case 16:
				{
					if (npcId == _npc[9])
					{
						htmltext = "9-02.htm";
					}
					break;
				}
				case 17:
				{
					if (npcId == _npc[9])
					{
						htmltext = "9-04.htm";
					}
					else if (npcId == _npc[10])
					{
						htmltext = "10-01.htm";
					}
					break;
				}
				case 18:
				{
					if (npcId == _npc[10])
					{
						htmltext = "10-05.htm";
					}
					break;
				}
				case 19:
				{
					if (npcId == _npc[10])
					{
						htmltext = "10-07.htm";
					}
					else if (npcId == _npc[0])
					{
						htmltext = "0-06.htm";
					}
					break;
				}
				case 20:
				{
					if (npcId == _npc[0])
					{
						if (player.getLevel() >= 76)
						{
							htmltext = "0-09.htm";
							
							st.exitQuest(false);
							addExpAndSp(player, 2299404, 0);
							giveAdena(player, 5000000, true);
							giveItems(player, 6622, 1); // XXX rewardItems?
							final int playerClass = getPlayerClass(player);
							final int prevClass = getPrevClass(player);
							player.setPlayerClass(playerClass);
							if (!player.isSubClassActive() && (player.getBaseClass() == prevClass))
							{
								player.setBaseClass(playerClass);
							}
							
							player.broadcastUserInfo();
							cast(npc, player, 4339, 1);
						}
						else
						{
							htmltext = "0-010.htm";
						}
					}
					break;
				}
			}
		}
		
		return htmltext;
	}
	
	private QuestState findQuest(Player player)
	{
		final QuestState st = getQuestState(player, false);
		if (st != null)
		{
			if (getId() == 68)
			{
				for (int q = 0; q < 2; q++)
				{
					if (player.getPlayerClass().getId() == QUEST_CLASSES[1][q])
					{
						return st;
					}
				}
			}
			else if (player.getPlayerClass().getId() == QUEST_CLASSES[getId() - 67][0])
			{
				return st;
			}
		}
		
		return null;
	}
	
	private void autoChat(Npc npc, String text)
	{
		npc.broadcastPacket(new NpcSay(npc.getObjectId(), ChatType.GENERAL, npc.getId(), text));
	}
	
	private void cast(Npc npc, Creature target, int skillId, int level)
	{
		target.broadcastSkillPacket(new MagicSkillUse(target, target, skillId, level, 6000, 1), target);
		target.broadcastSkillPacket(new MagicSkillUse(npc, npc, skillId, level, 6000, 1), npc);
	}
	
	private void addSpawn(QuestState st, Npc mob)
	{
		SPAWN_LIST.put(mob, st.getPlayer().getObjectId());
	}
	
	private static Npc findSpawn(Player player, Npc npc)
	{
		if (SPAWN_LIST.containsKey(npc) && (SPAWN_LIST.get(npc) == player.getObjectId()))
		{
			return npc;
		}
		
		return null;
	}
	
	private void deleteSpawn(Npc npc)
	{
		if (SPAWN_LIST.remove(npc) != null)
		{
			npc.deleteMe();
		}
	}
	
	private QuestState findRightState(Npc npc)
	{
		Player player = null;
		QuestState st = null;
		final Integer spawned = SPAWN_LIST.get(npc);
		if (spawned != null)
		{
			player = World.getPlayer(spawned);
			if (player != null)
			{
				st = player.getQuestState(getName());
			}
		}
		
		return st;
	}
	
	private int getPlayerClass(Player player)
	{
		if (player.getPlayerClass().getId() == 0x81)
		{
			return _classId[1];
		}
		
		return _classId[0];
	}
	
	private int getPrevClass(Player player)
	{
		if (player.getPlayerClass().getId() == 0x81)
		{
			if (_prevClass.length == 1)
			{
				return -1;
			}
			
			return _prevClass[1];
		}
		
		return _prevClass[0];
	}
	
	private void giveHalishaMark(QuestState st)
	{
		if (st.getInt("spawned") == 0)
		{
			final Player player = st.getPlayer();
			if (getQuestItemsCount(player, _items[3]) >= 700)
			{
				takeItems(player, _items[3], 20);
				final int xx = st.getPlayer().getX();
				final int yy = st.getPlayer().getY();
				final int zz = st.getPlayer().getZ();
				final Npc archon = addSpawn(_mob[1], xx, yy, zz, -1);
				addSpawn(st, archon);
				st.set("spawned", "1");
				startQuestTimer("Archon Hellisha has despawned", 600000, archon, player);
				autoChat(archon, _text[13].replace("PLAYERNAME", st.getPlayer().getName()));
				archon.asAttackable().addDamageHate(st.getPlayer(), 0, 99999);
				archon.getAI().setIntentionAttack(st.getPlayer());
			}
			else
			{
				giveItems(player, _items[3], getRandom(1, 4));
			}
		}
	}
}