So I'm terrible with timers, for some reason or another, I always end up in circles. Here is my Flight Item, I use this instead of the traditional methods to active flight for a gargoyle, I would like to cause this effect to it.

Start Flight Item (Double Click),
Flight permitted for up to 15 minutes, then force land if 15 minute timer is reached.

If gargoyle toon lands, start counting back the timer to add more flight time.

So basically trying to implement the idea of rest for flight.

Any suggestion to get the above effects?

Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;

namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
        }
           
       
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
               
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
               
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
               
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
               
                else
                {
                    from.Freeze(TimeSpan.FromSeconds(1));
                    from.RevealingAction();
                    from.Animate(60, 10, 1, true, false, 0);
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                    from.Flying = true;
                    BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                }

            }
           
            else
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
            }
        }
       
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
       

        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);

            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }

                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }

        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);

            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }

                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }

        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);

            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }

                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
       

    public FlightItem( 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();
    }
}
}
 
Try this out. It is untested, but might get you close. I put a debugger in there to notify you every 10 seconds how much time is left on the timer. To activate that you need to run the server in Debug mode.

Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
            m_TimeLeft = 900;
            m_Timer.Start();
        }
       
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; } }
       
        private FlightTimer m_Timer;
      
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
              
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
              
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
              
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
              
                else
                {
                    ToggleFlight(true);
                }
            }
          
            else
            {
                ToggleFlight(false);
            }
        }
       
        public void ToggleFlight(bool turnon)
        {
            if (turnon)
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(60, 10, 1, true, false, 0);
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                from.Flying = true;
                BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                m_Timer.Start();
            }
            else
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
            }
        }

        private class FlightTimer : Timer
        {
            private readonly Mobile m;
            private FlightItem fi;

            public FlightTimer(Mobile from, FlightItem item)
                : base(0)
            {
                m = from;
                fi = item;
                Priority = TimerPriority.OneSecond;
            }

            protected override void OnTick()
            {
                if (Core.Debug && fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
                if (m.Flying)
                {
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
                        m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
        }
      
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
      
        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
      
        public FlightItem( 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();
        }
    }
}
 
Oh, also, I did not serialize any of the new variables, so nothing will be saved over a server restart. If you want to add that, just serialize the TimeLeft integer.
 
Just got back from bear lake, I will give it a run tonight
[doublepost=1469420578][/doublepost]So I ran Into some compile errors.

First error was
Code:
Errors:
+ ALFheim/Items/FlightItem2.cs:
    CS0103: Line 93: The name 'from' does not exist in the current context
    CS0103: Line 94: The name 'from' does not exist in the current context
    CS0103: Line 95: The name 'from' does not exist in the current context
    CS0103: Line 96: The name 'from' does not exist in the current context
    CS0103: Line 97: The name 'from' does not exist in the current context
    CS0103: Line 98: The name 'from' does not exist in the current context
    CS1502: Line 108: The best overloaded method match for 'Server.Timer.Timer(System.TimeSpan)' has some invalid arguments
    CS1503: Line 108: Argument 1: cannot convert from 'int' to 'System.TimeSpan'
Scripts: One or more scripts failed to compile or no script files were found.
- Press return to exit, or R to try again.

So I added

Code:
Mobile from;
To define from as Mobile.

Then I got this compile error
Code:
Errors:
+ ALFheim/Items/FlightItem2.cs:
    CS0165: Line 83: Use of unassigned local variable 'from'
    CS0165: Line 94: Use of unassigned local variable 'from'
    CS1502: Line 109: The best overloaded method match for 'Server.Timer.Timer(System.TimeSpan)' has some invalid arguments
    CS1503: Line 109: Argument 1: cannot convert from 'int' to 'System.TimeSpan'
Scripts: One or more scripts failed to compile or no script files were found.
- Press return to exit, or R to try again.

Here is the current script with the above changes with the reference Mobile from; included.
Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
            m_TimeLeft = 900;
            m_Timer.Start();
        }
      
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; } }
      
        private FlightTimer m_Timer;
    
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
            
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
            
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
            
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
            
                else
                {
                    ToggleFlight(true);
                }
            }
        
            else
            {
                ToggleFlight(false);
            }
        }
      
        public void ToggleFlight(bool turnon)
        {
           
            if (turnon)
            {
                Mobile from;
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(60, 10, 1, true, false, 0);
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                from.Flying = true;
                BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                m_Timer.Start();
            }
            else
            {
                Mobile from;
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
            }
        }
        private class FlightTimer : Timer
        {
            private readonly Mobile m;
            private FlightItem fi;
            public FlightTimer(Mobile from, FlightItem item)
                : base(0)
            {
                m = from;
                fi = item;
                Priority = TimerPriority.OneSecond;
            }
            protected override void OnTick()
            {
                if (Core.Debug && fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
                if (m.Flying)
                {
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
                        m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
        }
    
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
    
        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
    
        public FlightItem( 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();
        }
    }
}
 
We need the mobile carried over from the other parts of the script, so change the definition:

public void ToggleFlight(bool turnon, Mobile from)

and take the Mobile from; out of the method itself.

Next, in the other places where we call "ToggleFlight" we need to add the mobile to the parameters passed.

Like: ToggleFlight(true, from)

or ToggleFlight(false, m)

or whatever makes sense in that context.
 
Made the suggested changes, last compile error.

Code:
Errors:
 + ALFheim/Items/FlightItem.cs:
  CS1502: Line 106: The best overloaded method match for 'Server.Timer.Timer(System.TimeSpan)' has some invalid arguments
  CS1503: Line 106: Argument 1: cannot convert from 'int' to 'System.TimeSpan'
Scripts: One or more scripts failed to compile or no script files were found.
 - Press return to exit, or R to try again.

Here is the code
Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
  public class FlightItem : Item
  {
  [Constructable]
  public FlightItem() : base( 0x5726 )
  {
  Movable = true;
  Weight = 0.0;
  Name = "Toggle Flight";
  LootType = LootType.Blessed;
  Hue = 6;
  m_TimeLeft = 900;
  m_Timer.Start();
  }
   
  private int m_TimeLeft;
  public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; } }
   
  private FlightTimer m_Timer;
   
  public override void OnDoubleClick( Mobile from )
  {
  if (from.Flying == false)
  {
  BlockMountType type = BaseMount.GetMountPrevention(from);
   
  if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
  {
  from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
  }
   
  else if (!from.Alive)
  {
  from.SendMessage("You may not fly while dead."); // You may not fly while dead.
  }
   
  else if (type != BlockMountType.None)
  {
  switch (type)
  {
  case BlockMountType.Dazed:
  from.SendMessage("You are still too dazed to fly.");
  break; // You are still too dazed to fly.
  case BlockMountType.BolaRecovery:
  from.SendMessage("You cannot fly while recovering from a bola throw.");
  break; // You cannot fly while recovering from a bola throw.
  case BlockMountType.DismountRecovery:
  from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
  break; // You cannot fly while recovering from a dismount maneuver.
  }
  return;
  }
   
  else
  {
  ToggleFlight(true, from);
  }
  }
   
  else
  {
  ToggleFlight(false, from);
  }
  }
   
  public void ToggleFlight(bool turnon, Mobile from)
  {
  if (turnon)
  {
  from.Freeze(TimeSpan.FromSeconds(1));
  from.RevealingAction();
  from.Animate(60, 10, 1, true, false, 0);
  from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
  from.Flying = true;
  BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
  m_Timer.Start();
  }
  else
  {
  from.Freeze(TimeSpan.FromSeconds(1));
  from.RevealingAction();
  from.Animate(61, 10, 1, true, false, 0);
  BuffInfo.RemoveBuff(from, BuffIcon.Fly);
  from.Flying = false;
  from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
  }
  }
  private class FlightTimer : Timer
  {
  private readonly Mobile m;
  private FlightItem fi;
  public FlightTimer(Mobile from, FlightItem item)
  : base(0)
  {
  m = from;
  fi = item;
  Priority = TimerPriority.OneSecond;
  }
  protected override void OnTick()
  {
  if (Core.Debug && fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
  if (m.Flying)
  {
  fi.TimeLeft--;
  if (fi.TimeLeft <= 0)
  {
  fi.ToggleFlight(false, m);
  }
  }
  else
  {
  fi.TimeLeft++;
  if (fi.TimeLeft >= 900)
  {
  m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
  this.Stop();
  }
  }
  }
  }
   
  public virtual bool Accepted
  {
  get
  {
  return this.Deleted;
  }
  }
   
  public override bool DropToWorld(Mobile from, Point3D p)
  {
  bool ret = base.DropToWorld(from, p);
  if (ret && !this.Accepted && this.Parent != from.Backpack)
  {
  if (from.IsStaff())
  {
  return true;
  }
  else
  {
  from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
  return false;
  }
  }
  else
  {
  return ret;
  }
  }
  public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
  {
  bool ret = base.DropToMobile(from, target, p);
  if (ret && !this.Accepted && this.Parent != from.Backpack)
  {
  if (from.IsStaff())
  {
  return true;
  }
  else
  {
  from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
  return false;
  }
  }
  else
  {
  return ret;
  }
  }
  public override bool DropToItem(Mobile from, Item target, Point3D p)
  {
  bool ret = base.DropToItem(from, target, p);
  if (ret && !this.Accepted && this.Parent != from.Backpack)
  {
  if (from.IsStaff())
  {
  return true;
  }
  else
  {
  from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
  return false;
  }
  }
  else
  {
  return ret;
  }
  }
   
  public FlightItem( 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();
  }
  }
}
 
