ZURSULUS L2

Saga of the Sword Muse

ID
72
Название
Saga of the Sword Muse
start_npcs_json
[]
npc_ids_json
[]
constants_json
{}
Статус разбора
metadata_only; dynamic Java conditions/rewards retained in source; unresolved starts: []
Источник
game/data/scripts/quests/Q00072_SagaOfTheSwordMuse/Q00072_SagaOfTheSwordMuse.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 Raien: So you're the Great Swordsinger I've heard about. You've comforted many a soldier with your songs of the glory of Eva. Some say they embody the wisdom of Eva, as the songs of a Swordsinger are taught by the goddess. Would you like to hear the story? "Yes!" [0-010.htm] Master Raien: You must continue your training. (Class transfer is allowed only for characters of level 76 or above. Do not abandon quest before class transfer is complete!) [0-02.htm] Master Raien: You must be well qualified to understand the way. I don't think you should do this. I don't think you can talk to him. I don't even want to think about him anymore. (This quest may only be undertaken by characters of level 76 or above.) [0-03.htm] Master Raien: Don't mind his grotesque beard and ugly smile, Blacksmith Feynn of Goddard Castle Town knows of the source of Eva's songs. Take this book, it tells of the fall of a Swordsinger. [0-04.htm] Master Raien: Blacksmith Feynn of Goddard Castle Town knows of the source of Eva's songs. Find him. [0-05.htm] Master Raien: Goddess Eva's songs and poems gave us intelligence, knowledge and magical power. It belonged only to the Elves. The traditional swordsong may be a far cry from its origins after mingling with the Humans, but it is still our tradition. The story tells of a tablet that contains the power of the original song. You'll have to solve one problem... Quest [0-06.htm] Master Raien: I dreamed of your return. Do you understand Eva's will? The one who sings her true song is called Eva's Sword Muse. "What should I do now?" [0-07.htm] Master Raien: You should know better than I. I only need to give you the title you are due, one who sings Eva's swordsong... [0-08.htm] Master Raien: You should know better than I. Your soul may be ready, but your body is lacking. (Class transfer is allowed only for characters of level 76 or above. Do not abandon quest before class transfer is complete!) [0-09.htm] Master Raien: Henceforth, you shall be known as a Sword Muse! [1-01.htm] Chef Donath: What can I help you with? What? Bitter Cold Beer? I've been getting a lot of requests for legendary dishes lately! Such is the plight of a great chef! Quality is always in demand! Listen! You'll need to bring me the ingredients on your own. Understand? "Yes, I understand." [1-02.htm] Chef Donath: You haven't found the ingredients yet? Before this oil burns, you need to bring me a fat white fish and an ice crystal! Ask Chef Jeremy regarding the ice crystal. You'll have to find the fish on your own. Hurry! [1-03.htm] Chef Donath: Oh, you brought the ice crystal and the fish! Great! Then, I'll make Bitter Cold Beer. According to legend, the original Bitter Cold Beer had a slightly fishy aroma. To get that, you need to roast this fish and capture the smell of it in the ice... In other words, cut up the fish and roast only its fins and bones... Chop the ice crystal into small pieces. A regular knife freezes the moment it touches the ice crystal. I use a special knife. This knife was made by the top maestro of the Black Anvil guild. He actually collected starlight and pummeled it! Making this beer is no easy task! Wait. [1-04.htm] Chef Donath: Why are you still here? I've done everything I could do! I just want to have my food enjoyed by as many people as possible, to give them joy in their lives! Now, take the beer to the Dwarf! [1-05.htm] Chef Donath: Now, I'll tell you what I'll need. Most important is the legendary ice crystal! Chef Jeremy will know where to get one. Knowing Jeremy, he'll want something in return. You'll also need to bring a fat, white fish. I simply can't make Bitter Cold Beer without it! Bring these things to me. I'll get the fire ready... [1-06.htm] Chef Donath: Great! Now put the ice crystals into the beer and let the aroma of the fish just... And here we go! Bitter Cold Beer! As a bonus, I'll fry up the left-over fish for you to have with your beer. Beer and fried fish are excellent together! I don't know why you're doing this, but I hope the Dwarf enjoys it! It's just a pitcher of beer, but it took a lot of effort! Now, take it and go! [10-01.htm] Tablet of Vision: As you approach the tablet, you sense a presence. Will you be able to overcome the temptation...? Hey, where did she go? A stage opens to thunderous applause, but you are the only audience... .....There is a tablet in front of you. Was that an illusion? A voice seems to float by on the breeze. Examine the area. [10-02.htm] Tablet of Vision: A vision appears of the devil you saw before... But who is that lady fighting him now? [10-03.htm] Tablet of Vision: The tablet is quiet. Talk with Moon Voice Irene. [10-04.htm] Tablet of Vision: You feel a presence as you approach the tablet. There's a disturbance going on somewhere. Best not to get involved. It's too early to start fighting. [10-05.htm] Tablet of Vision: The Stone of Commune emits light as you approach the tablet. Commune with the Tablet of Vision. [10-06.htm] Tablet of Vision: Vast amounts of knowledge rush into your mind. You hear the sound of distant laughter. A voice whispers, "Another Hero is born." The lady in blue disagrees, but he doesn't need his mother's protection anymore. Song is the key. A song is complete only when there is a singer and a listener. The singer lives to heal the heart of the listener through song. This is the lost magic. You can sing Eva's song. Go back to Master Raien of Aden Castle Town. [10-07.htm] Tablet of Vision: You can't commune with this tablet. Meet Master Raien of Aden Castle Town and finish the pilgrimage. [11-01.htm] Priest Cerenas: The Stone of Commune, eh? I'll bet you're looking for the tablet too, aren't you? Ah yes, the song of the Swordsinger... Surely you've heard the story of the legendary singer who followed the same path!? What was his name? Biel or something...? What? You fought him? So the stories were true! The merciful heart of Eva must have called you to help the one who has lost his way... Legend says that the goddess herself watches over Elves on that pilgrimage! That's you! If my memory serves, you'll find the location of the next stone from the tablet. Unfortunately, this one is mine and you can't have it! "Why not?" [11-02.htm] Priest Cerenas: To get the stone you must fight the Archon of Halisha in the Four Sepulchers or at the Shrine of the Loyal. [11-03.htm] Priest Cerenas: Eva would be quite displeased! My only function is to guide pilgrims on their way. You've already been on this path for a while, and seen several tablets. You are truly a pilgrim. This stone will prove your victory over the Archon of Halisha and his minions. Find them in the Four Sepulchers or in the Shrine of the Loyal near the Wall of Argos. If you fight the enemies and collect the marks of Halisha 700 or more, you can see the Archon of Halisha. You must slaughter the Archon of Halisha! [2-01.htm] Blacksmith Feynn: Ha ha! So you're here for the teachings of Eva, eh? Hmm... OK, but it won't come cheap! Get it? What's in it for me? No, I don't want your money or gemstones... Nothing like that! I've got all of that kind of stuff I need, thanks... What can you offer the man who has everything? "How about a song?" [2-02.htm] Blacksmith Feynn: What good is a song without a beer? Bring me a Bitter Cold Beer from Chef Jonas in Goddard Castle Town... That would even make the squealing of a pig sound like a beautiful aria! [2-03.htm] Blacksmith Feynn: Huh? Is that a beer?! Amazing! You really brought it! I thought you were just a weakling entertainer! I'm impressed! I guess if I live long enough, I'll see everything! You even brought snacks! You really take care of your customers, don't you? You passed the beer test with flying colors, but now comes the hard part! I haven't heard you sing yet! Sing me a song and then I'll decide whether or not to tell you how to get the stone of pilgrimage! "OK, here goes...!" [2-04.htm] Blacksmith Feynn: Huh? Have you forgotten where the stone tablet is already? I told you, it's in the southern part of the Tower of Insolence. Got it? Do you have the Stone of Commune? Don't drop it on the way there! You have a long journey ahead. Be careful! [2-05.htm] Blacksmith Feynn: You're really going to sing? This should be hilarious! Honestly, sometimes I just don't get you Elves! We Dwarves never listen to music sober! It's like eating pancakes without syrup! Have you ever tasted beer? From the moment it hits your tongue, a cold tingle shoots through you like an electric current... straight to your brain! Bring me some of the legendary beer and I'll listen to you sing! What do you say? I'll bet Chef Donath in the Hot Springs area of Goddard can make the legendary Bitter Cold Beer! If you get it from him, I'll listen to you sing! [2-06.htm] Blacksmith Feynn: Wait, let me take a drink first!... Gulp...Gulp...Gulp ...... .... ... . Oh yeah, great song, buddy! You passed the test! You know, a while back, a lady wearing a blue dress appeared to me in a dream! She said that soon I'd be visited by a singer seeking a test. She told me I should do it. Do you know the test? It was respect! To pass the test, the person would do as I asked, no matter how rude my manner was. And, he would sing a song with a sincere heart... Here is the Stone of Commune. Take it with you to the Tablet of Vision. The first tablet can be found in the south part of the Tower of Insolence. I'll pray that your song becomes popular! Oh, and thanks for the beer! Ha! Good luck! [3-01.htm] Beast Herder Tunatun: What? The Stone of Commune? Uh... As a matter of fact, yes, I have it! But I can't give it to you! Let me explain... For as long as I can remember, I've had but one dream! It was the same every night, but forgotten soon after waking. But recently, I remembered it! I dream of being able to communicate with all other intelligent beings! I suppose I'm getting ahead of myself... Basically, I just want everyone to understand each other... And the animals! I've always loved animals and want people to be able to talk with them! I believe that this Stone of Commune will lead me there... But, if you really need it, I'll give it to you. Just trade me something of equal value for it. Ask about the thing of equal value. [3-02.htm] Beast Herder Tunatun: Helping the Ketra Orcs, eh? That's fine. They're currently at war with the Varka Silenos over a piece of land. Honestly, my friend, I don't have a dog in that fight! So do me a favor... If you change your mind, you can go over to the other side. But eventually you should bring me the Divine Stone of Wisdom first. [3-03.htm] Beast Herder Tunatun: Helping the Varka Silenos, eh? That's fine. They're currently at war with the Ketra Orcs over a piece of land. Honestly, my friend, I don't have a dog in that fight! So do me a favor... If you change your mind, you can go over to the other side. But eventually you should bring me the Divine Stone of Wisdom first. [3-04.htm] Beast Herder Tunatun: Did you bring me the Divine Stone of Wisdom? That stone is proof of friendship. I won't give you this Stone of Commune until you bring me that stone! By the way, don't mention my name to anybody! I've got to live with these people after this is over! [3-05.htm] Beast Herder Tunatun: You've brought the Divine Stone of Wisdom, right? All right. Now, I'll give you the Stone of Commune. Actually, I'm hoping to get two stones of sacred wisdom! One from the Varka Silenos and one from the Ketra Orcs... If I had two stones, I could meet with the chiefs of both tribes! If I could just get them talking, I think we could establish a peace that would let us share our common land to our mutual benefit! Ah, yes! You wanted the Stone of Commune, right? "Yes, please." [3-06.htm] Beast Herder Tunatun: The stone tablet that's linked with the Stone of Commune is located in the northern part of the Varka Silenos Barracks. You must find that stone tablet! [3-07.htm] Beast Herder Tunatun: Ah, yes, the Divine Stone of Wisdom. It's owned by the Ketra Orcs and the Varka Silenos. It holds a secret... the ability to communicate between tribes! Not only that, the fact that you have it is proof of your close friendship with them! Although it's more than I can logically hope for, ultimately, it's my hope to communicate not only with animals but also with all other intelligent beings! Bring it to me and I'll give you this Stone of Commune. Which tribe will you get the stone from? "I'll get the stone from the Ketra Orcs." "I'll get the stone from the Varka Silenos." [3-08.htm] Beast Herder Tunatun: Although it's certainly not my problem, I suppose I should let you in on where the Stone of Commune will take you! The Stone of Commune is linked with the stone tablet on the north of the Varka Silenos Barracks. You must find that stone tablet! Meanwhile, I'll study the Divine Stone of Wisdom and try to find what I'm looking for, so that someday all species will be able to communicate with each other! [4-01.htm] Moonvoice Irene: Songs should be used for healing, not for seduction. Be careful how you use them! [4-010.htm] Moonvoice Irene: You're a great singer! Take this Stone of Commune to complete your pilgrimage. I must recover from that attack. Hold onto your good heart and always embrace others with Eva's melody. Do not surrender to seduction! "I'll take it." [4-011.htm] Moonvoice Irene: You're a great singer! Take this Stone of Commune to complete your pilgrimage. I must recover from that attack. Hold onto your good heart and always embrace others with Eva's melody. Do not surrender to seduction! [4-02.htm] Moonvoice Irene: Now's not a good time! This is dangerous, get back! [4-03.htm] Moonvoice Irene: He got away! [4-04.htm] Moonvoice Irene: I'm glad you're here. Together we will surely win. A trick of the dark arts forces people to listen and applaud. This is not the song of Eva! [4-05.htm] Moonvoice Irene: This is not a good time to chat! [4-06.htm] Moonvoice Irene: It's gone! That creature is trying to corrupt swordsingers. A singer doesn't just sing by herself, that would make you lonely! A singer exists for the audience, to make them happy and comfort them when they are sad. "I agree." [4-07.htm] Moonvoice Irene: It's gone! That creature is trying to corrupt swordsingers. A singer doesn't just sing by herself, that would make you lonely! A singer exists for the audience, to make them happy and comfort them when they are sad. "I agree." [4-08.htm] Moonvoice Irene: Sorry, I'm busy now. Go to the stone tablet! [4-09.htm] Moonvoice Irene: Why haven't you communed with the stone tablet yet? [5-01.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. [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 the wind were singing... You sense that the next Stone of Commune is being held by warriors beside the western wall in the Valley of the Saints. [5-03.htm] Tablet of Vision: Further communion with this tablet is futile. The next Stone of Commune is being held by the Guardians of Forbidden Knowledge in the Valley of the Saints. Kill the guardians and take the stone! [6-01.htm] Tablet of Vision: Hieroglyphics are engraved on the tablet. The Stone of Commune for this tablet is being held by one of the Guardians of Forbidden Knowledge. [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. You hear the faint whisper of a woman's voice. You see a vision of a male Elf, singing to thunderous applause! You once read about him in a book called "Critique of Biel's Song". Could he have the next Stone of Commune? He's waiting at the next Tablet of Vision, in the northeast corner of the Ketra Orc Outpost! [6-04.htm] Tablet of Vision: I have nothing to do with this Tablet Maybe, I will meet Biel, the cursed songster at the next Tablet. The next Tablet of Vision is in the northeast of the Ketra Orc Outpost. Prepare yourself and make haste. [7-01.htm] Tablet of Vision: As you near the Tablet of Vision, you sense a presence. Her desire for love from everyone left her completely alone! I read a critique once of the Song of Biel. Can I harmonize with her? "I'll just give it a try!" [7-02.htm] Tablet of Vision: Applause in an empty theater and a stage set for only one... She is truly in a world of her own! Eva herself must have sent me here! [7-03.htm] Tablet of Vision: It is not time to examine the Tablet of Vision. You're the only audience! You may have to pay attention to her song, otherwise... [7-04.htm] Tablet of Vision: You sense a disturbance near the tablet. The time hasn't yet come for you to prove yourself. [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: Thoughts beyond understanding are seared into your brain. You hear the faint whisper of a woman's voice. A vision appears of a man who believes that the thing everyone gave up on is possible. He hopes that one day everyone will understand each other! He's the Beast Herder Tunatun in the north of Rune Castle Town. [7-07.htm] Tablet of Vision: You do not need this tablet anymore. Get the next Stone of Commune from Beast Herder Tunatun. [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. I think I saw a man in black armor somewhere... I begin to visualize an image of the ElvenTetrarch and he's holding the Stone of Commune. He seems to be agonizing over something... Find the Priest Cerenas, Elven Tetrarch in Goddard Castle Town. [8-03.htm] Tablet of Vision: Fiddling with this tablet further is futile. Find the Priest Cerenas, Elven Tetrarch in Goddard Castle Town. [9-01.htm] Tablet of Vision: The tablet is still and dark. The Stone of Commune that can access this tablet can be found at the Wall of Argos or the Imperial Tomb. [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 appears of a black knight! And there's the demon who tempted Biel! It is a sweet but dangerous poison..! Why is he following that Elf? And what of the voice of the moon? She's headed to the sixth Tablet of Vision, south of Hunters Village, unaware that the demon awaits her there... [9-04.htm] Tablet of Vision: Further communion with this tablet would be futile. The next Stone of Commune is near the Tablet of Vision that can be found south of Hunters Village. I remember the sweet whisper of temptation from the demon. A song with irresistible magic and no audience to listen to it. Find the next tablet now.
Исходник условий и наград (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.Q00072_SagaOfTheSwordMuse;

import quests.AbstractSagaQuest;

/**
 * @author Emperorc
 */
public class Q00072_SagaOfTheSwordMuse extends AbstractSagaQuest
{
	public Q00072_SagaOfTheSwordMuse()
	{
		super(72, "Saga of the Sword Muse");
		_npc = new int[]
		{
			30853,
			31624,
			31583,
			31537,
			31618,
			31646,
			31649,
			31652,
			31654,
			31655,
			31659,
			31281
		};
		_items = new int[]
		{
			7080,
			7536,
			7081,
			7487,
			7270,
			7301,
			7332,
			7363,
			7394,
			7425,
			7095,
			6482
		};
		_mob = new int[]
		{
			27288,
			27221,
			27280
		};
		_classId = new int[]
		{
			100
		};
		_prevClass = new int[]
		{
			0x15
		};
		_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));
			}
		}
	}
}