RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Lucid's Archery -Won't fire from quiver

daat99

Moderator
Staff member
I'm confused, you said you had the following output:
Code making it to OnTarget.
Code making it to arrow check.
And now you are saying that you don't have this output anymore?
What was changed in the code between those 2 attempts?

Can you make a single post with the most recent code (all the files we modified if possible) and copy/paste the exact output you see in the console please?
 
Oh, no I do still get those, but as I said, that's not from our edits, that's something that was in there before. That part comes from bowtarget.cs which comes with the package. I just never noticed it before because I wasn't looking until now
 

daat99

Moderator
Staff member
Can you please attach the most resent code (all the files we modified with the console output) and the entire console output you get please?
 
The only file that has been modified since we started is the baserange.cs
Code:
using System;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Mobiles;
using Server.Targeting;
using System.Collections;
using System.Collections.Generic;
using Server.Enums;
using Server.ACC.CM;
using Server.LucidNagual;
 
namespace Server.Items
{
    public abstract class BaseRanged : BaseMeleeWeapon
    {
        //--<<Advanced Archery Edit>>---------------------[Start 1/4]
        //SkillModule edit.
        private BaseRangedModule m_BaseRangedModule;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public BaseRangedModule BaseRangedModule
        {
            get
            {
                BaseRangedModule existingModule = ( BaseRangedModule )CentralMemory.GetModule( this.Serial, typeof( BaseRangedModule ) );
               
                if ( existingModule == null )
                {
                    BaseRangedModule module = new BaseRangedModule( this.Serial );
                    CentralMemory.AppendModule( this.Serial, module, true );
                   
                    return ( m_BaseRangedModule = module as BaseRangedModule );
                }
                else
                {
                    if ( m_BaseRangedModule != null )
                        return m_BaseRangedModule;
                   
                    return ( m_BaseRangedModule = existingModule as BaseRangedModule );
                }
            }
        }
        //SkillModule edit.
       
        public static int PlayerFreezeTimer = 2;
        public static int NPCFreezeTimer = 2;       
       
        private bool m_IsLevelable;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public ArrowType ArrowSelection    { get { return m_BaseRangedModule.ArrowSelection; } set { m_BaseRangedModule.ArrowSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public BoltType BoltSelection { get { return m_BaseRangedModule.BoltSelection; } set { m_BaseRangedModule.BoltSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public StringStrength StringStrengthSelection { get { return m_BaseRangedModule.StringStrengthSelection; } set { m_BaseRangedModule.StringStrengthSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public PoundsPerPull PullWeightSelection { get { return m_BaseRangedModule.PullWeightSelection; } set { m_BaseRangedModule.PullWeightSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool HasBowString { get{ return m_BaseRangedModule.HasBowString; } set{ m_BaseRangedModule.HasBowString = value; } }       
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool IsLevelable { get{ return m_IsLevelable; } set{ m_IsLevelable = value; } }       
               
       
        private static Mobile m_Mobile;
        private static BaseRanged BRanged;
       
        public static TimeSpan StringWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextStringWarning;
        public static TimeSpan AmmoWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextAmmoWarning;
        //--<<Advanced Archery Edit>>---------------------[End 1/4]
 
        public abstract int EffectID{ get; }
        public abstract Type AmmoType{ get; }
        public abstract Item Ammo{ get; }
 
        public override int DefHitSound{ get{ return 0x234; } }
        public override int DefMissSound{ get{ return 0x238; } }
 
        public override SkillName DefSkill{ get{ return SkillName.Archery; } }
        public override WeaponType DefType{ get{ return WeaponType.Ranged; } }
        public override WeaponAnimation DefAnimation{ get{ return WeaponAnimation.ShootXBow; } }
 
        public override SkillName AccuracySkill{ get{ return SkillName.Archery; } }
 
        private Timer m_RecoveryTimer; // so we don't start too many timers
        private bool m_Balanced;
        private int m_Velocity;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool Balanced
        {
            get{ return m_Balanced; }
            set{ m_Balanced = value; InvalidateProperties(); }
        }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public int Velocity
        {
            get{ return m_Velocity; }
            set{ m_Velocity = value; InvalidateProperties(); }
        }
 
        public BaseRanged( int itemID ) : base( itemID )
        {
        }
 
        public BaseRanged( Serial serial ) : base( serial )
        {
        }
 
        public override TimeSpan OnSwing( Mobile attacker, Mobile defender )
        {
            WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
 
            // Make sure we've been standing still for .25/.5/1 second depending on Era
            if ( DateTime.Now > (attacker.LastMoveTime + TimeSpan.FromSeconds( Core.SE ? 0.25 : (Core.AOS ? 0.5 : 1.0) )) || (Core.AOS && WeaponAbility.GetCurrentAbility( attacker ) is MovingShot) )
            {
                bool canSwing = true;
 
                if ( Core.AOS )
                {
                    canSwing = ( !attacker.Paralyzed && !attacker.Frozen );
 
                    if ( canSwing )
                    {
                        Spell sp = attacker.Spell as Spell;
 
                        canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
                    }
                }
 
                #region Dueling
                if ( attacker is PlayerMobile )
                {
                    PlayerMobile pm = (PlayerMobile)attacker;
 
                    if ( pm.DuelContext != null && !pm.DuelContext.CheckItemEquip( attacker, this ) )
                        canSwing = false;
                }
                #endregion
 
                if ( canSwing && attacker.HarmfulCheck( defender ) )
                {
                    attacker.DisruptiveAction();
                    attacker.Send( new Swing( 0, attacker, defender ) );
 
                    if ( OnFired( attacker, defender ) )
                    {
                        if ( CheckHit( attacker, defender ) )
                            OnHit( attacker, defender );
                        else
                            OnMiss( attacker, defender );
                    }
                }
 
                attacker.RevealingAction();
 
                return GetDelay( attacker );
            }
            else
            {
                attacker.RevealingAction();
 
                return TimeSpan.FromSeconds( 0.25 );
            }
        }
 
        public override void OnHit( Mobile attacker, Mobile defender, double damageBonus )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 2/4]
            if ( attacker == null || defender == null )
                return;
           
            MoreBaseRanged.CustomAmmoCheck( attacker, defender, AmmoType );
           
            if ( Ammo == null )
                attacker.SendMessage( "You are out of arrows, or may have to choose a different type of arrow by double clicking the bow." );
            //--<<Advanced Archery Edit>>---------------------[End 2/4]
           
            if ( attacker.Player && !defender.Player && (defender.Body.IsAnimal || defender.Body.IsMonster) && 0.4 >= Utility.RandomDouble() )
                defender.AddToBackpack( Ammo );
 
            if ( Core.ML && m_Velocity > 0 )
            {
                int bonus = (int) attacker.GetDistanceToSqrt( defender );
 
                if ( bonus > 0 && m_Velocity > Utility.Random( 100 ) )
                {
                    AOS.Damage( defender, attacker, bonus * 3, 100, 0, 0, 0, 0 );
 
                    if ( attacker.Player )
                        attacker.SendLocalizedMessage( 1072794 ); // Your arrow hits its mark with velocity!
 
                    if ( defender.Player )
                        defender.SendLocalizedMessage( 1072795 ); // You have been hit by an arrow with velocity!
                }
            }
 
            base.OnHit( attacker, defender, damageBonus );
        }
 
        public override void OnMiss( Mobile attacker, Mobile defender )
        {
            if ( attacker.Player && 0.4 >= Utility.RandomDouble() )
            {
                if ( Core.SE )
                {
                    PlayerMobile p = attacker as PlayerMobile;
 
                    if ( p != null )
                    {
                        Type ammo = AmmoType;
 
                        if ( p.RecoverableAmmo.ContainsKey( ammo ) )
                            p.RecoverableAmmo[ ammo ]++;
                        else
                            p.RecoverableAmmo.Add( ammo, 1 );
 
                        if ( !p.Warmode )
                        {
                            if ( m_RecoveryTimer == null )
                                m_RecoveryTimer = Timer.DelayCall( TimeSpan.FromSeconds( 10 ), new TimerCallback( p.RecoverAmmo ) );
 
                            if ( !m_RecoveryTimer.Running )
                                m_RecoveryTimer.Start();
                        }
                    else
                        Ammo.MoveToWorld( new Point3D( defender.X + Utility.RandomMinMax( -1, 1 ), defender.Y + Utility.RandomMinMax( -1, 1 ), defender.Z ), defender.Map );
                    }
                }
            }
 
            base.OnMiss( attacker, defender );
        }
 
        public virtual bool OnFired( Mobile attacker, Mobile defender )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 3/4]
            PlayerMobile a_pm = attacker as PlayerMobile;
            Container pack = attacker.Backpack;
            BaseQuiver quiver = attacker.FindItemOnLayer( Layer.MiddleTorso ) as BaseQuiver;
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( !module.HasBowString )
            {
                if ( DateTime.Now >= m_NextStringWarning )
                {
                    m_NextStringWarning = DateTime.Now + StringWarningDelay;
                    attacker.SendMessage( "You need a string to use this bow. See a local fletcher to apply the string." );
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "String is null");
                        return false;
                }
            }
           
            if ( Ammo == null )
            {
                if ( DateTime.Now >= m_NextAmmoWarning )
                {
                    m_NextAmmoWarning = DateTime.Now + AmmoWarningDelay;
                    attacker.SendMessage( "You are out of ammo." );
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "Ammo is null");
                        return false;
                }
            }
           
            if( attacker.Player && quiver != null && quiver.LowerAmmoCost > Utility.Random( 100 ) )
            {
                attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                return true;
            }
           
            if( attacker.Player &&
              ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
              (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                return false;
            //--<<Advanced Archery Edit>>---------------------[End 3/4]
       
 
            if ( attacker.Player )
            {
                //BaseQuiver quiver = attacker.FindItemOnLayer( Layer.Cloak ) as BaseQuiver;
                //Container pack = attacker.Backpack;
 
                if ( quiver == null || Utility.Random( 100 ) >= quiver.LowerAmmoCost )
                {
                    if ( quiver != null )
                    {
                        Item[] typedItems = quiver.FindItemsByType( typeof( PoisonArrow ), true );
                        Console.WriteLine("FindItemsByType was able to find {0} items.", typedItems.Length); //try Count if it doesn't compile
                        if ( typedItems.Length > 0 )
                        {
                            Console.WriteLine("The amount of the first item is: {0}", typedItems[0].Amount);
                            typedItems[0].Consume( 1 );
                            Console.WriteLine("The amount of the first item after consuming 1 is: {0}", typedItems[0].Amount);
                        }
                    }
 
                    // consume ammo
                    if ( quiver != null && quiver.ConsumeTotal( AmmoType, 1 ) )
                        quiver.InvalidateWeight();
                    else if ( pack == null || !pack.ConsumeTotal( AmmoType, 1 ) )
                        return false;
                }
                else if ( quiver.FindItemByType( AmmoType ) == null && ( pack == null || pack.FindItemByType( AmmoType ) == null ) )
                {
                    // lower ammo cost should not work when we have no ammo at all
                    return false;
                }
            }
           
            attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
            return true;
        }
       
        //--<<Advanced Archery Edit>>---------------------[Start 4/4]
        public override void OnDoubleClick( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( IsChildOf( from.Backpack ) || Parent == from )
            {
                if ( module.HasBowString )
                {
                    if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                        this is MagicalShortbow || this is Yumi )
                    {
                        from.SendMessage( "Please choose which type of arrows you wish to use." );
                        from.Target = new BowTarget( this );
                    }
                   
                    if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                    {
                        from.SendMessage( "Please choose which type of bolts you wish to use." );
                        from.Target = new CrossbowTarget( this );
                    }
                }
                else
                {
                    from.SendMessage( "You must string your bow. Please select a bow stringer." );
                    from.Target = new StringerTarget( this );
                }
            }
           
            else
                return;
        }
       
        /*public override void OnDelete()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( module != null )
                module.Delete();
           
            base.OnDelete();
        }*/
       
        public override bool OnEquip( Mobile from )
        {
            m_Mobile = from;
           
            return true;
        }
       
        public override bool CanEquip( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( from != null && !module.HasBowString )
            {
                from.SendMessage( "You cannot use that without a string." );
                return false;
            }
           
            base.CanEquip( from );
           
            return true;
        }
       
        public virtual Item AmmoArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return new Arrow();
                case ArrowType.Poison:
                    return new PoisonArrow();
                case ArrowType.Explosive:
                    return new ExplosiveArrow();
                case ArrowType.ArmorPiercing:
                    return new ArmorPiercingArrow();
                case ArrowType.Freeze:
                    return new FreezeArrow();
                case ArrowType.Lightning:
                    return new LightningArrow();
                   
                default:
                    return new Arrow();
            }
        }
       
        public virtual Type GetArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return typeof( Arrow );
                case ArrowType.Poison:
                    return typeof( PoisonArrow );
                case ArrowType.Explosive:
                    return typeof( ExplosiveArrow );
                case ArrowType.ArmorPiercing:
                    return typeof( ArmorPiercingArrow );
                case ArrowType.Freeze:
                    return typeof( FreezeArrow );
                case ArrowType.Lightning:
                    return typeof( LightningArrow );
                   
                default:
                    return typeof( Arrow );
            }
        }
       