Getting closer.. lol

This time it compiled but as soon as I tried using the item the server crashed.

Code:
Server Crash Report
===================

RunUO Version 0.5, Build 6050.23834
Operating System: Microsoft Windows NT 6.2.9200.0
.NET Framework: 4.0.30319.42000
Time: 7/25/2016 3:54:36 PM
Mobiles: 4748
Items: 121433
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at Server.Items.FlightItem.ToggleFlight(Boolean turnon, Mobile from)
   at Server.Items.FlightItem.OnDoubleClick(Mobile from)
   at Server.Mobile.Use(Item item) in k:\AlfheimRebornServer\Ultima Server\Server\Mobile.cs:line 4478
   at Server.Engines.XmlSpawner2.XmlAttach.UseReq(NetState state, PacketReader pvSrc)
   at Server.Network.MessagePump.HandleReceive(NetState ns) in k:\AlfheimRebornServer\Ultima Server\Server\Network\MessagePump.cs:line 187
   at Server.Network.MessagePump.Slice() in k:\AlfheimRebornServer\Ultima Server\Server\Network\MessagePump.cs:line 121
   at Server.Core.Main(String[] args) in k:\AlfheimRebornServer\Ultima Server\Server\Main.cs:line 577
[doublepost=1469483906][/doublepost]Also to note I tested it on a item of that type that already existed, thats when it crashed. I booted the server back up again and tried adding a new FlightItem and it would not add it, stated Flight Item , Usage. when trying to add.
 
Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
            m_TimeLeft = 900;
            m_Timer.Start();
        }
      
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; } }
      
        private FlightTimer m_Timer;
    
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
            
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
            
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
            
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
            
                else
                {
                    ToggleFlight(true, from);
                }
            }
        
            else
            {
                ToggleFlight(false, from);
            }
        }
      
        public void ToggleFlight(bool turnon, Mobile from)
        {
            if (turnon)
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(60, 10, 1, true, false, 0);
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                from.Flying = true;
                BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                m_Timer.Start();
            }
            else
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
            }
        }
        private class FlightTimer : Timer
        {
            private readonly Mobile m;
            private FlightItem fi;
            public FlightTimer(Mobile from, FlightItem item)
                : base(TimeSpan.FromSeconds(0))
            {
                m = from;
                fi = item;
                Priority = TimerPriority.OneSecond;
            }
            protected override void OnTick()
            {
                if (Core.Debug && fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
                if (m.Flying)
                {
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false, m);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
                        m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
        }
    
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
    
        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
    
        public FlightItem( 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();
        }
    }
}
 
