context: /*
   * DAWN OF LIGHT - The first free open source DAoC server emulator
   * 
   * 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 2
   * 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, write to the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
   *
   */
  /*
   * Author:		Gandulf Kohlweiss
   * Date:			
   * Directory: /scripts/quests/midgard/
   *
   * Description:
   *  Brief Walkthrough: 
   * 1) Travel to loc=41211,50221 Vale of Mularn to speak with Dalikor 
   * 2) Go to loc=44585,56194 Vale of Mularn and /use the Magical Wooden Box on the Fallen Askefruer when they appear. 
   * 3) Take the Full Magical Wooden Box back to Dalikor for your reward.
   */
  
  using System;
  using System.Reflection;
  using DOL.AI.Brain;
  using DOL.Database;
  using DOL.Events;
  using DOL.GS.PacketHandler;
  using log4net;
  /* I suggest you declare yourself some namespaces for your quests
   * Like: DOL.GS.Quests.Albion
   *       DOL.GS.Quests.Midgard
   *       DOL.GS.Quests.Hibernia
   * Also this is the name that will show up in the database as QuestName
   * so setting good values here will result in easier to read and cleaner
   * Database Code
   */
  
  namespace DOL.GS.Quests.Midgard
  {
  	/* The first thing we do, is to declare the class we create
  	 * as Quest. To do this, we derive from the abstract class
  	 * AbstractQuest
  	 * 	 
  	 */
  
  	public class Nuisances : BaseDalikorQuest
  	{
  		/// <summary>
  		/// Defines a logger for this class.
  		/// </summary>
  		private static readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  
  		/* Declare the variables we need inside our quest.
  		 * You can declare static variables here, which will be available in 
  		 * ALL instance of your quest and should be initialized ONLY ONCE inside
  		 * the OnScriptLoaded method.
  		 * 
  		 * Or declare nonstatic variables here which can be unique for each Player
  		 * and change through the quest journey...
  		 * 
  		 */
  		protected const string questTitle = "Nuisances (Mid)";
  		protected const int minimumLevel = 2;
  		protected const int maximumLevel = 2;
  
  		private static GameNPC dalikor = null;
  		private GameNPC askefruer = null;
  
  		private static GameLocation askefruerLocation = new GameLocation("Fallen Askefruer", 100, 100, 44585, 56194, 4780, 294);
  		private static IArea askefruerArea = null;
  
  		private static ItemTemplate emptyMagicBox = null;
  		private static ItemTemplate fullMagicBox = null;
  		private static ItemTemplate recruitsShortSword = null;
  		private static ItemTemplate recruitsStaff = null;
  
  
  		/* We need to define the constructors from the base class here, else there might be problems
  		 * when loading this quest...
  		 */
  
  		public Nuisances() : base()
  		{
  		}
  
  		public Nuisances(GamePlayer questingPlayer) : this(questingPlayer, 1)
  		{
  		}
  
  		public Nuisances(GamePlayer questingPlayer, int step) : base(questingPlayer, step)
  		{
  		}
  
  		public Nuisances(GamePlayer questingPlayer, DBQuest dbQuest) : base(questingPlayer, dbQuest)
  		{
  		}
  
  
  		/* The following method is called automatically when this quest class
  		 * is loaded. You might notice that this method is the same as in standard
  		 * game events. And yes, quests basically are game events for single players
  		 * 
  		 * To make this method automatically load, we have to declare it static
  		 * and give it the [ScriptLoadedEvent] attribute. 
  		 *
  		 * Inside this method we initialize the quest. This is neccessary if we 
  		 * want to set the quest hooks to the NPCs.
  		 * 
  		 * If you want, you can however add a quest to the player from ANY place
  		 * inside your code, from events, from custom items, from anywhere you
  		 * want. 
  		 */
  
  		[ScriptLoadedEvent]
  		public static void ScriptLoaded(DOLEvent e, object sender, EventArgs args)
  		{
  			if (!ServerProperties.Properties.LOAD_QUESTS)
  				return;
  			if (log.IsInfoEnabled)
  				log.Info("Quest \"" + questTitle + "\" initializing ...");
  			/* First thing we do in here is to search for the NPCs inside
  				* the world who comes from the Albion realm. If we find a the players,
  				* this means we don't have to create a new one.
  				* 
  				* NOTE: You can do anything you want in this method, you don't have
  				* to search for NPC's ... you could create a custom item, place it
  				* on the ground and if a player picks it up, he will get the quest!
  				* Just examples, do anything you like and feel comfortable with :)
  				*/
  
  			#region defineNPCs
  
  			dalikor = GetDalikor();
  
  			#endregion
  
  			#region defineItems 
  
  			// item db check
  			emptyMagicBox = GameServer.Database.FindObjectByKey<ItemTemplate>("empty_wodden_magic_box");
  			if (emptyMagicBox == null)
  			{
  				if (log.IsWarnEnabled)
  					log.Warn("Could not find Empty Wodden Magic Box, creating it ...");
  				emptyMagicBox = new ItemTemplate();
  				emptyMagicBox.Name = "Empty Wodden Magic Box";
  
  				emptyMagicBox.Weight = 5;
  				emptyMagicBox.Model = 602;
  
  				emptyMagicBox.Object_Type = (int) eObjectType.GenericItem;
  				emptyMagicBox.Id_nb = "empty_wodden_magic_box";
  
  				emptyMagicBox.IsPickable = true;
  				emptyMagicBox.IsDropable = false;
  
  				//You don't have to store the created item in the db if you don't want,
  				//it will be recreated each time it is not found, just comment the following
  				//line if you rather not modify your database
  				if (SAVE_INTO_DATABASE)
  					GameServer.Database.AddObject(emptyMagicBox);
  			}
  
  			// item db check
  			fullMagicBox = GameServer.Database.FindObjectByKey<ItemTemplate>("full_wodden_magic_box");
  			if (fullMagicBox == null)
  			{
  				if (log.IsWarnEnabled)
  					log.Warn("Could not find Full Wodden Magic Box, creating it ...");
  				fullMagicBox = new ItemTemplate();
  				fullMagicBox.Name = "Full Wodden Magic Box";
  
  				fullMagicBox.Weight = 3;
  				fullMagicBox.Model = 602;
  
  				fullMagicBox.Object_Type = (int) eObjectType.GenericItem;
  
  				fullMagicBox.Id_nb = "full_wodden_magic_box";
  				fullMagicBox.IsPickable = true;
  				fullMagicBox.IsDropable = false;
  
  				//You don't have to store the created item in the db if you don't want,
  				//it will be recreated each time it is not found, just comment the following
  				//line if you rather not modify your database
  				if (SAVE_INTO_DATABASE)
  					GameServer.Database.AddObject(fullMagicBox);
  			}
  
  			// item db check
  			recruitsShortSword = GameServer.Database.FindObjectByKey<ItemTemplate>("recruits_short_sword_mid");
  			if (recruitsShortSword == null)
  			{
  				recruitsShortSword = new ItemTemplate();
  				recruitsShortSword.Name = "Recruit's Short Sword (Mid)";
  				if (log.IsWarnEnabled)
  					log.Warn("Could not find " + recruitsShortSword.Name + ", creating it ...");
  				recruitsShortSword.Level = 4;
  
  				recruitsShortSword.Weight = 18;
  				recruitsShortSword.Model = 3; // studded Boots
  
  				recruitsShortSword.DPS_AF = 23; // Armour
  				recruitsShortSword.SPD_ABS = 30; // Absorption
  
  				recruitsShortSword.Type_Damage = (int) eDamageType.Slash;
  				recruitsShortSword.Object_Type = (int) eObjectType.Sword;
  				recruitsShortSword.Item_Type = (int) eEquipmentItems.LEFT_HAND;
  				recruitsShortSword.Id_nb = "recruits_short_sword_mid";
  				recruitsShortSword.Price = Money.GetMoney(0,0,0,2,0);
  				recruitsShortSword.IsPickable = true;
  				recruitsShortSword.IsDropable = true;
  				recruitsShortSword.Color = 61;
  
  				recruitsShortSword.Bonus = 1; // default bonus
  
  				recruitsShortSword.Bonus1 = 3;
  				recruitsShortSword.Bonus1Type = (int) eStat.STR;
  
  				recruitsShortSword.Bonus2 = 1;
  				recruitsShortSword.Bonus2Type = (int) eResist.Body;
  
  				recruitsShortSword.Quality = 100;
  				recruitsShortSword.Condition = 1000;
  				recruitsShortSword.MaxCondition = 1000;
  				recruitsShortSword.Durability = 1000;
  				recruitsShortSword.MaxDurability = 1000;
  
  				//You don't have to store the created item in the db if you don't want,
  				//it will be recreated each time it is not found, just comment the following
  				//line if you rather not modify your database
  				if (SAVE_INTO_DATABASE)
  					GameServer.Database.AddObject(recruitsShortSword);
  			}
  
  			// item db check
  			recruitsStaff = GameServer.Database.FindObjectByKey<ItemTemplate>("recruits_staff");
  			if (recruitsStaff == null)
  			{
  				recruitsStaff = new ItemTemplate();
  				recruitsStaff.Name = "Recruit's Staff";
  				if (log.IsWarnEnabled)
  					log.Warn("Could not find " + recruitsStaff.Name + ", creating it ...");
  				recruitsStaff.Level = 4;
  
  				recruitsStaff.Weight = 45;
  				recruitsStaff.Model = 442;
  
  				recruitsStaff.DPS_AF = 24;
  				recruitsStaff.SPD_ABS = 45;
  
  				recruitsStaff.Type_Damage = (int) eDamageType.Slash;
  				recruitsStaff.Object_Type = (int) eObjectType.Staff;
  				recruitsStaff.Item_Type = (int) eEquipmentItems.LEFT_HAND;
  				recruitsStaff.Id_nb = "recruits_staff";
  				recruitsStaff.Price = Money.GetMoney(0,0,0,2,0);
  				recruitsStaff.IsPickable = true;
  				recruitsStaff.IsDropable = true;
  				recruitsStaff.Color = 61;
  
  				recruitsStaff.Bonus = 1; // default bonus
  
  				recruitsStaff.Bonus1 = 3;
  				recruitsStaff.Bonus1Type = (int) eStat.INT;
  
  				recruitsStaff.Bonus2 = 1;
  				recruitsStaff.Bonus2Type = (int) eResist.Crush;
  
  				recruitsStaff.Quality = 100;
  				recruitsStaff.Condition = 1000;
  				recruitsStaff.MaxCondition = 1000;
  				recruitsStaff.Durability = 1000;
  				recruitsStaff.MaxDurability = 1000;
  
  				//You don't have to store the created item in the db if you don't want,
  				//it will be recreated each time it is not found, just comment the following
  				//line if you rather not modify your database
  				if (SAVE_INTO_DATABASE)
  					GameServer.Database.AddObject(recruitsStaff);
  			}
  
  			#endregion
  
  			askefruerArea = WorldMgr.GetRegion(askefruerLocation.RegionID).AddArea(new Area.Circle("Askefruer contamined Area", askefruerLocation.X, askefruerLocation.Y, 0, 1500));
  			askefruerArea.RegisterPlayerEnter(new DOLEventHandler(PlayerEnterAskefruerArea));
  
  			/* Now we add some hooks to the npc we found.
  			* Actually, we want to know when a player interacts with him.
  			* So, we hook the right-click (interact) and the whisper method
  			* of npc and set the callback method to the "TalkToXXX"
  			* method. This means, the "TalkToXXX" method is called whenever
  			* a player right clicks on him or when he whispers to him.
  			*/
  			//We want to be notified whenever a player enters the world
  			GameEventMgr.AddHandler(GamePlayerEvent.AcceptQuest, new DOLEventHandler(SubscribeQuest));
  			GameEventMgr.AddHandler(GamePlayerEvent.DeclineQuest, new DOLEventHandler(SubscribeQuest));
  
  			GameEventMgr.AddHandler(GamePlayerEvent.GameEntered, new DOLEventHandler(PlayerEnterWorld));
  
  			GameEventMgr.AddHandler(dalikor, GameLivingEvent.Interact, new DOLEventHandler(TalkToDalikor));
  			GameEventMgr.AddHandler(dalikor, GameLivingEvent.WhisperReceive, new DOLEventHandler(TalkToDalikor));
  
  			/* Now we bring to dalikor the possibility to give this quest to players */
  			dalikor.AddQuestToGive(typeof (Nuisances));
  
  			if (log.IsInfoEnabled)
  				log.Info("Quest \"" + questTitle + "\" initialized");
  		}
  
  		/* The following method is called automatically when this quest class
  		 * is unloaded. 
  		 * 
  		 * Since we set hooks in the load method, it is good practice to remove
  		 * those hooks again!
  		 */
  
  		[ScriptUnloadedEvent]
  		public static void ScriptUnloaded(DOLEvent e, object sender, EventArgs args)
  		{
  			/* If sirQuait has not been initialized, then we don't have to remove any
  			 * hooks from him ;-)
  			 */
  			if (dalikor == null)
  				return;
  
  			askefruerArea.UnRegisterPlayerEnter(new DOLEventHandler(PlayerEnterAskefruerArea));
  			WorldMgr.GetRegion(askefruerLocation.RegionID).RemoveArea(askefruerArea);
  
  			/* Removing hooks works just as adding them but instead of 
  			 * AddHandler, we call RemoveHandler, the parameters stay the same
  			 */
  			GameEventMgr.RemoveHandler(GamePlayerEvent.AcceptQuest, new DOLEventHandler(SubscribeQuest));
  			GameEventMgr.RemoveHandler(GamePlayerEvent.DeclineQuest, new DOLEventHandler(SubscribeQuest));
  
  			GameEventMgr.RemoveHandler(GamePlayerEvent.GameEntered, new DOLEventHandler(PlayerEnterWorld));
  
  			GameEventMgr.RemoveHandler(dalikor, GameLivingEvent.Interact, new DOLEventHandler(TalkToDalikor));
  			GameEventMgr.RemoveHandler(dalikor, GameLivingEvent.WhisperReceive, new DOLEventHandler(TalkToDalikor));
  		
  			/* Now we remove to dalikor the possibility to give this quest to players */
  			dalikor.RemoveQuestToGive(typeof (Nuisances));
  		}
  
  		protected static void PlayerLeftWorld(DOLEvent e, object sender, EventArgs args)
  		{
  			GamePlayer player = sender as GamePlayer;
  
gt: 			if (player == null)