        public virtual Item AmmoBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return new Bolt();
                case BoltType.Poison:
                    return new PoisonBolt();
                case BoltType.Explosive:
                    return new ExplosiveBolt();
                case BoltType.ArmorPiercing:
                    return new ArmorPiercingBolt();
                case BoltType.Freeze:
                    return new FreezeBolt();
                case BoltType.Lightning:
                    return new LightningBolt();
                   
                default:
                    return new Bolt();
            }
        }
       
        public virtual Type GetBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return typeof( Bolt );
                case BoltType.Poison:
                    return typeof( PoisonBolt );
                case BoltType.Explosive:
                    return typeof( ExplosiveBolt );
                case BoltType.ArmorPiercing:
                    return typeof( ArmorPiercingBolt );
                case BoltType.Freeze:
                    return typeof( FreezeBolt );
                case BoltType.Lightning:
                    return typeof( LightningBolt );
                   
                default:
                    return typeof( Bolt );
            }
        }
       
        public override void GetProperties( ObjectPropertyList list )
        {
            base.GetProperties(list);
           
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( module != null )
            {
                ArrayList strings = new ArrayList();
               
                strings.Add( ( "---------------" ) );
               
                if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                    this is MagicalShortbow || this is Yumi )
                {
                    strings.Add( ( "Quiver Using: " + module.m_ArrowType ) );
                }
               
                if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                {
                    strings.Add( ( "Quiver Using: " + module.m_BoltType ) );
                }
               
                strings.Add( ( "lbs per Pull: " + module.m_PullWeight ) );
                strings.Add( ( "String Str: "  + module.m_Strength ) );
               
                string toAdd = "";
                int amount = strings.Count;
                int current = 1;
               
                foreach ( string str in strings )
                {
                    toAdd += str;
                   
                    if ( current != amount )
                        toAdd += "\n";
                   
                    ++current;
                }
               
                if ( toAdd != "" )
                    list.Add( 1070722, toAdd );
            }
            else
            {
                return;
            }
        }
        //--<<Advanced Archery Edit>>---------------------[End 4/4]
 
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
 
            writer.Write( (int) 3 ); // version
 
            writer.Write( (bool) m_Balanced );
            writer.Write( (int) m_Velocity );
        }
 
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
 
            int version = reader.ReadInt();
 
            switch ( version )
            {
                case 3:
                {
                    m_Balanced = reader.ReadBool();
                    m_Velocity = reader.ReadInt();
 
                    goto case 2;
                }
                case 2:
                case 1:
                {
                    break;
                }
                case 0:
                {
                    /*m_EffectID =*/ reader.ReadInt();
                    break;
                }
            }
 
            if ( version < 2 )
            {
                WeaponAttributes.MageWeapon = 0;
                WeaponAttributes.UseBestSkill = 0;
            }
        }
    }
}

And the only things I have changed are the lines you asked me to put in
Code:
Console.WriteLine("Returning false because {0}", "String is null");
                        return false;

Code:
Console.WriteLine("Returning false because {0}", "Ammo is null");
                        return false;

Code:
if ( quiver != null )
                    {
                        Item[] typedItems = quiver.FindItemsByType( typeof( PoisonArrow ), true );
                        Console.WriteLine("FindItemsByType was able to find {0} items.", typedItems.Length); //try Count if it doesn't compile
                        if ( typedItems.Length > 0 )
                        {
                            Console.WriteLine("The amount of the first item is: {0}", typedItems[0].Amount);
                            typedItems[0].Consume( 1 );
                            Console.WriteLine("The amount of the first item after consuming 1 is: {0}", typedItems[0].Amount);
                        }
                    }

I get the console output of
Code:
Code making it to OnTarget.
Code making it to arrow check.
when I target a new arrow type. These are actually coming from the code that came with the system, the bowtarget.cs I never noticed these output before because I was not looking for them. Here is the bowtarget.cs
Code:
using System;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Mobiles;
using System.Collections;
using Server.Enums;
using Server.ACC.CM;
using Server.LucidNagual;
 
 
namespace Server.Targeting
{
    public class BowTarget : Target
    {
        private BaseRanged it_Ranged;
       
        public BowTarget( BaseRanged ranged ) : base( 1, false, TargetFlags.None )
        {
            it_Ranged = ranged;
        }
       
        protected override void OnTarget( Mobile from, object targeted )
        {
            Console.WriteLine( "Code making it to OnTarget." );
            BaseRanged rang = it_Ranged as BaseRanged;
            BaseRangedModule module = rang.BaseRangedModule;
           
            if ( targeted is Item && targeted is Arrow )
            {
                Console.WriteLine( "Code making it to arrow check." );
                Item item = ( Item )targeted;
               
                string errorMsg = "You cannot arm a bow that does not have a string.";
               
                if ( !module.HasBowString )
                {
                    from.SendMessage( "{0}", errorMsg );
                    return;
                }
               
                if ( item.GetType() == typeof( Arrow ) )
                {
                    module.ArrowSelection = ArrowType.Normal;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( PoisonArrow ) )
                {
                    module.ArrowSelection = ArrowType.Poison;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( ExplosiveArrow ) )
                {
                    module.ArrowSelection = ArrowType.Explosive;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( ArmorPiercingArrow ) )
                {
                    module.ArrowSelection = ArrowType.ArmorPiercing;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( FreezeArrow ) )
                {
                    module.ArrowSelection = ArrowType.Freeze;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( LightningArrow ) )
                {
                    module.ArrowSelection = ArrowType.Lightning;
                    rang.InvalidateProperties();
                }
            }
            else
            {
                from.SendMessage( "You can only target an arrow." );
            }
        }
    }
}
Those are the only two files that should be giving me a console output regarding the archery system.
 

daat99

Moderator
Staff member
1. This doesn't have much to do with the firing or consumption but try this code:
Code:
        protected override void OnTarget( Mobile from, object targeted )
        {
            Console.WriteLine( "Code making it to OnTarget." );
            BaseRanged rang = it_Ranged as BaseRanged;
            BaseRangedModule module = rang.BaseRangedModule;
           
            if ( targeted is Item && targeted is Arrow )
            {
                Console.WriteLine( "Code making it to arrow check." );
                Item item = ( Item )targeted;
               
                string errorMsg = "You cannot arm a bow that does not have a string.";
                Console.WriteLine("Item type is: {0}.", item.GetType().ToString());
                if ( !module.HasBowString )
                {
                    Console.WriteLine("no bow string");
                    from.SendMessage( "{0}", errorMsg );
                    return;
                }
               
                if ( item.GetType() == typeof( Arrow ) )
                {
                    module.ArrowSelection = ArrowType.Normal;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( PoisonArrow ) )
                {
                    module.ArrowSelection = ArrowType.Poison;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( ExplosiveArrow ) )
                {
                    module.ArrowSelection = ArrowType.Explosive;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( ArmorPiercingArrow ) )
                {
                    module.ArrowSelection = ArrowType.ArmorPiercing;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( FreezeArrow ) )
                {
                    module.ArrowSelection = ArrowType.Freeze;
                    rang.InvalidateProperties();
                }
               
                if ( item.GetType() == typeof( LightningArrow ) )
                {
                    module.ArrowSelection = ArrowType.Lightning;
                    rang.InvalidateProperties();
                }
                Console.WriteLine("Using arrow selection: {0}", module.ArrowSelection);
            }
            else
            {
                from.SendMessage( "You can only target an arrow." );
            }
        }

2. Lets go back to this post:
Lucid's Archery -Won't fire from quiver post #13 by daat99
Follow that post and add the test code I described like Hammerhand did.

Then try to shoot some mob (rat/monster...).

Please post the updated code and the console output with both of the above changes.
 
Here is the new bowtarget.cs:
Code:
using System;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Mobiles;
using System.Collections;
using Server.Enums;
using Server.ACC.CM;
using Server.LucidNagual;
 
 
namespace Server.Targeting
{
    public class BowTarget : Target
    {
        private BaseRanged it_Ranged;
       
        public BowTarget( BaseRanged ranged ) : base( 1, false, TargetFlags.None )
        {
            it_Ranged = ranged;
        }
       