Try this:

Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
            m_TimeLeft = 900;
        }
    
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; } }
    
        private FlightTimer m_Timer;
  
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
          
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
          
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
          
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
          
                else
                {
                    ToggleFlight(true, from);
                }
            }
      
            else
            {
                ToggleFlight(false, from);
            }
        }
    
        public void ToggleFlight(bool turnon, Mobile from)
        {
            if (turnon)
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(60, 10, 1, true, false, 0);
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                from.Flying = true;
                BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                if (m_Timer == null) m_Timer = new FlightTimer(from, this);
                if (m_Timer.Stopped) m_Timer.Start();
            }
            else
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
                if (m_Timer == null) m_Timer = new FlightTimer(from, this);
                if (m_Timer.Stopped) m_Timer.Start();
            }
        }
        private class FlightTimer : Timer
        {
            private readonly Mobile m;
            private FlightItem fi;
            public FlightTimer(Mobile from, FlightItem item)
                : base(TimeSpan.FromSeconds(0))
            {
                m = from;
                fi = item;
                Priority = TimerPriority.OneSecond;
            }
            protected override void OnTick()
            {
                if (Core.Debug && fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
                if (m.Flying)
                {
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false, m);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
                        m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
        }
  
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
  
        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
  
        public FlightItem( 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();
        }
    }
}
 
