context: using System;
  using System.Collections;
  using System.Collections.Generic;
  using Server.ContextMenus;
  using Server.Engines.XmlSpawner2;
  using Server.Items;
  using Server.Network;
  using CPA = Server.CommandPropertyAttribute;
  
  /*
  ** TalkingBaseCreature
  ** A mobile that can be programmed with branching conversational sequences that are advanced by keywords at each sequence point.
  **
  ** 2/10/05
  ** modified to use the XmlDialog attachment
  */
  namespace Server.Mobiles
  {
  	public class TalkingBaseCreature : BaseCreature
  	{ 
  
  		private XmlDialog m_DialogAttachment;
  
          
  		public XmlDialog DialogAttachment {get { return m_DialogAttachment; } set {m_DialogAttachment = value; }}
  
  		private DateTime lasteffect;		
  		private int m_EItemID = 0;  // 0 = disable, 14202 = sparkle, 6251 = round stone, 7885 = light pyramid
  		private int m_Duration = 70;
  		private Point3D m_Offset = new Point3D(0,0,20); // overhead
  		private int m_EHue = 68; // green
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int EItemID { 
  			get{ return m_EItemID; } 
  			set { 
  				m_EItemID = value; 
  			} 
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public Point3D EOffset 
  		{ 
  			get{ return m_Offset; } 
  			set 
  			{ 
  				m_Offset = value; 
  			} 
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int EDuration 
  		{ 
  			get{ return m_Duration; } 
  			set 
  			{ 
  				m_Duration = value; 
  			} 
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int EHue 
  		{ 
  			get{ return m_EHue; } 
  			set 
  			{ 
  				m_EHue = value; 
  			} 
  		}
  		public void DisplayHighlight()
  		{
  			if(EItemID > 0)
  			{
  				 //SendOffsetTargetEffect(this, new Point3D(Location.X + EOffset.X, Location.Y + EOffset.Y, Location.Z + EOffset.Z), EItemID, 10, EDuration, EHue, 0);
  				Effects.SendLocationEffect(new Point3D(Location.X + EOffset.X, Location.Y + EOffset.Y, Location.Z + EOffset.Z), Map, EItemID, EDuration, EHue, 0);
  
  				lasteffect = DateTime.UtcNow;
  
  			}
  		}
  
  		public static void SendOffsetTargetEffect( IEntity target, Point3D loc, int itemID, int speed, int duration, int hue, int renderMode )
  		{
  			if ( target is Mobile )
  				((Mobile)target).ProcessDelta();
  
  			Effects.SendPacket( loc, target.Map, new OffsetTargetEffect( target, loc, itemID, speed, duration, hue, renderMode ) );
  		}
  
  		public sealed class OffsetTargetEffect : HuedEffect
  		{
  			public OffsetTargetEffect(IEntity e, Point3D loc, int itemID, int speed, int duration, int hue, int renderMode)
  				: base(EffectType.FixedFrom, e.Serial, Serial.Zero, itemID, loc, loc, speed, duration, true, false, hue, renderMode)
  			{
  			}
  		}
  
  		public override void OnThink()
  		{
  			base.OnThink();
  
  			if(lasteffect + TimeSpan.FromSeconds(1) < DateTime.UtcNow)
  			{
  				DisplayHighlight();
  			}
  		}
          
  		public override bool Move( Direction d )
  		{
  			bool didmove = base.Move( d );
  
  			DisplayHighlight();
  
  			return didmove;
  		}
  
  		private string m_TalkText;
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public string TalkText {get{ return m_TalkText; } set { m_TalkText = value; }}
  
  		// properties below are modified to access the equivalent XmlDialog properties
  		// this is largely for backward compatibility, but it does also add some convenience
  
  		public Mobile ActivePlayer
  		{
  			get 
  			{
  				if(DialogAttachment != null)
  					return DialogAttachment.ActivePlayer;
  				else
  					return null;
  			}
  			set 
  			{
  				if(DialogAttachment != null)
  					DialogAttachment.ActivePlayer = value;
  			}
  		}
  
  		public ArrayList SpeechEntries 
  		{
  			get 
  			{
  				if(DialogAttachment != null)
  					return DialogAttachment.SpeechEntries;
  				else
  					return null;
  			}
  			set 
  			{
  				if(DialogAttachment != null)
  					DialogAttachment.SpeechEntries = value;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public TimeSpan GameTOD
  		{
  			get
  			{
  				int hours;
  				int minutes;
  
  				Clock.GetTime(this.Map, this.Location.X, this.Location.Y, out  hours, out  minutes);
  				return (new DateTime(DateTime.UtcNow.Year,DateTime.UtcNow.Month,DateTime.UtcNow.Day,hours, minutes,0).TimeOfDay);
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public TimeSpan RealTOD
  		{
  			get
  			{
  				return DateTime.UtcNow.TimeOfDay;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int RealDay
  		{
  			get
  			{
  				return DateTime.UtcNow.Day;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public int RealMonth
  		{
  			get
  			{
  				return DateTime.UtcNow.Month;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public DayOfWeek RealDayOfWeek
  		{
  			get
  			{
  				return DateTime.UtcNow.DayOfWeek;
  			}
  		}
  
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public MoonPhase MoonPhase
  		{
  			get
  			{
  				return Clock.GetMoonPhase( this.Map, this.Location.X, this.Location.Y );
  			}
  
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public AccessLevel TriggerAccessLevel 
  		{
  			get 
  			{
  				if(DialogAttachment != null)
  					return DialogAttachment.TriggerAccessLevel;
  				else
  					return AccessLevel.Player;
  			}
  			set 
  			{
  				if(DialogAttachment != null)
  					DialogAttachment.TriggerAccessLevel = value;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public DateTime LastInteraction 
  		{
  			get 
  			{
  				if(DialogAttachment != null)
  					return DialogAttachment.LastInteraction;
  				else
  					return DateTime.MinValue;
  			}
  			set 
  			{
  				if(DialogAttachment != null)
  					DialogAttachment.LastInteraction = value;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool DoReset 
  		{
  			get 
  			{
  					return false;
  			}
  			set 
  			{
  				if(DialogAttachment != null)
  					DialogAttachment.DoReset = value;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool IsActive 
  		{
  			get 
  			{
  				if(DialogAttachment != null)
  					return DialogAttachment.IsActive;
  				else
  					return false;
  			}
  			set 
  			{
  				if(DialogAttachment != null)
  					DialogAttachment.IsActive = value;
  			}
  		}
  
  		[CommandProperty( AccessLevel.GameMaster )]
  		public bool AllowGhostTrig 
  		{
  			get 
  			{
  				if(DialogAttachment != null)
  					return DialogAttachment.AllowGhostTrig;
  				else
  					return false;
  			}
  			set 
  			{
  				if(DialogAttachment != null)
  					DialogAttachment.AllowGhostTrig = value;
  			}
  		}
  
  
gt: 		[CommandProperty( AccessLevel.GameMaster )]