        protected override void OnTarget( Mobile from, object targeted )
        {
            Console.WriteLine( "Code making it to OnTarget." );
            BaseRanged rang = it_Ranged as BaseRanged;
            BaseRangedModule module = rang.BaseRangedModule;
         
            if ( targeted is Item && targeted is Arrow )
            {
                Console.WriteLine( "Code making it to arrow check." );
                Item item = ( Item )targeted;
             
                string errorMsg = "You cannot arm a bow that does not have a string.";
                Console.WriteLine("Item type is: {0}.", item.GetType().ToString());
                if ( !module.HasBowString )
                {
                    Console.WriteLine("no bow string");
                    from.SendMessage( "{0}", errorMsg );
                    return;
                }
             
                if ( item.GetType() == typeof( Arrow ) )
                {
                    module.ArrowSelection = ArrowType.Normal;
                    rang.InvalidateProperties();
                }
             
                if ( item.GetType() == typeof( PoisonArrow ) )
                {
                    module.ArrowSelection = ArrowType.Poison;
                    rang.InvalidateProperties();
                }
             
                if ( item.GetType() == typeof( ExplosiveArrow ) )
                {
                    module.ArrowSelection = ArrowType.Explosive;
                    rang.InvalidateProperties();
                }
             
                if ( item.GetType() == typeof( ArmorPiercingArrow ) )
                {
                    module.ArrowSelection = ArrowType.ArmorPiercing;
                    rang.InvalidateProperties();
                }
             
                if ( item.GetType() == typeof( FreezeArrow ) )
                {
                    module.ArrowSelection = ArrowType.Freeze;
                    rang.InvalidateProperties();
                }
             
                if ( item.GetType() == typeof( LightningArrow ) )
                {
                    module.ArrowSelection = ArrowType.Lightning;
                    rang.InvalidateProperties();
                }
                Console.WriteLine("Using arrow selection: {0}", module.ArrowSelection);
            }
            else
            {
                from.SendMessage( "You can only target an arrow." );
            }
        }
    }
}
And the new base ranged:
Code:
using System;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Mobiles;
using Server.Targeting;
using System.Collections;
using System.Collections.Generic;
using Server.Enums;
using Server.ACC.CM;
using Server.LucidNagual;
 
namespace Server.Items
{
    public abstract class BaseRanged : BaseMeleeWeapon
    {
        //--<<Advanced Archery Edit>>---------------------[Start 1/4]
        //SkillModule edit.
        private BaseRangedModule m_BaseRangedModule;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public BaseRangedModule BaseRangedModule
        {
            get
            {
                BaseRangedModule existingModule = ( BaseRangedModule )CentralMemory.GetModule( this.Serial, typeof( BaseRangedModule ) );
               
                if ( existingModule == null )
                {
                    BaseRangedModule module = new BaseRangedModule( this.Serial );
                    CentralMemory.AppendModule( this.Serial, module, true );
                   
                    return ( m_BaseRangedModule = module as BaseRangedModule );
                }
                else
                {
                    if ( m_BaseRangedModule != null )
                        return m_BaseRangedModule;
                   
                    return ( m_BaseRangedModule = existingModule as BaseRangedModule );
                }
            }
        }
        //SkillModule edit.
       
        public static int PlayerFreezeTimer = 2;
        public static int NPCFreezeTimer = 2;       
       
        private bool m_IsLevelable;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public ArrowType ArrowSelection    { get { return m_BaseRangedModule.ArrowSelection; } set { m_BaseRangedModule.ArrowSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public BoltType BoltSelection { get { return m_BaseRangedModule.BoltSelection; } set { m_BaseRangedModule.BoltSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public StringStrength StringStrengthSelection { get { return m_BaseRangedModule.StringStrengthSelection; } set { m_BaseRangedModule.StringStrengthSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public PoundsPerPull PullWeightSelection { get { return m_BaseRangedModule.PullWeightSelection; } set { m_BaseRangedModule.PullWeightSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool HasBowString { get{ return m_BaseRangedModule.HasBowString; } set{ m_BaseRangedModule.HasBowString = value; } }       
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool IsLevelable { get{ return m_IsLevelable; } set{ m_IsLevelable = value; } }       
               
       
        private static Mobile m_Mobile;
        private static BaseRanged BRanged;
       
        public static TimeSpan StringWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextStringWarning;
        public static TimeSpan AmmoWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextAmmoWarning;
        //--<<Advanced Archery Edit>>---------------------[End 1/4]
 
        public abstract int EffectID{ get; }
        public abstract Type AmmoType{ get; }
        public abstract Item Ammo{ get; }
 
        public override int DefHitSound{ get{ return 0x234; } }
        public override int DefMissSound{ get{ return 0x238; } }
 
        public override SkillName DefSkill{ get{ return SkillName.Archery; } }
        public override WeaponType DefType{ get{ return WeaponType.Ranged; } }
        public override WeaponAnimation DefAnimation{ get{ return WeaponAnimation.ShootXBow; } }
 
        public override SkillName AccuracySkill{ get{ return SkillName.Archery; } }
 
        private Timer m_RecoveryTimer; // so we don't start too many timers
        private bool m_Balanced;
        private int m_Velocity;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool Balanced
        {
            get{ return m_Balanced; }
            set{ m_Balanced = value; InvalidateProperties(); }
        }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public int Velocity
        {
            get{ return m_Velocity; }
            set{ m_Velocity = value; InvalidateProperties(); }
        }
 
        public BaseRanged( int itemID ) : base( itemID )
        {
        }
 
        public BaseRanged( Serial serial ) : base( serial )
        {
        }
 
        public override TimeSpan OnSwing( Mobile attacker, Mobile defender )
        {
            WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
 
            // Make sure we've been standing still for .25/.5/1 second depending on Era
            if ( DateTime.Now > (attacker.LastMoveTime + TimeSpan.FromSeconds( Core.SE ? 0.25 : (Core.AOS ? 0.5 : 1.0) )) || (Core.AOS && WeaponAbility.GetCurrentAbility( attacker ) is MovingShot) )
            {
                bool canSwing = true;
 
                if ( Core.AOS )
                {
                    canSwing = ( !attacker.Paralyzed && !attacker.Frozen );
 
                    if ( canSwing )
                    {
                        Spell sp = attacker.Spell as Spell;
 
                        canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
                    }
                }
 
                #region Dueling
                if ( attacker is PlayerMobile )
                {
                    PlayerMobile pm = (PlayerMobile)attacker;
 
                    if ( pm.DuelContext != null && !pm.DuelContext.CheckItemEquip( attacker, this ) )
                        canSwing = false;
                }
                #endregion
 
                if ( canSwing && attacker.HarmfulCheck( defender ) )
                {
                    attacker.DisruptiveAction();
                    attacker.Send( new Swing( 0, attacker, defender ) );
 
                    if ( OnFired( attacker, defender ) )
                    {
                        if ( CheckHit( attacker, defender ) )
                            OnHit( attacker, defender );
                        else
                            OnMiss( attacker, defender );
                    }
                }
 
                attacker.RevealingAction();
 
                return GetDelay( attacker );
            }
            else
            {
                attacker.RevealingAction();
 
                return TimeSpan.FromSeconds( 0.25 );
            }
        }
 
        public override void OnHit( Mobile attacker, Mobile defender, double damageBonus )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 2/4]
            if ( attacker == null || defender == null )
                return;
           
            MoreBaseRanged.CustomAmmoCheck( attacker, defender, AmmoType );
           
            if ( Ammo == null )
                attacker.SendMessage( "You are out of arrows, or may have to choose a different type of arrow by double clicking the bow." );
            //--<<Advanced Archery Edit>>---------------------[End 2/4]
           
            if ( attacker.Player && !defender.Player && (defender.Body.IsAnimal || defender.Body.IsMonster) && 0.4 >= Utility.RandomDouble() )
                defender.AddToBackpack( Ammo );
 
            if ( Core.ML && m_Velocity > 0 )
            {
                int bonus = (int) attacker.GetDistanceToSqrt( defender );
 
                if ( bonus > 0 && m_Velocity > Utility.Random( 100 ) )
                {
                    AOS.Damage( defender, attacker, bonus * 3, 100, 0, 0, 0, 0 );
 
                    if ( attacker.Player )
                        attacker.SendLocalizedMessage( 1072794 ); // Your arrow hits its mark with velocity!
 
                    if ( defender.Player )
                        defender.SendLocalizedMessage( 1072795 ); // You have been hit by an arrow with velocity!
                }
            }
 
            base.OnHit( attacker, defender, damageBonus );
        }
 
        public override void OnMiss( Mobile attacker, Mobile defender )
        {
            if ( attacker.Player && 0.4 >= Utility.RandomDouble() )
            {
                if ( Core.SE )
                {
                    PlayerMobile p = attacker as PlayerMobile;
 
                    if ( p != null )
                    {
                        Type ammo = AmmoType;
 
                        if ( p.RecoverableAmmo.ContainsKey( ammo ) )
                            p.RecoverableAmmo[ ammo ]++;
                        else
                            p.RecoverableAmmo.Add( ammo, 1 );
 
                        if ( !p.Warmode )
                        {
                            if ( m_RecoveryTimer == null )
                                m_RecoveryTimer = Timer.DelayCall( TimeSpan.FromSeconds( 10 ), new TimerCallback( p.RecoverAmmo ) );
 
                            if ( !m_RecoveryTimer.Running )
                                m_RecoveryTimer.Start();
                        }
                    else
                        Ammo.MoveToWorld( new Point3D( defender.X + Utility.RandomMinMax( -1, 1 ), defender.Y + Utility.RandomMinMax( -1, 1 ), defender.Z ), defender.Map );
                    }
                }
            }
 
            base.OnMiss( attacker, defender );
        }
 
        public virtual bool OnFired( Mobile attacker, Mobile defender )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 3/4]
            PlayerMobile a_pm = attacker as PlayerMobile;
            Container pack = attacker.Backpack;
            BaseQuiver quiver = attacker.FindItemOnLayer( Layer.MiddleTorso ) as BaseQuiver;
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( !module.HasBowString )
            {
                if ( DateTime.Now >= m_NextStringWarning )
                {
                    m_NextStringWarning = DateTime.Now + StringWarningDelay;
                    attacker.SendMessage( "You need a string to use this bow. See a local fletcher to apply the string." );
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "String is null");
                        return false;
                }
            }
           
            if ( Ammo == null )
            {
                if ( DateTime.Now >= m_NextAmmoWarning )
                {
                    m_NextAmmoWarning = DateTime.Now + AmmoWarningDelay;
                    attacker.SendMessage( "You are out of ammo." );
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "Ammo is null");
                        return false;
                }
            }
           
            if( attacker.Player && quiver != null && quiver.LowerAmmoCost > Utility.Random( 100 ) )
            {
                attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                return true;
            }
           
            if( attacker.Player &&
              ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
              (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                return false;
            //--<<Advanced Archery Edit>>---------------------[End 3/4]
       
        if ( attacker.Player )
            {
                //BaseQuiver quiver = attacker.FindItemOnLayer( Layer.Cloak ) as BaseQuiver;
                //Container pack = attacker.Backpack;
 
                if ( quiver == null || Utility.Random( 100 ) >= quiver.LowerAmmoCost )
                {
                    if (quiver != null)
                    {
                        Item[] typedItems = quiver.FindItemsByType(typeof(PoisonArrow), true);
                        Console.WriteLine("FindItemsByType was able to find {0} items.", typedItems.Length); //try Count if it doesn't compile
                        if (typedItems.Length > 0)
                        {
                            Console.WriteLine("The amount of the first item is: {0}", typedItems[0].Amount);
                            typedItems[0].Consume(1);
                            Console.WriteLine("The amount of the first item after consuming 1 is: {1}", typedItems[0].Amount);
                        }
                    }
                    if ( quiver != null && quiver.ConsumeTotal( AmmoType, 1 ) )
                        quiver.InvalidateWeight();
                    else if ( pack == null || !pack.ConsumeTotal( AmmoType, 1 ) )
                        return false;
                }
                else if ( quiver.FindItemByType( AmmoType ) == null && ( pack == null || pack.FindItemByType( AmmoType ) == null ) )
                {
                    // lower ammo cost should not work when we have no ammo at all
                    return false;
                }
            }
 
            attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
 
            return true;
        }
       
        //--<<Advanced Archery Edit>>---------------------[Start 4/4]
        public override void OnDoubleClick( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( IsChildOf( from.Backpack ) || Parent == from )
            {
                if ( module.HasBowString )
                {
                    if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                        this is MagicalShortbow || this is Yumi )
                    {
                        from.SendMessage( "Please choose which type of arrows you wish to use." );
                        from.Target = new BowTarget( this );
                    }
                   
                    if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                    {
                        from.SendMessage( "Please choose which type of bolts you wish to use." );
                        from.Target = new CrossbowTarget( this );
                    }
                }
                else
                {
                    from.SendMessage( "You must string your bow. Please select a bow stringer." );
                    from.Target = new StringerTarget( this );
                }
            }
           
            else
                return;
        }
       
        /*public override void OnDelete()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( module != null )
                module.Delete();
           
            base.OnDelete();
        }*/
       
        public override bool OnEquip( Mobile from )
        {
            m_Mobile = from;
           
            return true;
        }
       
        public override bool CanEquip( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( from != null && !module.HasBowString )
            {
                from.SendMessage( "You cannot use that without a string." );
                return false;
            }
           
            base.CanEquip( from );
           
            return true;
        }
       
        public virtual Item AmmoArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return new Arrow();
                case ArrowType.Poison:
                    return new PoisonArrow();
                case ArrowType.Explosive:
                    return new ExplosiveArrow();
                case ArrowType.ArmorPiercing:
                    return new ArmorPiercingArrow();
                case ArrowType.Freeze:
                    return new FreezeArrow();
                case ArrowType.Lightning:
                    return new LightningArrow();
                   
                default:
                    return new Arrow();
            }
        }
       
        public virtual Type GetArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return typeof( Arrow );
                case ArrowType.Poison:
                    return typeof( PoisonArrow );
                case ArrowType.Explosive:
                    return typeof( ExplosiveArrow );
                case ArrowType.ArmorPiercing:
                    return typeof( ArmorPiercingArrow );
                case ArrowType.Freeze:
                    return typeof( FreezeArrow );
                case ArrowType.Lightning:
                    return typeof( LightningArrow );
                   
                default:
                    return typeof( Arrow );
            }
        }
       
