ZURSULUS L2

Saga of the Phoenix Knight

ID
70
Название
Saga of the Phoenix Knight
start_npcs_json
[]
npc_ids_json
[]
constants_json
{}
Статус разбора
metadata_only; dynamic Java conditions/rewards retained in source; unresolved starts: []
Источник
game/data/scripts/quests/Q00070_SagaOfThePhoenixKnight/Q00070_SagaOfThePhoenixKnight.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] Grand Master Sedrick: I'm sure you've felt the dilemma of being a Paladin by now. How do you act when life, honor, truth, justice, faith and belief seem in conflict with each other? How can you reconcile that? It's not easy to find justice. "What do you mean?" [0-010.htm] Grand Master Sedrick: Come back when your body is as strong as your faith. (Only a character of level 76 or above may transfer classes. Don't abandon the quest until class transfer is complete.) [0-02.htm] Grand Master Sedrick: Come back when your sword is shinier! (This quest may only be undertaken by a Paladin level is 76 or above.) [0-03.htm] Grand Master Sedrick: Find Felix in Goddard. He was a Knight of Dion and fell in love with a maiden there. He betrayed his knighthood and ran away with her when the uprising of the peasants led to the oppression of the Knights. The records of the Knights Guild speak of the most powerful Knight being obsessed with his title and disappearing. It could be him. [0-04.htm] Grand Master Sedrick: See Felix in Goddard. With his skills, he might be working as a guard or master. He will know of the ancient training. [0-05.htm] Grand Master Sedrick: Long ago, a peasant revolt broke out in a small village in Dion Territory. When talks failed, the local manor lord resorted to force. Obeying their orders, the top Knights of the guild fought for him. However, many young Knights followed their conscience and sided with the peasants. The order was split, each side feeling righteous. I wonder if either side was right. Could a Knight just be defending his ego? There is no such thing as true justice. Whether a Paladin or Dark Avenger, one must choose and defend that choice with conviction! Will you take this training journey, as written in the book of ancient rites? Then you'll be able to answer my question! "I will!" [0-06.htm] Grand Master Sedrick: You seem different. Do you think you know about trust? What is most important is to be trusted by others and to trust yourself. Can you answer my question now? "I must conduct myself honorably and practice justice." [0-07.htm] Grand Master Sedrick: There are many perspectives on justice. You have to fight by the light of the justice in your heart. My traveling days are over. You have transcended your country or religion as a Knight or Paladin with your values. Lead your life by the candle in your heart! [0-08.htm] Grand Master Sedrick: You need skill to protect justice. You have obtained enlightenment but still need the protection as a Knight of the temple. (Only a character of level 76 or above can transfer class. Do not abandon the quest until class transfer is complete!) [0-09.htm] Grand Master Sedrick: As long as the light in your heart is not extinguished, you may guard and protect justice without being bound by the rules of any organization. Hold the fire in your heart and live your life as a Knight re-born! [1-01.htm] Chef Donath: So, you want an Ice Cold Flower, eh? What do you need it for? Oh no! Not Execution Grounds Fever!? Isn't... That fever caused by corpses? The ingredients for Ice Cold Flower are hard to come by... "What can I do?" [1-02.htm] Chef Donath: That's a very serious disease! Whoever gets it falls down and doesn't get back up! Ask Chef Jeremy about the ice crystal. Ask a fisherman for the fat white fish, or perhaps you could catch it yourself! [1-03.htm] Chef Donath: Here's the ice crystal... and, a fat white fish! You've brought both of them! The dish is very simple. This fish contains cold air. Cut it carefully into thin slices and wrap them around ice crystals... It makes a great sushi! It perfectly enhances the chill of the ice crystal and spreads the cold air around it. Use the scales to wrap it up and seal it. This dish is called Ice Cold Flower... And here it is! "Thank you!" [1-04.htm] Chef Donath: Hey, what are you doing here? Didn't you say that Felix's daughter was dying? I've been working my ass off for you! [1-05.htm] Chef Donath: First, I'll need an ice crystal and a fat white fish. The dish's name is deceptive. It's actually a lovely cold dish made of fish. As ice crystals are the legendary food material, Chef Jeremy can tell you more of the details. You can either get the fish from a fisherman or catch it yourself! [1-06.htm] Chef Donath: Put it near the patient's head and pull that string. The dish will open like a flower and chilled air will escape from it. Did you say the patient was Felix? Or his daughter? Anyways, that chill should cure the Execution Grounds Fever. Now, you know what to do. Hurry back to your patient. [10-01.htm] Tablet of Vision: As you approach the tablet, you feel a presence. Could it be the soul of the one who discouraged Sedrick and degraded the Fallen Knight Adil, here to prevent anyone from learning the secrets of the tablet? It looks back at you with the eyes of those you chose not to protect. Now the tablet is before your eyes! Is it an illusion? The sound of swordplay brings you back to reality. Patrol the area. [10-02.htm] Tablet of Vision: Suddenly you feel a chill, and then see the flash of a blade! When you open your eyes you discover that a mortal blow was blocked... [10-03.htm] Tablet of Vision: The tablet is still and dark. You must speak with Eric over there. [10-04.htm] Tablet of Vision: There's a disturbance near the tablet, but it's not your business. Don't get involved. Come back when it's time. [10-05.htm] Tablet of Vision: The Stone of Commune begins emitting light as you near the tablet. Commune with the Tablet of Vision. [10-06.htm] Tablet of Vision: A sharp blast of knowlege courses through your cranium! You hear the sound of distant laughter. A man announces the birth of another Hero. The woman in blue disagrees... This is the last time she'll see the child! A voice in your head tells you forgotten stories of ancient knights. You must tell Grand Master Sedrick what you've learned! He'll make you a Phoenix Knight! [10-07.htm] Tablet of Vision: Further communion with this tablet would be futile. Go back to Grand Master Sedrick in Aden Castle Town. [11-01.htm] Master Felix: You haven't finished yet? I really appreciated you saving my daughter. I'll never forget that you protected my family. The fifth Stone of Commune? Ah, yes. I have it, but I can't give this one to you. A Knight gave me this an hour ago and told me to tell the next Knight who visits me how to get another one. "Tell me how!" [11-02.htm] Master Felix: To get the stone, there are two ways. You can get it either by entering the Four Sepulchers or by slaying evil monsters in the Shrine of the Loyal by the Wall of Argos. Anyways, you must kill the Archon of Halisha. The Stone of Commune will let you know where the next tablet is. [11-03.htm] Master Felix: To get the Stone of Commune, you must kill the Archon of Halisha, either by entering the Four Sepulchers or by slaying evil monsters in the Shrine of the Loyal by the Wall of Argos. Both paths will be difficult! The fifth stone tablet is in the northwest corner of the Wall of Argos. [2-01.htm] Master Felix: I used to have the pride of a Knight. I sacrificed it to save my family. Did Sedrick tell you I was the one who gave up everything and left? My wife has since died, and now my daughter is very sick. "What's wrong?" [2-02.htm] Master Felix: You don't have the Ice Cold Flower? See Donath in the hot springs area of Goddard! [2-03.htm] Master Felix: Ice Cold Flower! I'll put this at her bedside when she sleeps. You must visit the six stone tablets placed by the gods around our world. The legendary Knight disappeared to undertake this pilgrimage! However... "What?" [2-04.htm] Master Felix: Did you see the first stone tablet in the South of Tower of Insolence? I don't know about the Stone of Commune very well. However, Sedrick left this Stone of Commune with me long time ago... Go to the tablet. Then, commune with the first stone tablet! This is all I know now. [2-05.htm] Master Felix: My daughter has come down with Execution Grounds Fever. I need an Ice Cold Flower. Even if Sedrick has other plans for you, bring me one and I'll tell you what path to follow. Meet Chef Donath in the north, he'll help you get one. [2-06.htm] Master Felix: You saved my daughter's life! Sedrick is the only guild member to succeed in this quest. Take this stone and commune with the stone tablet, then you'll be able to read the inscriptions on it. The legendary Knight is the guardian of the stone tablets. He was cursed and bound to the tablets, and will attack pilgrims. Find the first tablet to the south of the Tower of Insolence! [3-01.htm] Grand Master Sedrick: From your wounds, I'd say you've fought with Adil. I wondered why we would undertake the pilgrimage when we couldn't even comprehend the inscriptions on the Tablets of Vision. I found out about the Stone of Commune in the ancient texts. I hit a wall, and my Stone of Commune was damaged beyond use. "How do I repair it?" [3-02.htm] Grand Master Sedrick: The advance base of the Ketra Orcs is in the northern part of Goddard Castle Town. Meet with Ketra's Messenger Wahkan. You can still change sides. Do you remember what a Knight seeks to defend? This task is relevant to that! If you fight for one side, you are fighting against the other! [3-03.htm] Grand Master Sedrick: The Varka Silenos stronghold is located in the western section of Goddard Castle Town. Meet with Varka's Messenger Naran Ashanuk. You can still change sides. Do you remember what a Knight seeks to defend? This task is relevant to that! If you fight for one side, you are fighting against the other! [3-04.htm] Grand Master Sedrick: Go get the Divine Stone of Wisdom either from the Ketra Orcs or the Varka Silenos. Only then will this Stone of Commune work. [3-05.htm] Grand Master Sedrick: Did you have to make a sacrifice to get the Divine Stone of Wisdom? Did you choose to defend your mission, the Ketra Orcs or the Varka Silenos? Sometimes you must make difficult choices. ...... [3-06.htm] Grand Master Sedrick: Go to the forth tablet in the north of the Varka Silenos Camp. Don't forget your new friendship or your sacrifice. [3-07.htm] Grand Master Sedrick: The Orc shaman Tarkai recently gave me instructions on how to activate the Stone of Commune. The Ketra Orcs and the Varka Silenos both possess and worship magical fragments called the Divine Stone of Wisdom. You need one of these fragments to restore power to the Stone of Commune! To get it, you'll have to win their trust. Which side will you get it from? The Ketra Orcs The Varka Silenos [3-08.htm] Grand Master Sedrick: The Stone of Commune is whole once again! You can feel it, right? Take it and go to the forth tablet in the north of the Varka Silenos Camp. But don't forget. The works you've done to get this... and the lessons from your trials! [4-01.htm] Eric Ramsheart: Finally, someone shows up! I knew it would happen sooner or later! Do you know what you're fighting for? If so, put your conviction onto your sword and kill this seducer of knights! [4-010.htm] Eric Ramsheart: Do you remember the oath you took when you first became a knight? To defend honor at all cost? Do you think the action of Sir Herod, who died a miserable death defending his honor, was a right one? What did you learn from the testimony of trust? Trust is what we knights have to give to people! Trust! Trust is also faith. You don't betray what you have faith in, nor those who have faith in you. There's only one more thing... You must discover how to earn trust from people.... You probably already know all about this. I shouldn't need to explain it to you... Now, ask your last question to the stone tablet. "Wait!" [4-011.htm] Eric Ramsheart: Do you remember the oath you took when you first became a knight? To defend honor at all cost? Do you think the actions of Sir Herod, who died a miserable death defending his honor, were right? What did you learn from the testimony of trust? Trust is all we knights have to offer! Trust also means faith. You don't betray what you have faith in, nor those who have faith in you. There's only one more thing... You must discover how to earn trust from people... You probably already know all about this. I shouldn't need to explain it to you... Now, ask your last question to the stone tablet. [4-02.htm] Eric Ramsheart: Don't talk to me now! It's too dangerous! Stay away! [4-03.htm] Eric Ramsheart: ............ Damn the bad luck.....! He got away again! I think I'm in over my head...! .... If only some capable person would offer to help me.... [4-04.htm] Eric Ramsheart: Don't hesitate to kill! This seducer digs its claws into the strongest of hearts! Countless brave knights have been corrupted by the mere whisper of this devil! Don't you have any self-respect? [4-05.htm] Eric Ramsheart: You're brave, but this isn't the time for you to fight! Stay away for now! [4-06.htm] Eric Ramsheart: There is an evil that lives deep within all knights' hearts... It's the spirit that ultimately corrupts knighthood. Beleth is a seducer. His trap lies in the foundation of equality, an absolute virtue! He treats everybody equally. That is, he destroys and corrupts all. But, that's not. We're not all equal. From the moment you resolve in your heart to become a protector, all others become either predators, protectors or protected. The strength of your commitment is tested daily. The path we walk flows deep with blood and gore. The longer you walk this path, the more that sticks to you, making your feet heavy and your sword dull. And that's not the worst of it! "What else is there?" [4-07.htm] Eric Ramsheart: There is an evil that lives deep within all knights' hearts... It's the spirit that ultimately corrupts knighthood. Beleth is a seducer. His trap lies in the foundation of equality, an absolute virtue! He treats everybody equally. That is, he destroys and corrupts all. But, we're not all equal. From the moment you resolve in your heart to become a protector, all others become either predators, protectors or protected. The strength of your commitment is tested daily. The path we walk flows deep with blood and gore. The longer you walk this path, the more that sticks to you, making your feet heavy and your sword dull. And that's not the worst of it! "What else is there?" [4-08.htm] Eric Ramsheart: I've already given you everything I have to give! Don't listen to me! Get your answer from that stone tablet over there! [4-09.htm] Eric Ramsheart: I've already given you everything I have to give! Don't listen to me! Get your answer from that stone tablet over there! [5-01.htm] Tablet of Vision: The Stone of Commune starts emitting light as you near the tablet. Commune with the Tablet of Vision. [5-02.htm] Tablet of Vision: Countless thoughts beyond comprehension sear painfully into your brain. A female voice seems to float on by as if she were quietly laughing at you... You sense the presence of many armed guards protecting the Stone of Commune. They're in the northeastern part of the Valley of Saints. [5-03.htm] Tablet of Vision: Further communion with this tablet is futile. The next Stone of Commune can be found in the northeastern part of the Valley of Saints. Kill the guardians and take their Stone of Commune. [6-01.htm] Tablet of Vision: The hieroglyphs on the tablet are indecipherable. The Guardians of Forbidden Knowledge have the Stone of Commune you need to access this tablet. [6-02.htm] Tablet of Vision: The Stone of Commune starts emitting light as soon as you near the Tablet of Vision. Commune with the Tablet of Vision. [6-03.htm] Tablet of Vision: Countless thoughts beyond comprehension sear painfully into your brain. A female voice seems to float on by as if she were quietly laughing at you... Suddenly you sense the presence of a knight named Adil, he who gave up everything for what he desired... Victory! He waits inside the Wall of Argos. [6-04.htm] Tablet of Vision: Further communion with this tablet is futile. You must prepare to meet Adil, the corrupt knight, and take the Stone of Commune from him! [7-01.htm] Tablet of Vision: As you near the Tablet of Vision, you sense a presence. Could it be someone you've learned about in the past? Might it be that you know the tale of the guardian of this tablet? Thoughts race through your mind. Have you read the book about Knight Adil? Look around [7-02.htm] Tablet of Vision: A heavy sensation grips you tightly. The one who sacrificed everything for victory! Victory in battle was his only desire! Can you defeat him? Could you possibly win against such an opponent? [7-03.htm] Tablet of Vision: The time has come to examine the Tablet of Vision. Adil's attack is coming constantly! Defeat him first! [7-04.htm] Tablet of Vision: You sense a disturbance near the tablet. The time hasn't yet come for you to prove yourself. Come back later. [7-05.htm] Tablet of Vision: The Stone of Commune starts emitting light as soon as you near the Tablet of Vision. Commune with the Tablet of Vision. [7-06.htm] Tablet of Vision: Countless thoughts beyond comprehension sear painfully into your brain. You hear the faint whisper of a woman's voice. A vision appears... A handsome young knight, entering Aden Castle Town with a Stone of Commune! Could it be... Sedrick? [7-07.htm] Tablet of Vision: Further communion with this tablet is futile. Get the next Stone of Commune from Grand Master Sedrick at Sedrick's Training Hall in Aden Castle Town! [8-01.htm] Tablet of Vision: The Stone of Commune starts emitting light as you approach the Tablet of Vision. Commune with the Tablet of Vision. [8-02.htm] Tablet of Vision: Countless thoughts beyond comprehension sear painfully into your brain. A vision appears of a mysterious dark knight... A man smiles broadly, because his daughter's illness was cured at Goddard Castle Town. He also has the Stone of Commune! Speak with Master Felix in Goddard Castle Town. [8-03.htm] Tablet of Vision: Further communion with this tablet would be pointless at this time. Speak with Master Felix in Goddard Castle Town. [9-01.htm] Tablet of Vision: The Tablet lies still as if there was no change. The correct Stone of Commune is obtainable at the Imperial Tomb or the Shrine of the Loyal. [9-02.htm] Tablet of Vision: The Stone of Commune starts emitting light as you approach the Tablet of Vision. Commune with the Tablet of Vision. [9-03.htm] Tablet of Vision: A sharp blast of knowlege courses through your cranium! A vision of a black knight appears... Sedrick was defeated! The last Stone of Commune... It was the black knight who corrupted Adil! [9-04.htm] Tablet of Vision: Further communion with this tablet would be futile. The next Stone of Commune is in the Forest of the Dead in Rune Territory. The horror of Sedrick's defeat is burned into my memory. Can I defeat the black knight?
Исходник условий и наград (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.Q00070_SagaOfThePhoenixKnight;

import quests.AbstractSagaQuest;

/**
 * @author Emperorc
 */
public class Q00070_SagaOfThePhoenixKnight extends AbstractSagaQuest
{
	public Q00070_SagaOfThePhoenixKnight()
	{
		super(70, "Saga of the Phoenix Knight");
		_npc = new int[]
		{
			30849,
			31624,
			31277,
			30849,
			31631,
			31646,
			31647,
			31650,
			31654,
			31655,
			31657,
			31277
		};
		_items = new int[]
		{
			7080,
			7534,
			7081,
			7485,
			7268,
			7299,
			7330,
			7361,
			7392,
			7423,
			7093,
			6482
		};
		_mob = new int[]
		{
			27286,
			27219,
			27278
		};
		_classId = new int[]
		{
			90
		};
		_prevClass = new int[]
		{
			0x05
		};
		_x = new int[]
		{
			191046,
			46087,
			46066
		};
		_y = new int[]
		{
			-40640,
			-36372,
			-36396
		};
		_z = new int[]
		{
			-3042,
			-1685,
			-1685
		};
		_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));
			}
		}
	}
}