This time it did not compile but we got this error. Seems we just need to define 'Stopped' .

Code:
Errors:
+ ALFheim/Items/FlightItem.cs:
    CS1061: Line 87: 'Server.Items.FlightItem.FlightTimer' does not contain a definition for 'Stopped' and no extension method 'Stopped' accepting a first argument of type 'Server.Items.FlightItem.FlightTimer' could be found (are you missing a using directive or an assembly reference?)
    CS1061: Line 98: 'Server.Items.FlightItem.FlightTimer' does not contain a definition for 'Stopped' and no extension method 'Stopped' accepting a first argument of type 'Server.Items.FlightItem.FlightTimer' could be found (are you missing a using directive or an assembly reference?)
Scripts: One or more scripts failed to compile or no script files were found.
- Press return to exit, or R to try again.
 
OK, so all of this is coming off the cuff with little reference to a server. Just checked the server, and I guess the correct method is "Running", so we want the reverse, so we have to use the "!" (not) symbol, so change both of those lines to this:

if (!m_Timer.Running) m_Timer.Start();
 
Sweet, no errors and no crashes. Now it's time to see how this works out.
[doublepost=1469498586][/doublepost]so after testing. Started Flight, waited about 10 minutes, landed and took off again, still says you've reached your maximum of 15 minutes charge time, so I left it flying for 30 minutes and never forced me to land, landed and still got the same message. So it seems the timer isn't effective in this case.

Current Script
Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
            m_TimeLeft = 900;
        }
  
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; } }
  
        private FlightTimer m_Timer;
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
        
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
        
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
        
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
        
                else
                {
                    ToggleFlight(true, from);
                }
            }
    
            else
            {
                ToggleFlight(false, from);
            }
        }
  
        public void ToggleFlight(bool turnon, Mobile from)
        {
            if (turnon)
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(60, 10, 1, true, false, 0);
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                from.Flying = true;
                BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                if (m_Timer == null) m_Timer = new FlightTimer(from, this);
                if (!m_Timer.Running) m_Timer.Start();
            }
            else
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
                if (m_Timer == null) m_Timer = new FlightTimer(from, this);
                if (!m_Timer.Running) m_Timer.Start();
            }
        }
        private class FlightTimer : Timer
        {
            private readonly Mobile m;
            private FlightItem fi;
            public FlightTimer(Mobile from, FlightItem item)
                : base(TimeSpan.FromSeconds(0))
            {
                m = from;
                fi = item;
                Priority = TimerPriority.OneSecond;
            }
            protected override void OnTick()
            {
                if (Core.Debug && fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
                if (m.Flying)
                {
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false, m);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
                        m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
        }
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public FlightItem( 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();
        }
    }
}
 