        public virtual Item AmmoBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return new Bolt();
                case BoltType.Poison:
                    return new PoisonBolt();
                case BoltType.Explosive:
                    return new ExplosiveBolt();
                case BoltType.ArmorPiercing:
                    return new ArmorPiercingBolt();
                case BoltType.Freeze:
                    return new FreezeBolt();
                case BoltType.Lightning:
                    return new LightningBolt();
                   
                default:
                    return new Bolt();
            }
        }
       
        public virtual Type GetBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return typeof( Bolt );
                case BoltType.Poison:
                    return typeof( PoisonBolt );
                case BoltType.Explosive:
                    return typeof( ExplosiveBolt );
                case BoltType.ArmorPiercing:
                    return typeof( ArmorPiercingBolt );
                case BoltType.Freeze:
                    return typeof( FreezeBolt );
                case BoltType.Lightning:
                    return typeof( LightningBolt );
                   
                default:
                    return typeof( Bolt );
            }
        }
       
        public override void GetProperties( ObjectPropertyList list )
        {
            base.GetProperties(list);
           
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( module != null )
            {
                ArrayList strings = new ArrayList();
               
                strings.Add( ( "---------------" ) );
               
                if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                    this is MagicalShortbow || this is Yumi )
                {
                    strings.Add( ( "Quiver Using: " + module.m_ArrowType ) );
                }
               
                if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                {
                    strings.Add( ( "Quiver Using: " + module.m_BoltType ) );
                }
               
                strings.Add( ( "lbs per Pull: " + module.m_PullWeight ) );
                strings.Add( ( "String Str: "  + module.m_Strength ) );
               
                string toAdd = "";
                int amount = strings.Count;
                int current = 1;
               
                foreach ( string str in strings )
                {
                    toAdd += str;
                   
                    if ( current != amount )
                        toAdd += "\n";
                   
                    ++current;
                }
               
                if ( toAdd != "" )
                    list.Add( 1070722, toAdd );
            }
            else
            {
                return;
            }
        }
        //--<<Advanced Archery Edit>>---------------------[End 4/4]
 
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
 
            writer.Write( (int) 3 ); // version
 
            writer.Write( (bool) m_Balanced );
            writer.Write( (int) m_Velocity );
        }
 
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
 
            int version = reader.ReadInt();
 
            switch ( version )
            {
                case 3:
                {
                    m_Balanced = reader.ReadBool();
                    m_Velocity = reader.ReadInt();
 
                    goto case 2;
                }
                case 2:
                case 1:
                {
                    break;
                }
                case 0:
                {
                    /*m_EffectID =*/ reader.ReadInt();
                    break;
                }
            }
 
            if ( version < 2 )
            {
                WeaponAttributes.MageWeapon = 0;
                WeaponAttributes.UseBestSkill = 0;
            }
        }
    }
}
This console output appears while I'm targeting the arrow:
Code:
Code making it to OnTarget.
Code making it to arrow check.
Item type is: Server.Items.PoisonArrow.
Using arrow selection: Poison
And when I shoot.....Nada. Nothing Appears, and nothing shoots
 

daat99

Moderator
Staff member
Ok, we need to break this down a bit more than.
Please add console write to the OnFired and OnSwing method.

