context: #region Header
  // **********
  // ServUO - Corpse.cs
  // **********
  #endregion
  
  #region References
  using System;
  using System.Collections.Generic;
  
  using Server.ContextMenus;
  using Server.Engines.PartySystem;
  using Server.Engines.Quests;
  using Server.Engines.Quests.Doom;
  using Server.Engines.Quests.Haven;
  using Server.Engines.XmlSpawner2;
  using Server.Guilds;
  using Server.Misc;
  using Server.Mobiles;
  using Server.Network;
  #endregion
  
  namespace Server.Items
  {
  	public interface IDevourer
  	{
  		bool Devour(Corpse corpse);
  	}
  
  	[Flags]
  	public enum CorpseFlag
  	{
  		None = 0x00000000,
  
  		/// <summary>
  		///     Has this corpse been carved?
  		/// </summary>
  		Carved = 0x00000001,
  
  		/// <summary>
  		///     If true, this corpse will not turn into bones
  		/// </summary>
  		NoBones = 0x00000002,
  
  		/// <summary>
  		///     If true, the corpse has turned into bones
  		/// </summary>
  		IsBones = 0x00000004,
  
  		/// <summary>
  		///     Has this corpse yet been visited by a taxidermist?
  		/// </summary>
  		VisitedByTaxidermist = 0x00000008,
  
  		/// <summary>
  		///     Has this corpse yet been used to channel spiritual energy? (AOS Spirit Speak)
  		/// </summary>
  		Channeled = 0x00000010,
  
  		/// <summary>
  		///     Was the owner criminal when he died?
  		/// </summary>
  		Criminal = 0x00000020,
  
  		/// <summary>
  		///     Has this corpse been animated?
  		/// </summary>
  		Animated = 0x00000040,
  
  		/// <summary>
  		///     Has this corpse been self looted?
  		/// </summary>
  		SelfLooted = 0x00000080,
  	}
  
  	public class Corpse : Container, ICarvable
  	{
  		private Mobile m_Owner; // Whos corpse is this?
  		private Mobile m_Killer; // Who killed the owner?
  		private CorpseFlag m_Flags; // @see CorpseFlag
  
  		private List<Mobile> m_Looters; // Who's looted this corpse?
  
  		private List<Item> m_EquipItems;
  						   // List of dropped equipment when the owner died. Ingame, these items display /on/ the corpse, not just inside
  
  		private List<Item> m_RestoreEquip; // List of items equipped when the owner died. Includes insured and blessed items.
  
  		private List<Mobile> m_Aggressors;
  							 // Anyone from this list will be able to loot this corpse; we attacked them, or they attacked us when we were freely attackable
  
  		private string m_CorpseName;
  					   // Value of the CorpseNameAttribute attached to the owner when he died -or- null if the owner had no CorpseNameAttribute; use "the remains of ~name~"
  
  		private IDevourer m_Devourer; // The creature that devoured this corpse
  
  		// For notoriety:
  		private AccessLevel m_AccessLevel; // Which AccessLevel the owner had when he died
  		private readonly Guild m_Guild; // Which Guild the owner was in when he died
  		private int m_Kills; // How many kills the owner had when he died
  
  		private DateTime m_TimeOfDeath; // What time was this corpse created?
  
  		private readonly HairInfo m_Hair; // This contains the hair of the owner
  		private readonly FacialHairInfo m_FacialHair; // This contains the facial hair of the owner
  
  		// For Forensics Evaluation
  		public string m_Forensicist; // Name of the first PlayerMobile who used Forensic Evaluation on the corpse
  
  		public static readonly TimeSpan MonsterLootRightSacrifice = TimeSpan.Zero;
  
  		public static readonly TimeSpan InstancedCorpseTime = TimeSpan.FromMinutes(3.0);
  
  		[CommandProperty(AccessLevel.GameMaster)]
  		public virtual bool InstancedCorpse
  		{
  			get
  			{
  				if (!Core.SE)
  				{
  					return false;
  				}
  
  				return (DateTime.UtcNow < (m_TimeOfDeath + InstancedCorpseTime));
  			}
  		}
  
  		private Dictionary<Item, InstancedItemInfo> m_InstancedItems;
  
  		private class InstancedItemInfo
  		{
  			private readonly Mobile m_Mobile;
  			private readonly Item m_Item;
  
  			public bool Perpetual { get; set; }
  
  			public InstancedItemInfo(Item i, Mobile m)
  			{
  				m_Item = i;
  				m_Mobile = m;
  			}
  
  			public bool IsOwner(Mobile m)
  			{
  				if (m_Item.LootType == LootType.Cursed) //Cursed Items are part of everyone's instanced corpse... (?)
  				{
  					return true;
  				}
  
  				if (m == null)
  				{
  					return false; //sanity
  				}
  
  				if (m_Mobile == m)
  				{
  					return true;
  				}
  
  				Party myParty = Party.Get(m_Mobile);
  
  				return (myParty != null && myParty == Party.Get(m));
  			}
  		}
  
  		public override bool IsChildVisibleTo(Mobile m, Item child)
  		{
  			if (!m.Player || m.IsStaff()) //Staff and creatures not subject to instancing.
  			{
  				return true;
  			}
  
  			if (m_InstancedItems != null)
  			{
  				InstancedItemInfo info;
  
  				if (m_InstancedItems.TryGetValue(child, out info) && (InstancedCorpse || info.Perpetual))
  				{
  					return info.IsOwner(m); //IsOwner checks Party stuff.
  				}
  			}
  
  			return true;
  		}
  
  		private void AssignInstancedLoot()
  		{
  			if (m_Aggressors.Count == 0 || Items.Count == 0)
  			{
  				return;
  			}
  
  			if (m_InstancedItems == null)
  			{
  				m_InstancedItems = new Dictionary<Item, InstancedItemInfo>();
  			}
  
  			var m_Stackables = new List<Item>();
  			var m_Unstackables = new List<Item>();
  
  			for (int i = 0; i < Items.Count; i++)
  			{
  				Item item = Items[i];
  
  				if (item.LootType != LootType.Cursed) //Don't have curesd items take up someone's item spot.. (?)
  				{
  					if (item.Stackable)
  					{
  						m_Stackables.Add(item);
  					}
  					else
  					{
  						m_Unstackables.Add(item);
  					}
  				}
  			}
  
  			var attackers = new List<Mobile>(m_Aggressors);
  
  			for (int i = 1; i < attackers.Count - 1; i++) //randomize
  			{
  				int rand = Utility.Random(i + 1);
  
  
gt: 				Mobile temp = attackers[rand];