OK. I actually fired up my server to test this one. Works fine. It alerts you every 10 seconds how much charge is left, both while using it, and while resting. If you want to remove that, just comment out that line.

Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
            m_TimeLeft = 900;
        }
    
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; } }
    
        private FlightTimer m_Timer;
  
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
          
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
          
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
          
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
          
                else
                {
                    ToggleFlight(true, from);
                }
            }
      
            else
            {
                ToggleFlight(false, from);
            }
        }
    
        public void ToggleFlight(bool turnon, Mobile from)
        {
            if (turnon)
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(60, 10, 1, true, false, 0);
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                from.Flying = true;
                BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                if (m_Timer != null)
                    m_Timer.Stop();
                m_Timer = new FlightTimer(from, this);
                m_Timer.Start();
            }
            else
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
                if (m_Timer != null)
                    m_Timer.Stop();
                m_Timer = new FlightTimer(from, this);
                m_Timer.Start();
            }
        }
        private class FlightTimer : Timer
        {
            private readonly Mobile m;
            private FlightItem fi;
            public FlightTimer(Mobile from, FlightItem item)
                : base(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1), 900)
            {
                m = from;
                fi = item;
                Priority = TimerPriority.EveryTick;
            }
            protected override void OnTick()
            {
                if (fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
                if (m.Flying)
                {
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false, m);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
                        m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
        }
  
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
  
        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
  
        public FlightItem( 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();
        }
    }
}
 
I would add the following:

  • Check inside the timer OnTick method to make sure that fl is not null and has not been deleted:
    • if (fi == null || fi.Deleted) Stop();
  • Perhaps instead of sending the player a message, it would set a name property on the FlightItem that would indicate how many seconds or minutes are left of available Flight Time.
 
Added in the suggestion above and tested, its working ! :) now that is awesome. I will see if I can figure out the proper list code to show the time remaining on the item itself
[doublepost=1469549088][/doublepost]I added the name property to show the time left however the item time doesn't update unless you drag the item around in the backpack and drop it.

Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
            m_TimeLeft = 900;
        }
  
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; } }
  
        private FlightTimer m_Timer;
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
        
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
        
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
        
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
        
                else
                {
                    ToggleFlight(true, from);
                }
            }
    
            else
            {
                ToggleFlight(false, from);
            }
        }
  
        public void ToggleFlight(bool turnon, Mobile from)
        {
            if (turnon)
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(60, 10, 1, true, false, 0);
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                from.Flying = true;
                BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                if (m_Timer != null)
                    m_Timer.Stop();
                m_Timer = new FlightTimer(from, this);
                m_Timer.Start();
            }
            else
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
                if (m_Timer != null)
                    m_Timer.Stop();
                m_Timer = new FlightTimer(from, this);
                m_Timer.Start();
            }
        }
        private class FlightTimer : Timer
        {
            private readonly Mobile m;
            private FlightItem fi;
            public FlightTimer(Mobile from, FlightItem item)
                : base(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1), 900)
            {
                m = from;
                fi = item;
                Priority = TimerPriority.EveryTick;
            }
            protected override void OnTick()
            {
                if (fi == null || fi.Deleted) Stop();
                if (fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
                if (m.Flying)
                {
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false, m);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
                        m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
        }
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
       
        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);
            list.Add("<BASEFONT COLOR=#7FCAE7>Time Remaining: {0}<BASEFONT COLOR=#17FF01>", m_TimeLeft.ToString());
        }
        public FlightItem( 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();
        }
    }
}
[doublepost=1469553053][/doublepost]I fixed the timer. around line 26 I changed this, and added InvalidateProperties