Code:
public override TimeSpan OnSwing( Mobile attacker, Mobile defender )
{
    Console.WriteLine("OnSwing started".);

Code:
public virtual bool OnFired( Mobile attacker, Mobile defender )
{
    Console.WriteLine("OnFired started".);
 
Error:
Code:
Errors:
+ Items/Weapons/Ranged/BaseRanged.cs:
    CS1001: Line 120: Identifier expected
    CS1001: Line 246: Identifier expected
Exactly as you put it:
Code:
public override TimeSpan OnSwing( Mobile attacker, Mobile defender )
        {
                Console.WriteLine("OnSwing started".);
 

daat99

Moderator
Staff member
You (I) placed the dot outside the string (quotes).

I recommend adopting a good habit to not treat a code as copy/paste but try to understand what it does and write your own similar code.
 
I guess that part's working.
Code:
OnSwing started.
OnFired started.
OnSwing started.
OnFired started.
OnSwing started.
OnFired started.
OnSwing started.
OnFired started.
OnSwing started.
OnFired started.
OnSwing started.
OnFired started.
 

daat99

Moderator
Staff member
Now that we know that Onfired is being called we need to know what happens there.
Please look for all the "return" instructions in the OnFired method and add a meaningful Console.WriteLine just before it.
Once you do please repeat the test and post both the updated code as well as the console output.

PS
You can remove the OnSwing console write because we already know it always calls for OnFired after OnSwing.
 
Got one false.
Code:
Returning false because not consuming
Returning false because not consuming
Returning false because not consuming
Not sure if the code actually says it's not consuming, but that's what I put. Here's what I put in.
Code:
if( attacker.Player &&
              ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
              (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                        Console.WriteLine("Returning false because not consuming");
 
Not sure how helpful this is, but here is a side-by-side comparison of a way older version that works (tested) vs mine.
Mine:
Code:
using System;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Mobiles;
using Server.Targeting;
using System.Collections;
using System.Collections.Generic;
using Server.Enums;
using Server.ACC.CM;
using Server.LucidNagual;
 
namespace Server.Items
{
    public abstract class BaseRanged : BaseMeleeWeapon
    {
        //--<<Advanced Archery Edit>>---------------------[Start 1/4]
        //SkillModule edit.
        private BaseRangedModule m_BaseRangedModule;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public BaseRangedModule BaseRangedModule
        {
            get
            {
                BaseRangedModule existingModule = ( BaseRangedModule )CentralMemory.GetModule( this.Serial, typeof( BaseRangedModule ) );
               
                if ( existingModule == null )
                {
                    BaseRangedModule module = new BaseRangedModule( this.Serial );
                    CentralMemory.AppendModule( this.Serial, module, true );
                   
                    return ( m_BaseRangedModule = module as BaseRangedModule );
                }
                else
                {
                    if ( m_BaseRangedModule != null )
                        return m_BaseRangedModule;
                   
                    return ( m_BaseRangedModule = existingModule as BaseRangedModule );
                }
            }
        }
        //SkillModule edit.
       
        public static int PlayerFreezeTimer = 2;
        public static int NPCFreezeTimer = 2;       
       
        private bool m_IsLevelable;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public ArrowType ArrowSelection    { get { return m_BaseRangedModule.ArrowSelection; } set { m_BaseRangedModule.ArrowSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public BoltType BoltSelection { get { return m_BaseRangedModule.BoltSelection; } set { m_BaseRangedModule.BoltSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public StringStrength StringStrengthSelection { get { return m_BaseRangedModule.StringStrengthSelection; } set { m_BaseRangedModule.StringStrengthSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public PoundsPerPull PullWeightSelection { get { return m_BaseRangedModule.PullWeightSelection; } set { m_BaseRangedModule.PullWeightSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool HasBowString { get{ return m_BaseRangedModule.HasBowString; } set{ m_BaseRangedModule.HasBowString = value; } }       
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool IsLevelable { get{ return m_IsLevelable; } set{ m_IsLevelable = value; } }       
               
       
        private static Mobile m_Mobile;
        private static BaseRanged BRanged;
       
        public static TimeSpan StringWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextStringWarning;
        public static TimeSpan AmmoWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextAmmoWarning;
        //--<<Advanced Archery Edit>>---------------------[End 1/4]
 
        public abstract int EffectID{ get; }
        public abstract Type AmmoType{ get; }
        public abstract Item Ammo{ get; }
 
        public override int DefHitSound{ get{ return 0x234; } }
        public override int DefMissSound{ get{ return 0x238; } }
 
        public override SkillName DefSkill{ get{ return SkillName.Archery; } }
        public override WeaponType DefType{ get{ return WeaponType.Ranged; } }
        public override WeaponAnimation DefAnimation{ get{ return WeaponAnimation.ShootXBow; } }
 
        public override SkillName AccuracySkill{ get{ return SkillName.Archery; } }
 
        private Timer m_RecoveryTimer; // so we don't start too many timers
        private bool m_Balanced;
        private int m_Velocity;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool Balanced
        {
            get{ return m_Balanced; }
            set{ m_Balanced = value; InvalidateProperties(); }
        }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public int Velocity
        {
            get{ return m_Velocity; }
            set{ m_Velocity = value; InvalidateProperties(); }
        }
 
        public BaseRanged( int itemID ) : base( itemID )
        {
        }
 
        public BaseRanged( Serial serial ) : base( serial )
        {
        }
 
        public override TimeSpan OnSwing( Mobile attacker, Mobile defender )
        {
            WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
 
            // Make sure we've been standing still for .25/.5/1 second depending on Era
            if ( DateTime.Now > (attacker.LastMoveTime + TimeSpan.FromSeconds( Core.SE ? 0.25 : (Core.AOS ? 0.5 : 1.0) )) || (Core.AOS && WeaponAbility.GetCurrentAbility( attacker ) is MovingShot) )
            {
                bool canSwing = true;
 
                if ( Core.AOS )
                {
                    canSwing = ( !attacker.Paralyzed && !attacker.Frozen );
 
                    if ( canSwing )
                    {
                        Spell sp = attacker.Spell as Spell;
 
                        canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
                    }
                }
 
                #region Dueling
                if ( attacker is PlayerMobile )
                {
                    PlayerMobile pm = (PlayerMobile)attacker;
 
                    if ( pm.DuelContext != null && !pm.DuelContext.CheckItemEquip( attacker, this ) )
                        canSwing = false;
                }
                #endregion
 
                if ( canSwing && attacker.HarmfulCheck( defender ) )
                {
                    attacker.DisruptiveAction();
                    attacker.Send( new Swing( 0, attacker, defender ) );
 
                    if ( OnFired( attacker, defender ) )
                    {
                        if ( CheckHit( attacker, defender ) )
                            OnHit( attacker, defender );
                        else
                            OnMiss( attacker, defender );
                    }
                }
 
                attacker.RevealingAction();
 
                return GetDelay( attacker );
            }
            else
            {
                attacker.RevealingAction();
 
                return TimeSpan.FromSeconds( 0.25 );
            }
        }
 
        public override void OnHit( Mobile attacker, Mobile defender, double damageBonus )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 2/4]
            if ( attacker == null || defender == null )
                return;
           
            MoreBaseRanged.CustomAmmoCheck( attacker, defender, AmmoType );
           
            if ( Ammo == null )
                attacker.SendMessage( "You are out of arrows, or may have to choose a different type of arrow by double clicking the bow." );
            //--<<Advanced Archery Edit>>---------------------[End 2/4]
           
            if ( attacker.Player && !defender.Player && (defender.Body.IsAnimal || defender.Body.IsMonster) && 0.4 >= Utility.RandomDouble() )
                defender.AddToBackpack( Ammo );
 
            if ( Core.ML && m_Velocity > 0 )
            {
                int bonus = (int) attacker.GetDistanceToSqrt( defender );
 
                if ( bonus > 0 && m_Velocity > Utility.Random( 100 ) )
                {
                    AOS.Damage( defender, attacker, bonus * 3, 100, 0, 0, 0, 0 );
 
                    if ( attacker.Player )
                        attacker.SendLocalizedMessage( 1072794 ); // Your arrow hits its mark with velocity!
 
                    if ( defender.Player )
                        defender.SendLocalizedMessage( 1072795 ); // You have been hit by an arrow with velocity!
                }
            }
 
            base.OnHit( attacker, defender, damageBonus );
        }
 
        public override void OnMiss( Mobile attacker, Mobile defender )
        {
            if ( attacker.Player && 0.4 >= Utility.RandomDouble() )
            {
                if ( Core.SE )
                {
                    PlayerMobile p = attacker as PlayerMobile;
 
                    if ( p != null )
                    {
                        Type ammo = AmmoType;
 
                        if ( p.RecoverableAmmo.ContainsKey( ammo ) )
                            p.RecoverableAmmo[ ammo ]++;
                        else
                            p.RecoverableAmmo.Add( ammo, 1 );
 
                        if ( !p.Warmode )
                        {
                            if ( m_RecoveryTimer == null )
                                m_RecoveryTimer = Timer.DelayCall( TimeSpan.FromSeconds( 10 ), new TimerCallback( p.RecoverAmmo ) );
 
                            if ( !m_RecoveryTimer.Running )
                                m_RecoveryTimer.Start();
                        }
                    else
                        Ammo.MoveToWorld( new Point3D( defender.X + Utility.RandomMinMax( -1, 1 ), defender.Y + Utility.RandomMinMax( -1, 1 ), defender.Z ), defender.Map );
                    }
                }
            }
 
            base.OnMiss( attacker, defender );
        }
 
        public virtual bool OnFired( Mobile attacker, Mobile defender )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 3/4]
            PlayerMobile a_pm = attacker as PlayerMobile;
            Container pack = attacker.Backpack;
            BaseQuiver quiver = attacker.FindItemOnLayer( Layer.MiddleTorso ) as BaseQuiver;
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( !module.HasBowString )
            {
                if ( DateTime.Now >= m_NextStringWarning )
                {
                    m_NextStringWarning = DateTime.Now + StringWarningDelay;
                    attacker.SendMessage( "You need a string to use this bow. See a local fletcher to apply the string." );
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "String is null");
                        return false;
                }
            }
           
            if ( Ammo == null )
            {
                if ( DateTime.Now >= m_NextAmmoWarning )
                {
                    m_NextAmmoWarning = DateTime.Now + AmmoWarningDelay;
                    attacker.SendMessage( "You are out of ammo." );
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "Ammo is null");
                        return false;
                }
            }
           
            if( attacker.Player && quiver != null && quiver.LowerAmmoCost > Utility.Random( 100 ) )
            {
                attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                        Console.WriteLine("Returning true because quiver.lowerammocost.");
                return true;
            }
           
            if( attacker.Player &&
              ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
              (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                        Console.WriteLine("Returning false because not consuming");
                return false;
           
            attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
            return true;
            //--<<Advanced Archery Edit>>---------------------[End 3/4]
       
        if ( attacker.Player )
            {
                //BaseQuiver quiver = attacker.FindItemOnLayer( Layer.Cloak ) as BaseQuiver;
                //Container pack = attacker.Backpack;
 
                if ( quiver == null || Utility.Random( 100 ) >= quiver.LowerAmmoCost )
                {
                    if (quiver != null)
                    {
                        Item[] typedItems = quiver.FindItemsByType(typeof(PoisonArrow), true);
                        Console.WriteLine("FindItemsByType was able to find {0} items.", typedItems.Length); //try Count if it doesn't compile
                        if (typedItems.Length > 0)
                        {
                            Console.WriteLine("The amount of the first item is: {0}", typedItems[0].Amount);
                            typedItems[0].Consume(1);
                            Console.WriteLine("The amount of the first item after consuming 1 is: {1}", typedItems[0].Amount);
                        }
                    }
                    if ( quiver != null && quiver.ConsumeTotal( AmmoType, 1 ) )
                        quiver.InvalidateWeight();
                    else if ( pack == null || !pack.ConsumeTotal( AmmoType, 1 ) )
                        return false;
                }
                else if ( quiver.FindItemByType( AmmoType ) == null && ( pack == null || pack.FindItemByType( AmmoType ) == null ) )
                {
                    // lower ammo cost should not work when we have no ammo at all
                    return false;
                }
            }
 
            attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
 
            return true;
        }
       
        //--<<Advanced Archery Edit>>---------------------[Start 4/4]
        public override void OnDoubleClick( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( IsChildOf( from.Backpack ) || Parent == from )
            {
                if ( module.HasBowString )
                {
                    if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                        this is MagicalShortbow || this is Yumi )
                    {
                        from.SendMessage( "Please choose which type of arrows you wish to use." );
                        from.Target = new BowTarget( this );
                    }
                   
                    if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                    {
                        from.SendMessage( "Please choose which type of bolts you wish to use." );
                        from.Target = new CrossbowTarget( this );
                    }
                }
                else
                {
                    from.SendMessage( "You must string your bow. Please select a bow stringer." );
                    from.Target = new StringerTarget( this );
                }
            }
           
            else
                return;
        }
       
        /*public override void OnDelete()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( module != null )
                module.Delete();
           
            base.OnDelete();
        }*/
       
        public override bool OnEquip( Mobile from )
        {
            m_Mobile = from;
           
            return true;
        }
       
        public override bool CanEquip( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( from != null && !module.HasBowString )
            {
                from.SendMessage( "You cannot use that without a string." );
                return false;
            }
           
            base.CanEquip( from );
           
            return true;
        }
       
        public virtual Item AmmoArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return new Arrow();
                case ArrowType.Poison:
                    return new PoisonArrow();
                case ArrowType.Explosive:
                    return new ExplosiveArrow();
                case ArrowType.ArmorPiercing:
                    return new ArmorPiercingArrow();
                case ArrowType.Freeze:
                    return new FreezeArrow();
                case ArrowType.Lightning:
                    return new LightningArrow();
                   
                default:
                    return new Arrow();
            }
        }
       
        public virtual Type GetArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return typeof( Arrow );
                case ArrowType.Poison:
                    return typeof( PoisonArrow );
                case ArrowType.Explosive:
                    return typeof( ExplosiveArrow );
                case ArrowType.ArmorPiercing:
                    return typeof( ArmorPiercingArrow );
                case ArrowType.Freeze:
                    return typeof( FreezeArrow );
                case ArrowType.Lightning:
                    return typeof( LightningArrow );
                   
                default:
                    return typeof( Arrow );
            }
        }
       
        public virtual Item AmmoBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return new Bolt();
                case BoltType.Poison:
                    return new PoisonBolt();
                case BoltType.Explosive:
                    return new ExplosiveBolt();
                case BoltType.ArmorPiercing:
                    return new ArmorPiercingBolt();
                case BoltType.Freeze:
                    return new FreezeBolt();
                case BoltType.Lightning:
                    return new LightningBolt();
                   
                default:
                    return new Bolt();
            }
        }
       
        public virtual Type GetBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return typeof( Bolt );
                case BoltType.Poison:
                    return typeof( PoisonBolt );
                case BoltType.Explosive:
                    return typeof( ExplosiveBolt );
                case BoltType.ArmorPiercing:
                    return typeof( ArmorPiercingBolt );
                case BoltType.Freeze:
                    return typeof( FreezeBolt );
                case BoltType.Lightning:
                    return typeof( LightningBolt );
                   
                default:
                    return typeof( Bolt );
            }
        }
       
        public override void GetProperties( ObjectPropertyList list )
        {
            base.GetProperties(list);
           
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( module != null )
            {
                ArrayList strings = new ArrayList();
               
                strings.Add( ( "---------------" ) );
               
                if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                    this is MagicalShortbow || this is Yumi )
                {
                    strings.Add( ( "Quiver Using: " + module.m_ArrowType ) );
                }
               
                if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                {
                    strings.Add( ( "Quiver Using: " + module.m_BoltType ) );
                }
               
                strings.Add( ( "lbs per Pull: " + module.m_PullWeight ) );
                strings.Add( ( "String Str: "  + module.m_Strength ) );
               
                string toAdd = "";
                int amount = strings.Count;
                int current = 1;
               
                foreach ( string str in strings )
                {
                    toAdd += str;
                   
                    if ( current != amount )
                        toAdd += "\n";
                   
                    ++current;
                }
               
                if ( toAdd != "" )
                    list.Add( 1070722, toAdd );
            }
            else
            {
                return;
            }
        }
        //--<<Advanced Archery Edit>>---------------------[End 4/4]
 
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
 
            writer.Write( (int) 3 ); // version
 
            writer.Write( (bool) m_Balanced );
            writer.Write( (int) m_Velocity );
        }
 
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
 
            int version = reader.ReadInt();
 
            switch ( version )
            {
                case 3:
                {
                    m_Balanced = reader.ReadBool();
                    m_Velocity = reader.ReadInt();
 
                    goto case 2;
                }
                case 2:
                case 1:
                {
                    break;
                }
                case 0:
                {
                    /*m_EffectID =*/ reader.ReadInt();
                    break;
                }
            }
 
            if ( version < 2 )
            {
                WeaponAttributes.MageWeapon = 0;
                WeaponAttributes.UseBestSkill = 0;
            }
        }
    }
}

