CODE |
using System; using System.Collections.Generic; using Server; using Server.Gumps; using Server.Items; using Server.Mobiles; using Server.Network; using Server.Targeting; using Server.Engines.XmlSpawner2; namespace Server.Items { public class NaturePen : Item { public static int Range = ( 5 ); public override double DefaultWeight { get { return 0.1; } } [Constructable] public NaturePen(int amount) : base(0x0FBF) { Stackable = false; Amount = amount; Name = "Irwin's Pen"; Hue = 2006; } public NaturePen( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int) 0 ); // version } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); } public override void OnDoubleClick( Mobile from ) { if ( from.InRange( GetWorldLocation(), Range ) ) { from.SendMessage ("Which creature do you wish to observe?"); from.Target = new InternalTarget( this ); } else { from.SendMessage("You must be closer to the creature in order to properly observe it."); } } private class InternalTarget : Target { private NaturePen m_NaturePen; public InternalTarget(NaturePen pen) : base(NaturePen.Range, false, TargetFlags.None) { m_NaturePen = pen; } protected override void OnTarget( Mobile from, object targeted ) { if ( m_NaturePen.Deleted ) return; if ( targeted is Mobile ) { if (from.InRange(m_NaturePen.GetWorldLocation(), NaturePen.Range)) { if (NaturePenContext.BeginNotes(from, (Mobile)targeted) != null) { if ((Mobile)targeted is PlayerMobile) { from.SendMessage("That person, although fascinating, is not a member of an endangered species."); } } } else { from.SendMessage("You must be closer to the creature in order to properly observe it."); } } else { from.SendMessage("You ponder it for a moment, but decide not to waste time taking any notes."); } } } } public class NaturePenContext { private Mobile m_Notetaker; private Mobile m_Targetcreature; private int m_Slips; private Timer m_Timer; public Mobile Notetaker{ get{ return m_Notetaker; } } public Mobile Targetcreature{ get{ return m_Targetcreature; } } public int Slips{ get{ return m_Slips; } set{ m_Slips = value; } } public Timer Timer{ get{ return m_Timer; } } public void Slip() { m_Notetaker.SendMessage("Your note-taking has been disturbed!"); ++m_Slips; } public NaturePenContext( Mobile notetaker, Mobile targetcreature, TimeSpan delay ) { m_Notetaker = notetaker; m_Targetcreature = targetcreature; m_Timer = new InternalTimer( this, delay ); m_Timer.Start(); } public void StopNotes() { m_Table.Remove( m_Notetaker ); if ( m_Timer != null ) m_Timer.Stop(); m_Timer = null; } private static Dictionary<Mobile, NaturePenContext> m_Table = new Dictionary<Mobile, NaturePenContext>(); public static NaturePenContext GetContext( Mobile notetaker ) { NaturePenContext bc = null; m_Table.TryGetValue( notetaker, out bc ); return bc; } public static SkillName GetPrimarySkill( Mobile m ) { return SkillName.Inscribe; } public static SkillName GetSecondarySkill( Mobile m ) { return SkillName.AnimalLore; } public void EndNotes() { StopNotes(); int notetakerNumber = -1, targetcreatureNumber = -1; bool playSound = true; bool checkSkills = false; SkillName primarySkill = GetPrimarySkill( m_Targetcreature ); SkillName secondarySkill = GetSecondarySkill( m_Targetcreature ); BaseCreature petTargetcreature = m_Targetcreature as BaseCreature; if ( !m_Notetaker.Alive ) { notetakerNumber = 500962; // You were unable to finish your work before you died. targetcreatureNumber = -1; playSound = false; } else if ( !m_Notetaker.InRange( m_Targetcreature, NaturePen.Range ) ) { m_Notetaker.SendMessage("You did not stay close enough to properly observe your target!"); targetcreatureNumber = -1; playSound = false; } else if (!m_Targetcreature.Alive) { m_Notetaker.SendMessage("You must observe and record the behaviors of a living creature!"); } else //if (creature from list one... repeat for the 4 other lists) { targetcreatureNumber = -1; double inscription = m_Notetaker.Skills[primarySkill].Value; double anatomy = m_Notetaker.Skills[secondarySkill].Value; double chance = ((inscription) / 100.0) - (m_Slips * 0.02); if (chance > Utility.RandomDouble()) { m_Notetaker.SendMessage("You successfully complete your observation of the creature!"); //TODO: Set a specific objective on a questholder to complete } else { switch (Utility.Random(4)) { case 0: m_Notetaker.SendMessage("Your notes are barely comprehensible. Try again, and this time aim for clarity and precision!"); playSound = false; break; case 1: m_Notetaker.SendMessage("Your drawing fails to capture the essence of the creature. Try again, and this time cast aside the constructs of your brain and draw what you see!"); playSound = false; break; case 2: m_Notetaker.SendMessage("Your writing lacks the detail necessary to truly capture the essence of the creature in words. Try again!"); playSound = false; break; case 3: m_Notetaker.SendMessage("You look over your notes and decide that further observation is necessary."); playSound = false; break; } } } if ( notetakerNumber != -1 ) m_Notetaker.SendLocalizedMessage( notetakerNumber ); if ( targetcreatureNumber != -1 ) m_Targetcreature.SendLocalizedMessage( targetcreatureNumber ); if ( playSound ) m_Targetcreature.PlaySound(0x249); // should be the writing noise if ( checkSkills ) { m_Notetaker.CheckSkill( secondarySkill, 0.0, 120.0 ); m_Notetaker.CheckSkill( primarySkill, 0.0, 120.0 ); } } private class InternalTimer : Timer { private NaturePenContext m_Context; public InternalTimer( NaturePenContext context, TimeSpan delay ) : base( delay ) { m_Context = context; Priority = TimerPriority.FiftyMS; } protected override void OnTick() { m_Context.EndNotes(); } } public static NaturePenContext BeginNotes( Mobile notetaker, Mobile targetcreature ) { bool isDeadPet = ( targetcreature is BaseCreature && ((BaseCreature)targetcreature).IsDeadPet ); if ( targetcreature is Golem ) { notetaker.SendMessage("You get the feeling that the tinkers of the world already have fairly extensive Golem documentation."); // NaturePens cannot be used on that. } else if ( targetcreature is BaseCreature && ((BaseCreature)targetcreature).IsAnimatedDead ) { notetaker.SendMessage("You wonder if the necromancers would appreciate your efforts and think the better of it."); } else { //bool onSelf = ( notetaker == targetcreature ); int dex = notetaker.Dex; double seconds; double resDelay = ( targetcreature.Alive ? 0.0 : 5.0 ); if ( dex >= 190 ) seconds = 10.0 + resDelay; else if ( dex >= 100 ) seconds = 15.0 + resDelay; else seconds = 20.0 + resDelay; NaturePenContext context = GetContext( notetaker ); if ( context != null ) context.StopNotes(); context = new NaturePenContext( notetaker, targetcreature, TimeSpan.FromSeconds( seconds ) ); m_Table[notetaker] = context; //if ( !onSelf ) //replace this with a flirty message //targetcreature.SendLocalizedMessage( 1008078, false, notetaker.Name ); // : Attempting to heal you. notetaker.SendMessage("You begin the record of your observations."); return context; } return null; } } } |
CODE |
XmlQuestHolder quest = (XmlQuestHolder ) BaseXmlSpawner.SearchMobileForItem(m_Notetaker, questname, "XmlQuestHolder" , false); |
CODE |
if(quest != null) quest.Completed1 = true; |
CODE |
using Server.Engines.XmlSpawner2; |