Code:
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; InvalidateProperties(); } }
[doublepost=1469555134][/doublepost]Here is the completed script with the serial and deserialization added and the above fix to the timer display. Tested this out in a few different scenario's, this meets what I was looking for. Thank you for your help Lokai :)

Code:
using System;
using Server;
using Server.Multis;
using Server.Network;
using Server.Items;
using Server.Spells;
using Server.Targeting;
using Server.Commands;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Items
{
    public class FlightItem : Item
    {
        [Constructable]
        public FlightItem() : base( 0x5726 )
        {
            Movable = true;
            Weight = 0.0;
            Name = "Toggle Flight";
            LootType = LootType.Blessed;
            Hue = 6;
            m_TimeLeft = 900;
        }
  
        private int m_TimeLeft;
        public int TimeLeft { get{ return m_TimeLeft; } set { m_TimeLeft = value; InvalidateProperties(); } }
  
        private FlightTimer m_Timer;
        public override void OnDoubleClick( Mobile from )
        {
            if (from.Flying == false)
            {
                BlockMountType type = BaseMount.GetMountPrevention(from);
        
                if (from.IsBodyMod && !(from.BodyMod == 666 || from.BodyMod == 667))
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You can't fly in your current form!"); // You can't fly in your current form!
                }
        
                else if (!from.Alive)
                {
                     from.SendMessage("You may not fly while dead."); // You may not fly while dead.
                }
        
                else if (type != BlockMountType.None)
                {
                    switch (type)
                    {
                        case BlockMountType.Dazed:
                            from.SendMessage("You are still too dazed to fly.");
                            break; // You are still too dazed to fly.
                        case BlockMountType.BolaRecovery:
                            from.SendMessage("You cannot fly while recovering from a bola throw.");
                            break; // You cannot fly while recovering from a bola throw.
                        case BlockMountType.DismountRecovery:
                            from.SendMessage("You cannot fly while recovering from a dismount maneuver.");
                            break; // You cannot fly while recovering from a dismount maneuver.
                    }
                    return;
                }
        
                else
                {
                    ToggleFlight(true, from);
                }
            }
    
            else
            {
                ToggleFlight(false, from);
            }
        }
  
        public void ToggleFlight(bool turnon, Mobile from)
        {
            if (turnon)
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(60, 10, 1, true, false, 0);
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You are flying!");
                from.Flying = true;
                BuffInfo.AddBuff(from, new BuffInfo(BuffIcon.Fly, 1112567));
                if (m_Timer != null)
                    m_Timer.Stop();
                m_Timer = new FlightTimer(from, this);
                m_Timer.Start();
            }
            else
            {
                from.Freeze(TimeSpan.FromSeconds(1));
                from.RevealingAction();
                from.Animate(61, 10, 1, true, false, 0);
                BuffInfo.RemoveBuff(from, BuffIcon.Fly);
                from.Flying = false;
                from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You've Landed!");
                if (m_Timer != null)
                    m_Timer.Stop();
                m_Timer = new FlightTimer(from, this);
                m_Timer.Start();
            }
        }
        private class FlightTimer : Timer
        {
            private readonly Mobile m;
            private FlightItem fi;
            public FlightTimer(Mobile from, FlightItem item)
                : base(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1), 900)
            {
                m = from;
                fi = item;
                Priority = TimerPriority.EveryTick;
            }
            protected override void OnTick()
            {
                if (fi == null || fi.Deleted) Stop();
     //           if (fi.TimeLeft%10 == 0) m.SendMessage("You have {0} seconds of Flight Time remaining.", fi.TimeLeft);
                if (m.Flying)
                {
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false, m);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
     //                   m.SendMessage("Your Flight Timer has reached maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
        }
        public virtual bool Accepted
        {
            get
            {
                return this.Deleted;
            }
        }
        public override bool DropToWorld(Mobile from, Point3D p)
        {
            bool ret = base.DropToWorld(from, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "You feel silly for wanting to drop something so useful...");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToMobile(Mobile from, Mobile target, Point3D p)
        {
            bool ret = base.DropToMobile(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This cannot be traded!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
        public override bool DropToItem(Mobile from, Item target, Point3D p)
        {
            bool ret = base.DropToItem(from, target, p);
            if (ret && !this.Accepted && this.Parent != from.Backpack)
            {
                if (from.IsStaff())
                {
                    return true;
                }
                else
                {
                    from.LocalOverheadMessage(MessageType.Emote, 0x22, true, "This can only exist on the top level of the backpack!");
                    return false;
                }
            }
            else
            {
                return ret;
            }
        }
           
        public override void GetProperties(ObjectPropertyList list)
        {
            base.GetProperties(list);
            list.Add("<BASEFONT COLOR=#7FCAE7>Time Remaining: {0}<BASEFONT COLOR=#17FF01>", m_TimeLeft.ToString());
        }
        public FlightItem( Serial serial ) : base( serial )
        {
        }
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
            writer.Write( (int) 0 ); // version
            writer.WriteEncodedInt((int)m_TimeLeft);
        }
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
            int version = reader.ReadInt();
            m_TimeLeft = reader.ReadInt();
        }
    }
}
[doublepost=1469555879][/doublepost]Nevermind on the serial method, apparently I goofed it, deletes the item each server restart.. lol I will post back once I got that fixed
[doublepost=1469556256][/doublepost]There we go..