The older working one:
Code:
using System;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Mobiles;
using Server.Targeting;
using System.Collections;
using Server.Enums;
using Server.ACC.CM;
using Server.LucidNagual;
 
 
namespace Server.Items
{
    public abstract class BaseRanged : BaseMeleeWeapon
    {
        //--<<Advanced Archery Edit>>---------------------[Start 1/4]
        //SkillModule edit.
        private BaseRangedModule m_BaseRangedModule;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public BaseRangedModule BaseRangedModule
        {
            get
            {
                BaseRangedModule existingModule = ( BaseRangedModule )CentralMemory.GetModule( this.Serial, typeof( BaseRangedModule ) );
               
                if ( existingModule == null )
                {
                    BaseRangedModule module = new BaseRangedModule( this.Serial );
                    CentralMemory.AppendModule( this.Serial, module, true );
                   
                    return ( m_BaseRangedModule = module as BaseRangedModule );
                }
                else
                {
                    if ( m_BaseRangedModule != null )
                        return m_BaseRangedModule;
                   
                    return ( m_BaseRangedModule = existingModule as BaseRangedModule );
                }
            }
        }
        //SkillModule edit.
       
        public static int PlayerFreezeTimer = 2;
        public static int NPCFreezeTimer = 2;       
       
        private bool m_IsLevelable;
       
        [CommandProperty( AccessLevel.GameMaster )]
        public ArrowType ArrowSelection    { get { return m_BaseRangedModule.ArrowSelection; } set { m_BaseRangedModule.ArrowSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public BoltType BoltSelection { get { return m_BaseRangedModule.BoltSelection; } set { m_BaseRangedModule.BoltSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public StringStrength StringStrengthSelection { get { return m_BaseRangedModule.StringStrengthSelection; } set { m_BaseRangedModule.StringStrengthSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public PoundsPerPull PullWeightSelection { get { return m_BaseRangedModule.PullWeightSelection; } set { m_BaseRangedModule.PullWeightSelection = value; } }
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool HasBowString { get{ return m_BaseRangedModule.HasBowString; } set{ m_BaseRangedModule.HasBowString = value; } }       
       
        [CommandProperty( AccessLevel.GameMaster )]
        public bool IsLevelable { get{ return m_IsLevelable; } set{ m_IsLevelable = value; } }       
               
       
        private static Mobile m_Mobile;
        private static BaseRanged BRanged;
       
        public static TimeSpan StringWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextStringWarning;
        public static TimeSpan AmmoWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextAmmoWarning;
        //--<<Advanced Archery Edit>>---------------------[End 1/4]
       
        public abstract int EffectID{ get; }
        public abstract Type AmmoType{ get; }
        public abstract Item Ammo{ get; }
       
        public override int DefHitSound{ get{ return 0x234; } }
        public override int DefMissSound{ get{ return 0x238; } }
       
        public override SkillName DefSkill{ get{ return SkillName.Archery; } }
        public override WeaponType DefType{ get{ return WeaponType.Ranged; } }
        public override WeaponAnimation DefAnimation{ get{ return WeaponAnimation.ShootXBow; } }
       
        public override SkillName AccuracySkill{ get{ return SkillName.Archery; } }
       
        public BaseRanged( int itemID ) : base( itemID )
        {
        }
       
        public BaseRanged( Serial serial ) : base( serial )
        {
            BRanged = this;
        }
       
        public static void Initialize()
        {
            Mobile from = m_Mobile;
            //Mobile m = (Mobile)parent;
            //BaseWeapon weapon = m.Weapon as BaseWeapon;
        }
       
        public override TimeSpan OnSwing( Mobile attacker, Mobile defender )
        {
            WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
           
            // Make sure we've been standing still for .25/.5/1 second depending on Era
            if ( DateTime.Now > ( attacker.LastMoveTime + TimeSpan.FromSeconds( Core.SE ? 0.25 : (Core.AOS ? 0.5 : 1.0) )) || (Core.AOS && WeaponAbility.GetCurrentAbility( attacker ) is MovingShot) )
            {
                bool canSwing = true;
               
                if ( Core.AOS )
                {
                    canSwing = ( !attacker.Paralyzed && !attacker.Frozen );
                   
                    if ( canSwing )
                    {
                        Spell sp = attacker.Spell as Spell;
                       
                        canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
                    }
                }
               
                if ( canSwing && attacker.HarmfulCheck( defender ) )
                {
                    attacker.DisruptiveAction();
                    attacker.Send( new Swing( 0, attacker, defender ) );
                   
                    if ( OnFired( attacker, defender ) )
                    {
                        if ( CheckHit( attacker, defender ) )
                            OnHit( attacker, defender );
                        else
                            OnMiss( attacker, defender );
                    }
                }
               
                attacker.RevealingAction();
               
                return GetDelay( attacker );
            }
            else
            {
                attacker.RevealingAction();
               
                return TimeSpan.FromSeconds( 0.25 );
            }
        }
       
        public override void OnHit( Mobile attacker, Mobile defender )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 2/4]
            if ( attacker == null || defender == null )
                return;
           
            MoreBaseRanged.CustomAmmoCheck( attacker, defender, AmmoType );
           
            if ( Ammo == null )
                attacker.SendMessage( "You are out of arrows, or may have to choose a different type of arrow by double clicking the bow." );
            //--<<Advanced Archery Edit>>---------------------[End 2/4]
           
            if ( attacker.Player && !defender.Player && ( defender.Body.IsAnimal || defender.Body.IsMonster ) && 0.4 >= Utility.RandomDouble() )
                defender.AddToBackpack( Ammo );
           
            base.OnHit( attacker, defender );
        }
       
        public override void OnMiss( Mobile attacker, Mobile defender )
        {
            if ( attacker.Player && 0.4 >= Utility.RandomDouble() )
                Ammo.MoveToWorld( new Point3D( defender.X + Utility.RandomMinMax( -1, 1 ), defender.Y + Utility.RandomMinMax( -1, 1 ), defender.Z ), defender.Map );
           
            base.OnMiss( attacker, defender );
        }
       
        public virtual bool OnFired( Mobile attacker, Mobile defender )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 3/4]
            PlayerMobile a_pm = attacker as PlayerMobile;
            Container pack = attacker.Backpack;
            BaseQuiver quiver = attacker.FindItemOnLayer( Layer.MiddleTorso ) as BaseQuiver;
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( !module.HasBowString )
            {
                if ( DateTime.Now >= m_NextStringWarning )
                {
                    m_NextStringWarning = DateTime.Now + StringWarningDelay;
                    attacker.SendMessage( "You need a string to use this bow. See a local fletcher to apply the string." );
                    return false;
                }
                else
                    return false;
            }
           
            if ( Ammo == null )
            {
                if ( DateTime.Now >= m_NextAmmoWarning )
                {
                    m_NextAmmoWarning = DateTime.Now + AmmoWarningDelay;
                    attacker.SendMessage( "You are out of ammo." );
                    return false;
                }
                else
                    return false;
            }
           
            if( attacker.Player && quiver != null && quiver.LowerAmmoCost > Utility.Random( 100 ) )
            {
                attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                return true;
            }
           
            if( attacker.Player &&
              ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
              (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                return false;
           
            attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
            return true;
            //--<<Advanced Archery Edit>>---------------------[End 3/4]
        }
       
        //--<<Advanced Archery Edit>>---------------------[Start 4/4]
        public override void OnDoubleClick( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( IsChildOf( from.Backpack ) || Parent == from )
            {
                if ( module.HasBowString )
                {
                    if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                        this is MagicalShortbow || this is Yumi )
                    {
                        from.SendMessage( "Please choose which type of arrows you wish to use." );
                        from.Target = new BowTarget( this );
                    }
                   
                    if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                    {
                        from.SendMessage( "Please choose which type of bolts you wish to use." );
                        from.Target = new CrossbowTarget( this );
                    }
                }
                else
                {
                    from.SendMessage( "You must string your bow. Please select a bow stringer." );
                    from.Target = new StringerTarget( this );
                }
            }
           
            else
                return;
        }
       
        /*public override void OnDelete()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( module != null )
                module.Delete();
           
            base.OnDelete();
        }*/
       
        public override bool OnEquip( Mobile from )
        {
            m_Mobile = from;
           
            return true;
        }
       
        public override bool CanEquip( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( from != null && !module.HasBowString )
            {
                from.SendMessage( "You cannot use that without a string." );
                return false;
            }
           
            base.CanEquip( from );
           
            return true;
        }
       
        public virtual Item AmmoArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return new Arrow();
                case ArrowType.Poison:
                    return new PoisonArrow();
                case ArrowType.Explosive:
                    return new ExplosiveArrow();
                case ArrowType.ArmorPiercing:
                    return new ArmorPiercingArrow();
                case ArrowType.Freeze:
                    return new FreezeArrow();
                case ArrowType.Lightning:
                    return new LightningArrow();
                   
                default:
                    return new Arrow();
            }
        }
       
        public virtual Type GetArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return typeof( Arrow );
                case ArrowType.Poison:
                    return typeof( PoisonArrow );
                case ArrowType.Explosive:
                    return typeof( ExplosiveArrow );
                case ArrowType.ArmorPiercing:
                    return typeof( ArmorPiercingArrow );
                case ArrowType.Freeze:
                    return typeof( FreezeArrow );
                case ArrowType.Lightning:
                    return typeof( LightningArrow );
                   
                default:
                    return typeof( Arrow );
            }
        }
       
        public virtual Item AmmoBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return new Bolt();
                case BoltType.Poison:
                    return new PoisonBolt();
                case BoltType.Explosive:
                    return new ExplosiveBolt();
                case BoltType.ArmorPiercing:
                    return new ArmorPiercingBolt();
                case BoltType.Freeze:
                    return new FreezeBolt();
                case BoltType.Lightning:
                    return new LightningBolt();
                   
                default:
                    return new Bolt();
            }
        }
       
        public virtual Type GetBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
           
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return typeof( Bolt );
                case BoltType.Poison:
                    return typeof( PoisonBolt );
                case BoltType.Explosive:
                    return typeof( ExplosiveBolt );
                case BoltType.ArmorPiercing:
                    return typeof( ArmorPiercingBolt );
                case BoltType.Freeze:
                    return typeof( FreezeBolt );
                case BoltType.Lightning:
                    return typeof( LightningBolt );
                   
                default:
                    return typeof( Bolt );
            }
        }
       
        public override void GetProperties( ObjectPropertyList list )
        {
            base.GetProperties(list);
           
            BaseRangedModule module = this.BaseRangedModule;
           
            if ( module != null )
            {
                ArrayList strings = new ArrayList();
               
                strings.Add( ( "---------------" ) );
               
                if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                    this is MagicalShortbow || this is Yumi )
                {
                    strings.Add( ( "Quiver Using: " + module.m_ArrowType ) );
                }
               
                if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                {
                    strings.Add( ( "Quiver Using: " + module.m_BoltType ) );
                }
               
                strings.Add( ( "lbs per Pull: " + module.m_PullWeight ) );
                strings.Add( ( "String Str: "  + module.m_Strength ) );
               
                string toAdd = "";
                int amount = strings.Count;
                int current = 1;
               
                foreach ( string str in strings )
                {
                    toAdd += str;
                   
                    if ( current != amount )
                        toAdd += "\n";
                   
                    ++current;
                }
               
                if ( toAdd != "" )
                    list.Add( 1070722, toAdd );
            }
            else
            {
                return;
            }
        }
        //--<<Advanced Archery Edit>>---------------------[End 4/4]
       
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
            writer.Write( (int) 2 ); // version
        }
       
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
            int version = reader.ReadInt();
           
            switch ( version )
            {
                case 2:
                case 1:
                    {
                        break;
                    }
                case 0:
                    {
                        /*m_EffectID =*/ reader.ReadInt();
                        break;
                    }
            }
           
            if ( version < 2 )
            {
                WeaponAttributes.MageWeapon = 0;
                WeaponAttributes.UseBestSkill = 0;
            }
        }
    }
}
The old one comes from the RunUO 2.0 Final Re-Pack made by seanandre, found here:http://www.runuo.com/community/threads/runuo-2-0-final-re-pack.102954/
The arrows do fire from the quiver on this server, but I don't see why. Hope this is useful
 

daat99

Moderator
Staff member
Please move the debug code I posted to be before that if statement that return false for not consuming.
We need to know what's going on before that line and the debug chunk of code should do the trick.
 