Code:
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
            writer.Write( (int) 0 ); // version
            writer.Write((int)m_TimeLeft);
           
        }
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
            int version = reader.ReadInt();
            m_TimeLeft = reader.ReadInt();
        }
 
Last edited:
Nice! This is the last recommendation. If they are flying keep a message notification in there of how many minutes are left. Here is the modified Tick method that calls out every minute instead of every 10 seconds:

Code:
            protected override void OnTick()
            {
                if (fi == null || fi.Deleted) Stop();
                if (m.Flying)
                {
                    if (fi.TimeLeft%60 == 0)
                        m.SendMessage("You have {0} minutes of Flight Time remaining.", (int)(fi.TimeLeft/60));
                    fi.TimeLeft--;
                    if (fi.TimeLeft <= 0)
                    {
                        fi.ToggleFlight(false, m);
                    }
                }
                else
                {
                    fi.TimeLeft++;
                    if (fi.TimeLeft >= 900)
                    {
                        m.SendMessage("Your Flight Timer has reached the maximum charge of 15 minutes available.");
                        this.Stop();
                    }
                }
            }
 
btw, this is likely not going to work, is it possible to have the welcometimer or loginstatis check player back pack to see if flightitem exist, if it does start flight item timer? if the player logs in, their timer does not start. I figured it may be easier to add a check in the welcometimer then to add an entry into the PM.. lol

I like the recommendation, i will check it out now.
 
What you probably want to do is add a public method called NewTimer:

Code:
public void NewTimer(Mobile from)
{
      if (m_Timer != null)
            m_Timer.Stop();
      m_Timer = new FlightTimer(from, this);
      m_Timer.Start();
}

Then add your login class as a new file:

Code:
using System;
using Server.Network;

namespace Server.Misc
{
    public class LoginFlightItemCheck
    {
        public static void Initialize()
        {
            EventSink.Login += new LoginEventHandler(EventSink_Login);
        }

        private static void EventSink_Login(LoginEventArgs args)
        {
            Mobile m = args.Mobile;
           
            Container pack = m.Backpack;
            if (pack == null) return;
           
            FlightItem item = (FlightItem)pack.FindItemByType(typeof(FlightItem));
           
            if (item == null) return;
           
            item.NewTimer(m);
        }
    }
}

This is all off the cuff, so check the syntax and everything before testing.
 
For off the cuff it was dead on, no syntax issues, only thing that needed to be added was Using server.items; to reference the flightitem, tried a few toons, used up their flight time, logged out, logged back in and it was already counting up.
 
Back