Okay, so I don't know if this is how you wanted it, but this is what I put in.
Code:
if ( quiver != null )
            {
                    Item[] typedItems = quiver.FindItemsByType( typeof( LightningArrow ), true );
                    Console.WriteLine("FindItemsByType was able to find {0} items.", typedItems.Length); //try Count if it doesn't compile
                    if ( typedItems.Length > 0 )
                    {
                        Console.WriteLine("The amount of the first item is: {0}", typedItems[0].Amount);
                        typedItems[0].Consume( 1 );
                        Console.WriteLine("The amount of the first item after consuming 1 is: {1}", typedItems[0].Amount);
                    }
            }
           
            if( attacker.Player &&
              ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
              (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                        Console.WriteLine("Returning false because not consuming");
                return false;
And nothing appeared in the console
 

daat99

Moderator
Staff member
I have no idea where you added this to the code if you keep posting just snippets without context :(
 
I indicated the edit last made
Code:
using System;
using Server.Items;
using Server.Network;
using Server.Spells;
using Server.Mobiles;
using Server.Targeting;
using System.Collections;
using System.Collections.Generic;
using Server.Enums;
using Server.ACC.CM;
using Server.LucidNagual;
 
namespace Server.Items
{
    public abstract class BaseRanged : BaseMeleeWeapon
    {
        //--<<Advanced Archery Edit>>---------------------[Start 1/4]
        //SkillModule edit.
        private BaseRangedModule m_BaseRangedModule;
     
        [CommandProperty( AccessLevel.GameMaster )]
        public BaseRangedModule BaseRangedModule
        {
            get
            {
                BaseRangedModule existingModule = ( BaseRangedModule )CentralMemory.GetModule( this.Serial, typeof( BaseRangedModule ) );
             
                if ( existingModule == null )
                {
                    BaseRangedModule module = new BaseRangedModule( this.Serial );
                    CentralMemory.AppendModule( this.Serial, module, true );
                 
                    return ( m_BaseRangedModule = module as BaseRangedModule );
                }
                else
                {
                    if ( m_BaseRangedModule != null )
                        return m_BaseRangedModule;
                 
                    return ( m_BaseRangedModule = existingModule as BaseRangedModule );
                }
            }
        }
        //SkillModule edit.
     
        public static int PlayerFreezeTimer = 2;
        public static int NPCFreezeTimer = 2;     
     
        private bool m_IsLevelable;
     
        [CommandProperty( AccessLevel.GameMaster )]
        public ArrowType ArrowSelection    { get { return m_BaseRangedModule.ArrowSelection; } set { m_BaseRangedModule.ArrowSelection = value; } }
     
        [CommandProperty( AccessLevel.GameMaster )]
        public BoltType BoltSelection { get { return m_BaseRangedModule.BoltSelection; } set { m_BaseRangedModule.BoltSelection = value; } }
     
        [CommandProperty( AccessLevel.GameMaster )]
        public StringStrength StringStrengthSelection { get { return m_BaseRangedModule.StringStrengthSelection; } set { m_BaseRangedModule.StringStrengthSelection = value; } }
     
        [CommandProperty( AccessLevel.GameMaster )]
        public PoundsPerPull PullWeightSelection { get { return m_BaseRangedModule.PullWeightSelection; } set { m_BaseRangedModule.PullWeightSelection = value; } }
     
        [CommandProperty( AccessLevel.GameMaster )]
        public bool HasBowString { get{ return m_BaseRangedModule.HasBowString; } set{ m_BaseRangedModule.HasBowString = value; } }     
     
        [CommandProperty( AccessLevel.GameMaster )]
        public bool IsLevelable { get{ return m_IsLevelable; } set{ m_IsLevelable = value; } }     
             
     
        private static Mobile m_Mobile;
        private static BaseRanged BRanged;
     
        public static TimeSpan StringWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextStringWarning;
        public static TimeSpan AmmoWarningDelay = TimeSpan.FromSeconds( 10.0 );
        public static DateTime m_NextAmmoWarning;
        //--<<Advanced Archery Edit>>---------------------[End 1/4]
 
        public abstract int EffectID{ get; }
        public abstract Type AmmoType{ get; }
        public abstract Item Ammo{ get; }
 
        public override int DefHitSound{ get{ return 0x234; } }
        public override int DefMissSound{ get{ return 0x238; } }
 
        public override SkillName DefSkill{ get{ return SkillName.Archery; } }
        public override WeaponType DefType{ get{ return WeaponType.Ranged; } }
        public override WeaponAnimation DefAnimation{ get{ return WeaponAnimation.ShootXBow; } }
 
        public override SkillName AccuracySkill{ get{ return SkillName.Archery; } }
 
        private Timer m_RecoveryTimer; // so we don't start too many timers
        private bool m_Balanced;
        private int m_Velocity;
     
        [CommandProperty( AccessLevel.GameMaster )]
        public bool Balanced
        {
            get{ return m_Balanced; }
            set{ m_Balanced = value; InvalidateProperties(); }
        }
     
        [CommandProperty( AccessLevel.GameMaster )]
        public int Velocity
        {
            get{ return m_Velocity; }
            set{ m_Velocity = value; InvalidateProperties(); }
        }
 
        public BaseRanged( int itemID ) : base( itemID )
        {
        }
 
        public BaseRanged( Serial serial ) : base( serial )
        {
        }
 
        public override TimeSpan OnSwing( Mobile attacker, Mobile defender )
        {
            WeaponAbility a = WeaponAbility.GetCurrentAbility( attacker );
 
            // Make sure we've been standing still for .25/.5/1 second depending on Era
            if ( DateTime.Now > (attacker.LastMoveTime + TimeSpan.FromSeconds( Core.SE ? 0.25 : (Core.AOS ? 0.5 : 1.0) )) || (Core.AOS && WeaponAbility.GetCurrentAbility( attacker ) is MovingShot) )
            {
                bool canSwing = true;
 
                if ( Core.AOS )
                {
                    canSwing = ( !attacker.Paralyzed && !attacker.Frozen );
 
                    if ( canSwing )
                    {
                        Spell sp = attacker.Spell as Spell;
 
                        canSwing = ( sp == null || !sp.IsCasting || !sp.BlocksMovement );
                    }
                }
 
                #region Dueling
                if ( attacker is PlayerMobile )
                {
                    PlayerMobile pm = (PlayerMobile)attacker;
 
                    if ( pm.DuelContext != null && !pm.DuelContext.CheckItemEquip( attacker, this ) )
                        canSwing = false;
                }
                #endregion
 
                if ( canSwing && attacker.HarmfulCheck( defender ) )
                {
                    attacker.DisruptiveAction();
                    attacker.Send( new Swing( 0, attacker, defender ) );
 
                    if ( OnFired( attacker, defender ) )
                    {
                        if ( CheckHit( attacker, defender ) )
                            OnHit( attacker, defender );
                        else
                            OnMiss( attacker, defender );
                    }
                }
 
                attacker.RevealingAction();
 
                return GetDelay( attacker );
            }
            else
            {
                attacker.RevealingAction();
 
                return TimeSpan.FromSeconds( 0.25 );
            }
        }
 
        public override void OnHit( Mobile attacker, Mobile defender, double damageBonus )
        {
            //--<<Advanced Archery Edit>>---------------------[Start 2/4]
            if ( attacker == null || defender == null )
                return;
         
            MoreBaseRanged.CustomAmmoCheck( attacker, defender, AmmoType );
         
            if ( Ammo == null )
                attacker.SendMessage( "You are out of arrows, or may have to choose a different type of arrow by double clicking the bow." );
            //--<<Advanced Archery Edit>>---------------------[End 2/4]
         
            if ( attacker.Player && !defender.Player && (defender.Body.IsAnimal || defender.Body.IsMonster) && 0.4 >= Utility.RandomDouble() )
                defender.AddToBackpack( Ammo );
 
            if ( Core.ML && m_Velocity > 0 )
            {
                int bonus = (int) attacker.GetDistanceToSqrt( defender );
 
                if ( bonus > 0 && m_Velocity > Utility.Random( 100 ) )
                {
                    AOS.Damage( defender, attacker, bonus * 3, 100, 0, 0, 0, 0 );
 
                    if ( attacker.Player )
                        attacker.SendLocalizedMessage( 1072794 ); // Your arrow hits its mark with velocity!
 
                    if ( defender.Player )
                        defender.SendLocalizedMessage( 1072795 ); // You have been hit by an arrow with velocity!
                }
            }
 
            base.OnHit( attacker, defender, damageBonus );
        }
 
        public override void OnMiss( Mobile attacker, Mobile defender )
        {
            if ( attacker.Player && 0.4 >= Utility.RandomDouble() )
            {
                if ( Core.SE )
                {
                    PlayerMobile p = attacker as PlayerMobile;
 
                    if ( p != null )
                    {
                        Type ammo = AmmoType;
 
                        if ( p.RecoverableAmmo.ContainsKey( ammo ) )
                            p.RecoverableAmmo[ ammo ]++;
                        else
                            p.RecoverableAmmo.Add( ammo, 1 );
 
                        if ( !p.Warmode )
                        {
                            if ( m_RecoveryTimer == null )
                                m_RecoveryTimer = Timer.DelayCall( TimeSpan.FromSeconds( 10 ), new TimerCallback( p.RecoverAmmo ) );
 
                            if ( !m_RecoveryTimer.Running )
                                m_RecoveryTimer.Start();
                        }
                    else
                        Ammo.MoveToWorld( new Point3D( defender.X + Utility.RandomMinMax( -1, 1 ), defender.Y + Utility.RandomMinMax( -1, 1 ), defender.Z ), defender.Map );
                    }
                }
            }
 
            base.OnMiss( attacker, defender );
        }
 
        public virtual bool OnFired( Mobile attacker, Mobile defender )
        {
                Console.WriteLine("OnFired started.");
            //--<<Advanced Archery Edit>>---------------------[Start 3/4]
            PlayerMobile a_pm = attacker as PlayerMobile;
            Container pack = attacker.Backpack;
            BaseQuiver quiver = attacker.FindItemOnLayer( Layer.MiddleTorso ) as BaseQuiver;
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( !module.HasBowString )
            {
                if ( DateTime.Now >= m_NextStringWarning )
                {
                    m_NextStringWarning = DateTime.Now + StringWarningDelay;
                    attacker.SendMessage( "You need a string to use this bow. See a local fletcher to apply the string." );
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "String is null");
                        return false;
                }
            }
         
            if ( Ammo == null )
            {
                if ( DateTime.Now >= m_NextAmmoWarning )
                {
                    m_NextAmmoWarning = DateTime.Now + AmmoWarningDelay;
                    attacker.SendMessage( "You are out of ammo." );
                        Console.WriteLine("Returning false because there is no ammo");
                    return false;
                }
                else
                {
                        Console.WriteLine("Returning false because {0}", "Ammo is null");
                        return false;
                }
            }
         
            if( attacker.Player && quiver != null && quiver.LowerAmmoCost > Utility.Random( 100 ) )
            {
                attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                        Console.WriteLine("Returning true because quiver.lowerammocost.");
                return true;
            }
 
//NEWEST EDIT
            if ( quiver != null )
            {
                    Item[] typedItems = quiver.FindItemsByType( typeof( LightningArrow ), true );
                    Console.WriteLine("FindItemsByType was able to find {0} items.", typedItems.Length); //try Count if it doesn't compile
                    if ( typedItems.Length > 0 )
                    {
                        Console.WriteLine("The amount of the first item is: {0}", typedItems[0].Amount);
                        typedItems[0].Consume( 1 );
                        Console.WriteLine("The amount of the first item after consuming 1 is: {1}", typedItems[0].Amount);
                    }
            }
         
            if( attacker.Player &&
              ( quiver == null || !quiver.ConsumeTotal( AmmoType, 1 ) ) &&
              (  pack == null ||  !pack.ConsumeTotal( AmmoType, 1 ) ) )
                        Console.WriteLine("Returning false because not consuming");
                return false;
         
            attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                        Console.WriteLine("Returning true because Moving Effect");
            return true;
            //--<<Advanced Archery Edit>>---------------------[End 3/4]
     
        if ( attacker.Player )
            {
                //BaseQuiver quiver = attacker.FindItemOnLayer( Layer.Cloak ) as BaseQuiver;
                //Container pack = attacker.Backpack;
 
                if ( quiver == null || Utility.Random( 100 ) >= quiver.LowerAmmoCost )
                {
                    if ( quiver != null && quiver.ConsumeTotal( AmmoType, 1 ) )
                        quiver.InvalidateWeight();
                    else if ( pack == null || !pack.ConsumeTotal( AmmoType, 1 ) )
            Console.WriteLine("returning false because quiver != null");
                        return false;
                }
                else if ( quiver.FindItemByType( AmmoType ) == null && ( pack == null || pack.FindItemByType( AmmoType ) == null ) )
                {
                    // lower ammo cost should not work when we have no ammo at all
            Console.WriteLine("returning false because ammo");
                    return false;
                }
            }
 
            attacker.MovingEffect( defender, EffectID, 18, 1, false, false );
                        Console.WriteLine("Returning true because Moving Effect");
 
            return true;
        }
     
        //--<<Advanced Archery Edit>>---------------------[Start 4/4]
        public override void OnDoubleClick( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
         
            if ( IsChildOf( from.Backpack ) || Parent == from )
            {
                if ( module.HasBowString )
                {
                    if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                        this is MagicalShortbow || this is Yumi )
                    {
                        from.SendMessage( "Please choose which type of arrows you wish to use." );
                        from.Target = new BowTarget( this );
                    }
                 
                    if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                    {
                        from.SendMessage( "Please choose which type of bolts you wish to use." );
                        from.Target = new CrossbowTarget( this );
                    }
                }
                else
                {
                    from.SendMessage( "You must string your bow. Please select a bow stringer." );
                    from.Target = new StringerTarget( this );
                }
            }
         
            else
                return;
        }
     
        /*public override void OnDelete()
        {
            BaseRangedModule module = this.BaseRangedModule;
         
            if ( module != null )
                module.Delete();
         
            base.OnDelete();
        }*/
     
        public override bool OnEquip( Mobile from )
        {
            m_Mobile = from;
         
            return true;
        }
     
        public override bool CanEquip( Mobile from )
        {
            BaseRangedModule module = this.BaseRangedModule;
 
            if ( from != null && !module.HasBowString )
            {
                from.SendMessage( "You cannot use that without a string." );
                return false;
            }
         
            base.CanEquip( from );
         
            return true;
        }
     
        public virtual Item AmmoArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
         
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return new Arrow();
                case ArrowType.Poison:
                    return new PoisonArrow();
                case ArrowType.Explosive:
                    return new ExplosiveArrow();
                case ArrowType.ArmorPiercing:
                    return new ArmorPiercingArrow();
                case ArrowType.Freeze:
                    return new FreezeArrow();
                case ArrowType.Lightning:
                    return new LightningArrow();
                 
                default:
                    return new Arrow();
            }
        }
     
        public virtual Type GetArrowSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
         
            switch ( module.m_ArrowType )
            {
                case ArrowType.Normal:
                    return typeof( Arrow );
                case ArrowType.Poison:
                    return typeof( PoisonArrow );
                case ArrowType.Explosive:
                    return typeof( ExplosiveArrow );
                case ArrowType.ArmorPiercing:
                    return typeof( ArmorPiercingArrow );
                case ArrowType.Freeze:
                    return typeof( FreezeArrow );
                case ArrowType.Lightning:
                    return typeof( LightningArrow );
                 
                default:
                    return typeof( Arrow );
            }
        }
     
        public virtual Item AmmoBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
         
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return new Bolt();
                case BoltType.Poison:
                    return new PoisonBolt();
                case BoltType.Explosive:
                    return new ExplosiveBolt();
                case BoltType.ArmorPiercing:
                    return new ArmorPiercingBolt();
                case BoltType.Freeze:
                    return new FreezeBolt();
                case BoltType.Lightning:
                    return new LightningBolt();
                 
                default:
                    return new Bolt();
            }
        }
     
        public virtual Type GetBoltSelected()
        {
            BaseRangedModule module = this.BaseRangedModule;
         
            switch ( module.m_BoltType )
            {
                case BoltType.Normal:
                    return typeof( Bolt );
                case BoltType.Poison:
                    return typeof( PoisonBolt );
                case BoltType.Explosive:
                    return typeof( ExplosiveBolt );
                case BoltType.ArmorPiercing:
                    return typeof( ArmorPiercingBolt );
                case BoltType.Freeze:
                    return typeof( FreezeBolt );
                case BoltType.Lightning:
                    return typeof( LightningBolt );
                 
                default:
                    return typeof( Bolt );
            }
        }
     
        public override void GetProperties( ObjectPropertyList list )
        {
            base.GetProperties(list);
         
            BaseRangedModule module = this.BaseRangedModule;
         
            if ( module != null )
            {
                ArrayList strings = new ArrayList();
             
                strings.Add( ( "---------------" ) );
             
                if ( this is Bow || this is CompositeBow || this is ElvenCompositeLongbow ||
                    this is MagicalShortbow || this is Yumi )
                {
                    strings.Add( ( "Quiver Using: " + module.m_ArrowType ) );
                }
             
                if ( this is Crossbow || this is HeavyCrossbow || this is RepeatingCrossbow )
                {
                    strings.Add( ( "Quiver Using: " + module.m_BoltType ) );
                }
             
                strings.Add( ( "lbs per Pull: " + module.m_PullWeight ) );
                strings.Add( ( "String Str: "  + module.m_Strength ) );
             
                string toAdd = "";
                int amount = strings.Count;
                int current = 1;
             
                foreach ( string str in strings )
                {
                    toAdd += str;
                 
                    if ( current != amount )
                        toAdd += "\n";
                 
                    ++current;
                }
             
                if ( toAdd != "" )
                    list.Add( 1070722, toAdd );
            }
            else
            {
                return;
            }
        }
        //--<<Advanced Archery Edit>>---------------------[End 4/4]
 
        public override void Serialize( GenericWriter writer )
        {
            base.Serialize( writer );
 
            writer.Write( (int) 3 ); // version
 
            writer.Write( (bool) m_Balanced );
            writer.Write( (int) m_Velocity );
        }
 
        public override void Deserialize( GenericReader reader )
        {
            base.Deserialize( reader );
 
            int version = reader.ReadInt();
 
            switch ( version )
            {
                case 3:
                {
                    m_Balanced = reader.ReadBool();
                    m_Velocity = reader.ReadInt();
 
                    goto case 2;
                }
                case 2:
                case 1:
                {
                    break;
                }
                case 0:
                {
                    /*m_EffectID =*/ reader.ReadInt();
                    break;
                }
            }
 
            if ( version < 2 )
            {
                WeaponAttributes.MageWeapon = 0;
                WeaponAttributes.UseBestSkill = 0;
            }
        }
    }
}
 
Top