Went into geting owlr to publish 54, but did run into some error. With im geting when im mining out any new custom resource. As far im geting its something inwolving one null geting into another. But my programing kinda sux :D

Crash part and code parts attached. Thanx if you can give a hint.

Code:
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at daat99.ResourceHelper.GetDaat99HarvestedType(Type originalType, Boolean prospected, Double skill)
   at Server.Engines.Harvest.HarvestSystem.FinishHarvesting(Mobile from, Item tool, HarvestDefinition def, Object toHarvest, Object locked)
   at Server.Engines.Harvest.HarvestSoundTimer.OnTick()
   at Server.Timer.Slice() in c:\Users\matis\Desktop\ServUO\Server\Timer.cs:line 409
   at Server.Core.Main(String[] args) in c:\Users\matis\Desktop\ServUO\Server\Main.cs:line 570

Code:
        public virtual void FinishHarvesting(Mobile from, Item tool, HarvestDefinition def, object toHarvest, object locked)
        {
            from.EndAction(locked);

            if (!this.CheckHarvest(from, tool))
                return;

            int tileID;
            Map map;
            Point3D loc;

            if (!this.GetHarvestDetails(from, tool, toHarvest, out tileID, out map, out loc))
            {
                this.OnBadHarvestTarget(from, tool, toHarvest);
                return;
            }
            else if (!def.Validate(tileID))
            {
                this.OnBadHarvestTarget(from, tool, toHarvest);
                return;
            }
           
            if (!this.CheckRange(from, tool, def, map, loc, true))
                return;
            else if (!this.CheckResources(from, tool, def, map, loc, true))
                return;
            else if (!this.CheckHarvest(from, tool, def, toHarvest))
                return;

            if (this.SpecialHarvest(from, tool, def, map, loc))
                return;

            HarvestBank bank = def.GetBank(map, loc.X, loc.Y);

            if (bank == null)
                return;

            HarvestVein vein = bank.Vein;

            if (vein != null)
                vein = this.MutateVein(from, tool, def, bank, toHarvest, vein);

            if (vein == null)
                return;

            HarvestResource primary = vein.PrimaryResource;
            HarvestResource fallback = vein.FallbackResource;
            HarvestResource resource = this.MutateResource(from, tool, def, map, loc, vein, primary, fallback);

            double skillBase = from.Skills[def.Skill].Base;
            double skillValue = from.Skills[def.Skill].Value;

            Type type = null;
            //daat99 OWLTR start - daat99 harvesting
            type = GetResourceType(from, tool, def, map, loc, resource);
            bool daatHarvesting = false;
            if (daat99.OWLTROptionsManager.IsEnabled(daat99.OWLTROptionsManager.OPTIONS_ENUM.DAAT99_MINING) && (type.IsSubclassOf(typeof(BaseOre)) || type.IsSubclassOf(typeof(BaseGranite))))
                daatHarvesting = true;
            else if (daat99.OWLTROptionsManager.IsEnabled(daat99.OWLTROptionsManager.OPTIONS_ENUM.DAAT99_LUMBERJACKING) && type.IsSubclassOf(typeof(BaseLog)))
                daatHarvesting = true;

            if ( daatHarvesting || (skillBase >= resource.ReqSkill && from.CheckSkill( def.Skill, resource.MinSkill, resource.MaxSkill )) )
            {


                if (type != null)
                    type = MutateType( type, from, tool, def, map, loc, resource );
                if (daatHarvesting)
                {
                    type = ResourceHelper.GetDaat99HarvestedType(type, bank.Vein.IsProspected, skillValue);
                    //type = GetResourceType(from, tool, def, map, loc, resource);
                    from.CheckSkill(def.Skill, 0.0, from.Skills[def.Skill].Cap + (vein.IsProspected?10.0:0.0));
                }
                //daat99 OWLTR end - daat99 harvesting

                if (type != null)
                {
                    Item item = this.Construct(type, from);

                    if (item == null)
                    {
                        type = null;
                    }
                    else
                    {
                        //The whole harvest system is kludgy and I'm sure this is just adding to it.
                        if (item.Stackable)
                        {
                            int amount = def.ConsumedPerHarvest;
                            int feluccaAmount = def.ConsumedPerFeluccaHarvest;

                            int racialAmount = (int)Math.Ceiling(amount * 1.1);
                            int feluccaRacialAmount = (int)Math.Ceiling(feluccaAmount * 1.1);

                            bool eligableForRacialBonus = (def.RaceBonus && from.Race == Race.Human);
                            bool inFelucca = (map == Map.Felucca);

                            if (eligableForRacialBonus && inFelucca && bank.Current >= feluccaRacialAmount && 0.1 > Utility.RandomDouble())
                                item.Amount = feluccaRacialAmount;
                            else if (inFelucca && bank.Current >= feluccaAmount)
                                item.Amount = feluccaAmount;
                            else if (eligableForRacialBonus && bank.Current >= racialAmount && 0.1 > Utility.RandomDouble())
                                item.Amount = racialAmount;
                            else
                                item.Amount = amount;
                        }

                        bank.Consume(item.Amount, from);
                        //daat99 OWLTR start - custom harvesting
                        CraftResource craftResourceFromType = CraftResources.GetFromType(type);
                        string s_Type = "UNKNOWN";
                        int i_Tokens = 1;
                        if (craftResourceFromType != CraftResource.None)
                        {
                            s_Type = CraftResources.GetInfo(craftResourceFromType).Name;
                            i_Tokens = CraftResources.GetIndex(craftResourceFromType) + 1;
                        }
                        if (craftResourceFromType != CraftResource.None && daat99.OWLTROptionsManager.IsEnabled(daat99.OWLTROptionsManager.OPTIONS_ENUM.DAAT99_MINING) && def.Skill == SkillName.Mining && (type.IsSubclassOf(typeof(Server.Items.BaseOre)) || type.IsSubclassOf(typeof(Server.Items.BaseGranite))))
                        {
                            if (type.IsSubclassOf(typeof(Server.Items.BaseOre)))
                            {

                                if ( Give( from, item, def.PlaceAtFeetIfFull ) )
                                    from.SendMessage("You dig some {0} ore and placed it in your backpack.", s_Type);
                                else
                                {
                                    from.SendMessage("Your backpack is full, so the ore you mined is lost.");
                                    item.Delete();
                                }
                            }
                            else
                            {
                                if ( Give( from, item, def.PlaceAtFeetIfFull ) )
                                    from.SendMessage("You carefully extract some workable stone from the ore vein.");
                                else
                                {
                                    from.SendMessage("Your backpack is full, so the ore you mined is lost.");
                                    item.Delete();
                                }
                            }
                        }
                        else if (craftResourceFromType != CraftResource.None && OWLTROptionsManager.IsEnabled(OWLTROptionsManager.OPTIONS_ENUM.DAAT99_LUMBERJACKING) && def.Skill == SkillName.Lumberjacking)
                        {
                            if ( Give( from, item, def.PlaceAtFeetIfFull ) )
                                from.SendMessage("You placed some {0} logs in your backpack.", s_Type);
                            else
                            {
                                from.SendMessage("You can't place any wood into your backpack!");
                                item.Delete();
                            }
                        }
                        else
                        {
                        //daat99 OWLTR end - custom harvesting
                            if ( Give( from, item, def.PlaceAtFeetIfFull ) )
                            {
                                SendSuccessTo( from, item, resource );
                        }
                        else
                        {
                            this.SendPackFullTo(from, item, def, resource);
                            item.Delete();
                        }
                        //daat99 OWLTR start - custom harvesting
                        }
                        if (from.Map == Map.Felucca)
                            i_Tokens = (int)(i_Tokens*1.5);
                        if ( OWLTROptionsManager.IsEnabled(OWLTROptionsManager.OPTIONS_ENUM.HARVEST_GIVE_TOKENS) )
                            TokenSystem.GiveTokensToPlayer(from as Server.Mobiles.PlayerMobile, i_Tokens);
                        //daat99 OWLTR end - custom harvesting

                        BonusHarvestResource bonus = def.GetBonusResource();

                        if (bonus != null && bonus.Type != null && skillBase >= bonus.ReqSkill)
                        {
                            Item bonusItem = this.Construct(bonus.Type, from);

                            if (this.Give(from, bonusItem, true))    //Bonuses always allow placing at feet, even if pack is full irregrdless of def
                            {
                                bonus.SendSuccessTo(from);
                            }
                            else
                            {
                                item.Delete();
                            }
                        }

                        if (tool is IUsesRemaining)
                        {
                            IUsesRemaining toolWithUses = (IUsesRemaining)tool;

                            toolWithUses.ShowUsesRemaining = true;

                            if (toolWithUses.UsesRemaining > 0)
                                --toolWithUses.UsesRemaining;

                            if (toolWithUses.UsesRemaining < 1)
                            {
                                tool.Delete();
                                def.SendMessageTo(from, def.ToolBrokeMessage);
                            }
                        }
                    }
                }
            }
 
Unfortunately this does not give us much to go on. It tells us that a null reference occurs somewhere within the GetDaat99HarvestedType method, but not where. Is it possible to rebuild your core and extensions with debugging enabled? I must confess I am not quite sure how to do this myself with ServUO's build system.
 
Unfortunately this does not give us much to go on. It tells us that a null reference occurs somewhere within the GetDaat99HarvestedType method, but not where. Is it possible to rebuild your core and extensions with debugging enabled? I must confess I am not quite sure how to do this myself with ServUO's build system.
You can enable debugging by adding -debug to the launch parameters.
 
Will that include file name and line numbers in stack traces? I thought there was a compile-time option that was required for that. To be honest dot net is not my specialty :)
 
Got that, but now i feel more confused :D Got feeling, that it would mutch easyer to make new own system sometimes based on existing :D
Code:
Exception:
System.NullReferenceException: Object reference not set to an instance of an object.
   at daat99.ResourceHelper.GetDaat99HarvestedType(Type originalType, Boolean prospected, Double skill) in c:\Users\matis\Desktop\ServUO\Scripts\Customs\OWLTR 3.01.00\New\Resource Helper.cs:line 73
   at Server.Engines.Harvest.HarvestSystem.FinishHarvesting(Mobile from, Item tool, HarvestDefinition def, Object toHarvest, Object locked) in c:\Users\matis\Desktop\ServUO\Scripts\Services\Harvest\Core\HarvestSystem.cs:line 169
   at Server.Engines.Harvest.HarvestSoundTimer.OnTick() in c:\Users\matis\Desktop\ServUO\Scripts\Services\Harvest\Core\HarvestSoundTimer.cs:line 31
   at Server.Timer.Slice() in c:\Users\matis\Desktop\ServUO\Server\Timer.cs:line 409
   at Server.Core.Main(String[] args) in c:\Users\matis\Desktop\ServUO\Server\Main.cs:line 570

Code:
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Targeting;
using daat99;

namespace Server.Engines.Harvest
{
    public abstract class HarvestSystem
    {
        private readonly List<HarvestDefinition> m_Definitions;
        public HarvestSystem()
        {
            this.m_Definitions = new List<HarvestDefinition>();
        }

        public List<HarvestDefinition> Definitions
        {
            get
            {
                return this.m_Definitions;
            }
        }
        public virtual bool CheckTool(Mobile from, Item tool)
        {
            bool wornOut = (tool == null || tool.Deleted || (tool is IUsesRemaining && ((IUsesRemaining)tool).UsesRemaining <= 0));

            if (wornOut)
                from.SendLocalizedMessage(1044038); // You have worn out your tool!

            return !wornOut;
        }

        public virtual bool CheckHarvest(Mobile from, Item tool)
        {
            return this.CheckTool(from, tool);
        }

        public virtual bool CheckHarvest(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
        {
            return this.CheckTool(from, tool);
        }

        public virtual bool CheckRange(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, bool timed)
        {
            bool inRange = (from.Map == map && from.InRange(loc, def.MaxRange));

            if (!inRange)
                def.SendMessageTo(from, timed ? def.TimedOutOfRangeMessage : def.OutOfRangeMessage);

            return inRange;
        }

        public virtual bool CheckResources(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, bool timed)
        {
            HarvestBank bank = def.GetBank(map, loc.X, loc.Y);
            bool available = (bank != null && bank.Current >= def.ConsumedPerHarvest);

            if (!available)
                def.SendMessageTo(from, timed ? def.DoubleHarvestMessage : def.NoResourcesMessage);

            return available;
        }

        public virtual void OnBadHarvestTarget(Mobile from, Item tool, object toHarvest)
        {
        }

        public virtual object GetLock(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
        {
            /* Here we prevent multiple harvesting.
            *
            * Some options:
            *  - 'return tool;' : This will allow the player to harvest more than once concurrently, but only if they use multiple tools. This seems to be as OSI.
            *  - 'return GetType();' : This will disallow multiple harvesting of the same type. That is, we couldn't mine more than once concurrently, but we could be both mining and lumberjacking.
            *  - 'return typeof( HarvestSystem );' : This will completely restrict concurrent harvesting.
            */
            return tool;
        }

        public virtual void OnConcurrentHarvest(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
        {
        }

        public virtual void OnHarvestStarted(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
        {
        }

        public virtual bool BeginHarvesting(Mobile from, Item tool)
        {
            if (!this.CheckHarvest(from, tool))
                return false;

            from.Target = new HarvestTarget(tool, this);
            return true;
        }

        public virtual void FinishHarvesting(Mobile from, Item tool, HarvestDefinition def, object toHarvest, object locked)
        {
            from.EndAction(locked);

            if (!this.CheckHarvest(from, tool))
                return;

            int tileID;
            Map map;
            Point3D loc;

            if (!this.GetHarvestDetails(from, tool, toHarvest, out tileID, out map, out loc))
            {
                this.OnBadHarvestTarget(from, tool, toHarvest);
                return;
            }
            else if (!def.Validate(tileID))
            {
                this.OnBadHarvestTarget(from, tool, toHarvest);
                return;
            }
           
            if (!this.CheckRange(from, tool, def, map, loc, true))
                return;
            else if (!this.CheckResources(from, tool, def, map, loc, true))
                return;
            else if (!this.CheckHarvest(from, tool, def, toHarvest))
                return;

            if (this.SpecialHarvest(from, tool, def, map, loc))
                return;

            HarvestBank bank = def.GetBank(map, loc.X, loc.Y);

            if (bank == null)
                return;

            HarvestVein vein = bank.Vein;

            if (vein != null)
                vein = this.MutateVein(from, tool, def, bank, toHarvest, vein);

            if (vein == null)
                return;

            HarvestResource primary = vein.PrimaryResource;
            HarvestResource fallback = vein.FallbackResource;
            HarvestResource resource = this.MutateResource(from, tool, def, map, loc, vein, primary, fallback);

            double skillBase = from.Skills[def.Skill].Base;
            double skillValue = from.Skills[def.Skill].Value;

            Type type = null;
            //daat99 OWLTR start - daat99 harvesting
            type = GetResourceType(from, tool, def, map, loc, resource);
            bool daatHarvesting = false;
            if (daat99.OWLTROptionsManager.IsEnabled(daat99.OWLTROptionsManager.OPTIONS_ENUM.DAAT99_MINING) && (type.IsSubclassOf(typeof(BaseOre)) || type.IsSubclassOf(typeof(BaseGranite))))
                daatHarvesting = true;
            else if (daat99.OWLTROptionsManager.IsEnabled(daat99.OWLTROptionsManager.OPTIONS_ENUM.DAAT99_LUMBERJACKING) && type.IsSubclassOf(typeof(BaseLog)))
                daatHarvesting = true;

            if ( daatHarvesting || (skillBase >= resource.ReqSkill && from.CheckSkill( def.Skill, resource.MinSkill, resource.MaxSkill )) )
            {
                type = this.GetResourceType(from, tool, def, map, loc, resource);

                if (type != null)
                    type = this.MutateType(type, from, tool, def, map, loc, resource );
                if (daatHarvesting)
                {
                    type = ResourceHelper.GetDaat99HarvestedType(type, bank.Vein.IsProspected, skillValue);
                    //type = GetResourceType(from, tool, def, map, loc, resource);
                    from.CheckSkill(def.Skill, 0.0, from.Skills[def.Skill].Cap + (vein.IsProspected?10.0:0.0));
                }
                //daat99 OWLTR end - daat99 harvesting

                if (type != null)
                {
                    Item item = this.Construct(type, from);

                    if (item == null)
                    {
                        type = null;
                    }
                    else
                    {
                        //The whole harvest system is kludgy and I'm sure this is just adding to it.
                        if (item.Stackable)
                        {
                            int amount = def.ConsumedPerHarvest;
                            int feluccaAmount = def.ConsumedPerFeluccaHarvest;

                            int racialAmount = (int)Math.Ceiling(amount * 1.1);
                            int feluccaRacialAmount = (int)Math.Ceiling(feluccaAmount * 1.1);

                            bool eligableForRacialBonus = (def.RaceBonus && from.Race == Race.Human);
                            bool inFelucca = (map == Map.Felucca);

                            if (eligableForRacialBonus && inFelucca && bank.Current >= feluccaRacialAmount && 0.1 > Utility.RandomDouble())
                                item.Amount = feluccaRacialAmount;
                            else if (inFelucca && bank.Current >= feluccaAmount)
                                item.Amount = feluccaAmount;
                            else if (eligableForRacialBonus && bank.Current >= racialAmount && 0.1 > Utility.RandomDouble())
                                item.Amount = racialAmount;
                            else
                                item.Amount = amount;
                        }

                        bank.Consume(item.Amount, from);
                        //daat99 OWLTR start - custom harvesting
                        CraftResource craftResourceFromType = CraftResources.GetFromType(type);
                        string s_Type = "UNKNOWN";
                        int i_Tokens = 1;
                        if (craftResourceFromType != CraftResource.None)
                        {
                            s_Type = CraftResources.GetInfo(craftResourceFromType).Name;
                            i_Tokens = CraftResources.GetIndex(craftResourceFromType) + 1;
                        }
                        if (craftResourceFromType != CraftResource.None && daat99.OWLTROptionsManager.IsEnabled(daat99.OWLTROptionsManager.OPTIONS_ENUM.DAAT99_MINING) && def.Skill == SkillName.Mining && (type.IsSubclassOf(typeof(Server.Items.BaseOre)) || type.IsSubclassOf(typeof(Server.Items.BaseGranite))))
                        {
                            if (type.IsSubclassOf(typeof(Server.Items.BaseOre)))
                            {

                                if ( Give( from, item, def.PlaceAtFeetIfFull ) )
                                    from.SendMessage("You dig some {0} ore and placed it in your backpack.", s_Type);
                                else
                                {
                                    from.SendMessage("Your backpack is full, so the ore you mined is lost.");
                                    item.Delete();
                                }
                            }
                            else
                            {
                                if ( Give( from, item, def.PlaceAtFeetIfFull ) )
                                    from.SendMessage("You carefully extract some workable stone from the ore vein.");
                                else
                                {
                                    from.SendMessage("Your backpack is full, so the ore you mined is lost.");
                                    item.Delete();
                                }
                            }
                        }
                        else if (craftResourceFromType != CraftResource.None && OWLTROptionsManager.IsEnabled(OWLTROptionsManager.OPTIONS_ENUM.DAAT99_LUMBERJACKING) && def.Skill == SkillName.Lumberjacking)
                        {
                            if ( Give( from, item, def.PlaceAtFeetIfFull ) )
                                from.SendMessage("You placed some {0} logs in your backpack.", s_Type);
                            else
                            {
                                from.SendMessage("You can't place any wood into your backpack!");
                                item.Delete();
                            }
                        }
                        else
                        {
                        //daat99 OWLTR end - custom harvesting
                            if ( Give( from, item, def.PlaceAtFeetIfFull ) )
                            {
                                this.SendSuccessTo( from, item, resource );
                        }
                        else
                        {
                            this.SendPackFullTo(from, item, def, resource);
                            item.Delete();
                        }
                        //daat99 OWLTR start - custom harvesting
                        }
                        if (from.Map == Map.Felucca)
                            i_Tokens = (int)(i_Tokens*1.5);
                        if ( OWLTROptionsManager.IsEnabled(OWLTROptionsManager.OPTIONS_ENUM.HARVEST_GIVE_TOKENS) )
                            TokenSystem.GiveTokensToPlayer(from as Server.Mobiles.PlayerMobile, i_Tokens);
                        //daat99 OWLTR end - custom harvesting

                        BonusHarvestResource bonus = def.GetBonusResource();

                        if (bonus != null && bonus.Type != null && skillBase >= bonus.ReqSkill)
                        {
                            Item bonusItem = this.Construct(bonus.Type, from);

                            if (this.Give(from, bonusItem, true))    //Bonuses always allow placing at feet, even if pack is full irregrdless of def
                            {
                                bonus.SendSuccessTo(from);
                            }
                            else
                            {
                                item.Delete();
                            }
                        }

                        if (tool is IUsesRemaining)
                        {
                            IUsesRemaining toolWithUses = (IUsesRemaining)tool;

                            toolWithUses.ShowUsesRemaining = true;

                            if (toolWithUses.UsesRemaining > 0)
                                --toolWithUses.UsesRemaining;

                            if (toolWithUses.UsesRemaining < 1)
                            {
                                tool.Delete();
                                def.SendMessageTo(from, def.ToolBrokeMessage);
                            }
                        }
                    }
                }
            }

            if (type == null)
                def.SendMessageTo(from, def.FailMessage);

            //daat99 OWLTR start - custom harvesting
            if ( this is Lumberjacking || this is Mining )
                this.OnHarvestFinished( from, tool, def, vein, bank, resource, toHarvest, type );
            else
            //daat99 OWLTR end - custom harvesting
            this.OnHarvestFinished(from, tool, def, vein, bank, resource, toHarvest);
        }

        //daat99 OWLTR start - custom resources
        public virtual void OnHarvestFinished( Mobile from, Item tool, HarvestDefinition def, HarvestVein vein, HarvestBank bank, HarvestResource resource, object harvested, Type type )
        {
        }
        //daat99 OWLTR end - custom resources
        public virtual void OnHarvestFinished(Mobile from, Item tool, HarvestDefinition def, HarvestVein vein, HarvestBank bank, HarvestResource resource, object harvested)
        {
        }

        public virtual bool SpecialHarvest(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc)
        {
            return false;
        }

        public virtual Item Construct(Type type, Mobile from)
        {
            try
            {
                return Activator.CreateInstance(type) as Item;
            }
            catch
            {
                return null;
            }
        }

        public virtual HarvestVein MutateVein(Mobile from, Item tool, HarvestDefinition def, HarvestBank bank, object toHarvest, HarvestVein vein)
        {
            return vein;
        }

        public virtual void SendSuccessTo(Mobile from, Item item, HarvestResource resource)
        {
            resource.SendSuccessTo(from);
        }

        public virtual void SendPackFullTo(Mobile from, Item item, HarvestDefinition def, HarvestResource resource)
        {
            def.SendMessageTo(from, def.PackFullMessage);
        }

        public virtual bool Give(Mobile m, Item item, bool placeAtFeet)
        {
            if (m.PlaceInBackpack(item))
                return true;

            if (!placeAtFeet)
                return false;

            Map map = m.Map;

            if (map == null)
                return false;

            List<Item> atFeet = new List<Item>();

            foreach (Item obj in m.GetItemsInRange(0))
                atFeet.Add(obj);

            for (int i = 0; i < atFeet.Count; ++i)
            {
                Item check = atFeet[i];

                if (check.StackWith(m, item, false))
                    return true;
            }

            item.MoveToWorld(m.Location, map);
            return true;
        }

        public virtual Type MutateType(Type type, Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestResource resource)
        {
            return from.Region.GetResource(type);
        }

        public virtual Type GetResourceType(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestResource resource)
        {
            if (resource.Types.Length > 0)
                return resource.Types[Utility.Random(resource.Types.Length)];

            return null;
        }

        public virtual HarvestResource MutateResource(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc, HarvestVein vein, HarvestResource primary, HarvestResource fallback)
        {
            bool racialBonus = (def.RaceBonus && from.Race == Race.Elf);

            if (vein.ChanceToFallback > (Utility.RandomDouble() + (racialBonus ? .20 : 0)))
                return fallback;

            double skillValue = from.Skills[def.Skill].Value;

            if (fallback != null && (skillValue < primary.ReqSkill || skillValue < primary.MinSkill))
                return fallback;

            return primary;
        }

        public virtual bool OnHarvesting(Mobile from, Item tool, HarvestDefinition def, object toHarvest, object locked, bool last)
        {
            if (!this.CheckHarvest(from, tool))
            {
                from.EndAction(locked);
                return false;
            }

            int tileID;
            Map map;
            Point3D loc;

            if (!this.GetHarvestDetails(from, tool, toHarvest, out tileID, out map, out loc))
            {
                from.EndAction(locked);
                this.OnBadHarvestTarget(from, tool, toHarvest);
                return false;
            }
            else if (!def.Validate(tileID))
            {
                from.EndAction(locked);
                this.OnBadHarvestTarget(from, tool, toHarvest);
                return false;
            }
            else if (!this.CheckRange(from, tool, def, map, loc, true))
            {
                from.EndAction(locked);
                return false;
            }
            else if (!this.CheckResources(from, tool, def, map, loc, true))
            {
                from.EndAction(locked);
                return false;
            }
            else if (!this.CheckHarvest(from, tool, def, toHarvest))
            {
                from.EndAction(locked);
                return false;
            }

            this.DoHarvestingEffect(from, tool, def, map, loc);

            new HarvestSoundTimer(from, tool, this, def, toHarvest, locked, last).Start();

            return !last;
        }

        public virtual void DoHarvestingSound(Mobile from, Item tool, HarvestDefinition def, object toHarvest)
        {
            if (def.EffectSounds.Length > 0)
                from.PlaySound(Utility.RandomList(def.EffectSounds));
        }

        public virtual void DoHarvestingEffect(Mobile from, Item tool, HarvestDefinition def, Map map, Point3D loc)
        {
            from.Direction = from.GetDirectionTo(loc);

            if (!from.Mounted)
                from.Animate(Utility.RandomList(def.EffectActions), 5, 1, true, false, 0);
        }

        public virtual HarvestDefinition GetDefinition(int tileID)
        {
            HarvestDefinition def = null;

            for (int i = 0; def == null && i < this.m_Definitions.Count; ++i)
            {
                HarvestDefinition check = this.m_Definitions[i];

                if (check.Validate(tileID))
                    def = check;
            }

            return def;
        }

        public virtual void StartHarvesting(Mobile from, Item tool, object toHarvest)
        {
            if (!this.CheckHarvest(from, tool))
                return;

            int tileID;
            Map map;
            Point3D loc;

            if (!this.GetHarvestDetails(from, tool, toHarvest, out tileID, out map, out loc))
            {
                this.OnBadHarvestTarget(from, tool, toHarvest);
                return;
            }

            HarvestDefinition def = this.GetDefinition(tileID);

            if (def == null)
            {
                this.OnBadHarvestTarget(from, tool, toHarvest);
                return;
            }

            if (!this.CheckRange(from, tool, def, map, loc, false))
                return;
            else if (!this.CheckResources(from, tool, def, map, loc, false))
                return;
            else if (!this.CheckHarvest(from, tool, def, toHarvest))
                return;

            object toLock = this.GetLock(from, tool, def, toHarvest);

            if (!from.BeginAction(toLock))
            {
                this.OnConcurrentHarvest(from, tool, def, toHarvest);
                return;
            }

            new HarvestTimer(from, tool, this, def, toHarvest, toLock).Start();
            this.OnHarvestStarted(from, tool, def, toHarvest);
        }

        public virtual bool GetHarvestDetails(Mobile from, Item tool, object toHarvest, out int tileID, out Map map, out Point3D loc)
        {
            if (toHarvest is Static && !((Static)toHarvest).Movable)
            {
                Static obj = (Static)toHarvest;

                tileID = (obj.ItemID & 0x3FFF) | 0x4000;
                map = obj.Map;
                loc = obj.GetWorldLocation();
            }
            else if (toHarvest is StaticTarget)
            {
                StaticTarget obj = (StaticTarget)toHarvest;

                tileID = (obj.ItemID & 0x3FFF) | 0x4000;
                map = from.Map;
                loc = obj.Location;
            }
            else if (toHarvest is LandTarget)
            {
                LandTarget obj = (LandTarget)toHarvest;

                tileID = obj.TileID;
                map = from.Map;
                loc = obj.Location;
            }
            else
            {
                tileID = 0;
                map = null;
                loc = Point3D.Zero;
                return false;
            }

            return (map != null && map != Map.Internal);
        }
    }
}

namespace Server
{
    public interface IChopable
    {
        void OnChop(Mobile from);
    }

    [AttributeUsage(AttributeTargets.Class)]
    public class FurnitureAttribute : Attribute
    {
        public FurnitureAttribute()
        {
        }

        public static bool Check(Item item)
        {
            return (item != null && item.GetType().IsDefined(typeof(FurnitureAttribute), false));
        }
    }
}

Code:
using System;
using System.Collections.Generic;
using Server.Items;
using Server.Engines.Craft;
using Server;

namespace daat99
{
    public static class ResourceHelper
    {
        private static readonly int CANT_CRAFT_METAL = 1044268;
        private static readonly int CANT_CRAFT_STONE_GRANITE = 1044526;
        //private static readonly int CANT_CRAFT_STONE_OTHERS = 1044527;
        private static readonly int CANT_CRAFT_WOOD = 1044268;
        private static readonly int CANT_CRAFT_SCALE = 1044268;
        private static readonly int CANT_CRAFT_LEATHER = 1044462;

        private static Dictionary<CraftResource, double> craftResourceMinSkill;
        public static Dictionary<CraftResource, double> CraftResourceMinSkill
        {
            get
            {
                if (craftResourceMinSkill == null)
                {
                    craftResourceMinSkill = new Dictionary<CraftResource, double>();
                    foreach (ResourceData data in Resources)
                    {
                        try
                        {
                            if (!craftResourceMinSkill.ContainsKey(data.CraftResource))
                                craftResourceMinSkill.Add(data.CraftResource, data.MinSkill);
                        }
                        catch { }
                    }
                }
                return craftResourceMinSkill;
            }
        }

        public static Type GetDaat99HarvestedType(Type originalType, bool prospected, double skill)
        {

            double MAX_SKILL = 130.0;
            if (skill > MAX_SKILL)
                skill = MAX_SKILL;
            double chance = Utility.RandomMinMax(1, (int)(skill*10))/10.0 + (prospected ? 10 : 0);

            CraftResource originalCraftResource = CraftResources.GetFromType(originalType);
            CraftResource firstCraftResource = GetFirstCraftResourceFromType(originalCraftResource);
            CraftResource resultCraftResource = firstCraftResource;


            if ( Utility.RandomDouble() < 0.3 )
            {
                CraftResource check = GetLastCraftResourceFromType(originalCraftResource);
                double diff = MAX_SKILL/((int)check - (int)firstCraftResource + 1);
               
                for ( ; check > firstCraftResource; check = (CraftResource)((int)check - 1) )
                {
                    double minSkill = GetMinSkill(check);
                    if ( skill < minSkill )
                        continue;
                    if (chance > minSkill - diff)
                    {
                        resultCraftResource = check;
                        break;
                    }
                }
            }
            CraftResourceInfo info = CraftResources.GetInfo(resultCraftResource);
            if (originalType.IsSubclassOf(typeof(BaseGranite)) && info.ResourceTypes.Length > 2)
                return info.ResourceTypes[2];
            if (info.ResourceTypes.Length > 1)
                return info.ResourceTypes[1];
            return info.ResourceTypes[0];
        }

        private static Dictionary<CraftResource, ResourceData> craftResourceDataList;
        public static Dictionary<CraftResource, ResourceData> CraftResourceDataList
        {
            get
            {
                if (craftResourceDataList == null)
                {
                    craftResourceDataList = new Dictionary<CraftResource, ResourceData>();
                    foreach (ResourceData data in Resources)
                    {
                        try
                        {
                            if (!craftResourceDataList.ContainsKey(data.CraftResource))
                                craftResourceDataList.Add(data.CraftResource, data);
                        }
                        catch { }
                    }
                }
                return craftResourceDataList;
            }
        }

        public static double GetMinSkill(CraftResource resource)
        {
            if (CraftResourceMinSkill.ContainsKey(resource))
                return CraftResourceMinSkill[resource];
            return 0.0;
        }

        private static List<ResourceData> resources;
        private static List<ResourceData> Resources
        {
            get
            {
                if ( resources == null )
                {
                    resources = new List<ResourceData>();
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Iron,             "Iron",             typeof(IronIngot),             typeof(IronOre),          00.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.DullCopper,         "Dull Copper",         typeof(DullCopperIngot),     typeof(DullCopperOre),      20.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.ShadowIron,         "Shadow Iron",         typeof(ShadowIronIngot),     typeof(ShadowIronOre),      30.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Copper,             "Copper",             typeof(CopperIngot),         typeof(CopperOre),          40.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Bronze,             "Bronze",             typeof(BronzeIngot),         typeof(BronzeOre),          50.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Gold,             "Gold",             typeof(GoldIngot),             typeof(GoldOre),          60.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Agapite,             "Agapite",             typeof(AgapiteIngot),         typeof(AgapiteOre),      70.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Verite,             "Verite",             typeof(VeriteIngot),         typeof(VeriteOre),          80.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Valorite,         "Valorite",         typeof(ValoriteIngot),         typeof(ValoriteOre),      90.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Blaze,             "Blaze",             typeof(BlazeIngot),         typeof(BlazeOre),         100.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Ice,                 "Ice",                 typeof(IceIngot),             typeof(IceOre),         105.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Toxic,             "Toxic",             typeof(ToxicIngot),         typeof(ToxicOre),         110.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Electrum,         "Electrum",         typeof(ElectrumIngot),         typeof(ElectrumOre),     115.0, CANT_CRAFT_METAL));
                    resources.Add( new ResourceData(CraftResourceType.Metal,     CraftResource.Platinum,         "Platinum",         typeof(PlatinumIngot),         typeof(PlatinumOre),     119.0, CANT_CRAFT_METAL));
                   
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.RegularWood,         "Log",                 typeof(Board),                 typeof(Log),               00.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.OakWood,             "Oak",                 typeof(OakBoard),             typeof(OakLog),           20.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.AshWood,             "Ash",                 typeof(AshBoard),             typeof(AshLog),          30.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.YewWood,             "Yew",                 typeof(YewBoard),             typeof(YewLog),          40.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.Heartwood,         "Heartwood",         typeof(HeartwoodBoard),     typeof(HeartwoodLog),      50.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.Bloodwood,         "Bloodwood",         typeof(BloodwoodBoard),     typeof(BloodwoodLog),      60.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.Frostwood,         "Frostwood",         typeof(FrostwoodBoard),     typeof(FrostwoodLog),      70.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.Ebony,             "Ebony",             typeof(EbonyBoard),         typeof(EbonyLog),          80.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.Bamboo,             "Bamboo",             typeof(BambooBoard),         typeof(BambooLog),          90.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.PurpleHeart,         "PurpleHeart",         typeof(PurpleHeartBoard),     typeof(PurpleHeartLog), 100.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.Redwood,             "Redwood",             typeof(RedwoodBoard),         typeof(RedwoodLog),     110.0, CANT_CRAFT_WOOD));
                    resources.Add( new ResourceData(CraftResourceType.Wood,     CraftResource.Petrified,         "Petrified",         typeof(PetrifiedBoard),     typeof(PetrifiedLog),     119.0, CANT_CRAFT_WOOD));
                   
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.RegularLeather,    "Regular Leather",    typeof(Leather),             typeof(Hides),               00.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.SpinedLeather,     "Spined Leather",     typeof(SpinedLeather),         typeof(SpinedHides),      20.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.HornedLeather,     "Horned Leather",     typeof(HornedLeather),         typeof(HornedHides),      35.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.BarbedLeather,     "Barbed Leather",     typeof(BarbedLeather),         typeof(BarbedHides),      50.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.PolarLeather,      "Polar Leather",     typeof(PolarLeather),         typeof(PolarHides),      60.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.SyntheticLeather,    "Synthetic Leather",typeof(SyntheticLeather),     typeof(SyntheticHides),  70.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.BlazeLeather,         "Blaze Leather",     typeof(BlazeLeather),         typeof(BlazeHides),      80.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.DaemonicLeather,    "Daemonic Leather",    typeof(DaemonicLeather),     typeof(DaemonicHides),      90.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.ShadowLeather,     "Shadow Leather",     typeof(ShadowLeather),         typeof(ShadowHides),     100.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.FrostLeather,        "Frost Leather",     typeof(FrostLeather),         typeof(FrostHides),     110.0, CANT_CRAFT_LEATHER));
                    resources.Add( new ResourceData(CraftResourceType.Leather,     CraftResource.EtherealLeather,    "Ethereal Leather", typeof(EtherealLeather),     typeof(EtherealHides),     119.0, CANT_CRAFT_LEATHER));                   
                   
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.RedScales,        "Red Scales",        typeof(RedScales),             typeof(RedScales),           00.0, CANT_CRAFT_SCALE));
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.YellowScales,        "Yellow Scales",    typeof(YellowScales),         typeof(YellowScales),     00.0, CANT_CRAFT_SCALE));
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.BlackScales,        "Black Scales",        typeof(BlackScales),         typeof(BlackScales),       00.0, CANT_CRAFT_SCALE));
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.GreenScales,        "Green Scales",        typeof(GreenScales),         typeof(GreenScales),       00.0, CANT_CRAFT_SCALE));
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.WhiteScales,        "White Scales",        typeof(WhiteScales),         typeof(WhiteScales),       00.0, CANT_CRAFT_SCALE));
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.BlueScales,        "Blue Scales",        typeof(BlueScales),         typeof(BlueScales),       00.0, CANT_CRAFT_SCALE));
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.CopperScales,        "Copper Scales",    typeof(CopperScales),         typeof(CopperScales),       00.0, CANT_CRAFT_SCALE));
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.SilverScales,        "Silver Scales",    typeof(SilverScales),         typeof(SilverScales),       00.0, CANT_CRAFT_SCALE));
                    resources.Add( new ResourceData(CraftResourceType.Scales,     CraftResource.GoldScales,        "Gold Scales",        typeof(GoldScales),         typeof(GoldScales),       00.0, CANT_CRAFT_SCALE));
                   
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Iron,             "Granite",             typeof(Granite),             typeof(Granite),          00.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.DullCopper,         "Dull Copper",         typeof(DullCopperGranite),     typeof(DullCopperGranite),20.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.ShadowIron,         "Shadow Iron",         typeof(ShadowIronGranite),     typeof(ShadowIronGranite),30.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Copper,             "Copper",             typeof(CopperGranite),         typeof(CopperGranite),      40.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Bronze,             "Bronze",             typeof(BronzeGranite),         typeof(BronzeGranite),      50.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Gold,             "Gold",             typeof(GoldGranite),         typeof(GoldGranite),      60.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Agapite,             "Agapite",             typeof(AgapiteGranite),     typeof(AgapiteGranite),  70.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Verite,             "Verite",             typeof(VeriteGranite),         typeof(VeriteGranite),      80.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Valorite,         "Valorite",         typeof(ValoriteGranite),     typeof(ValoriteGranite), 90.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Blaze,             "Blaze",             typeof(BlazeGranite),         typeof(BlazeGranite),     100.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Ice,                 "Ice",                 typeof(IceGranite),         typeof(IceGranite),     105.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Toxic,             "Toxic",             typeof(ToxicGranite),         typeof(ToxicGranite),     110.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Electrum,         "Electrum",         typeof(ElectrumGranite),     typeof(ElectrumGranite),115.0, CANT_CRAFT_STONE_GRANITE));
                    resources.Add( new ResourceData(CraftResourceType.None,     CraftResource.Platinum,         "Platinum",         typeof(PlatinumGranite),     typeof(PlatinumGranite),119.0, CANT_CRAFT_STONE_GRANITE));
                }
                return resources;
            }
        }

        #region AddCraftingResources
        //daat99.ResourceHelper.AddMetalResources(this);
        public static void AddMetalResources(CraftSystem system)
        {
            bool first = true;
            foreach ( ResourceData data in Resources )
            {
                if ( data.ResourceType == CraftResourceType.Metal )
                {
                    if ( first )
                    {
                        system.SetSubRes( data.ItemType, data.Name );
                        first = false;
                    }
                    system.AddSubRes( data.ItemType, data.Name, data.MinSkill, data.CantCraftMessage );
                }
            }
        }
       
        //daat99.ResourceHelper.AddStoneResources(this);
        public static void AddStoneResources(CraftSystem system)
        {   
            bool first = true;
            foreach ( ResourceData data in Resources )
            {
                if ( data.ResourceType == CraftResourceType.None )
                {
                    if ( first )
                    {
                        system.SetSubRes( data.ItemType, data.Name );
                        first = false;
                    }
                    system.AddSubRes( data.ItemType, data.Name, data.MinSkill, data.CantCraftMessage );
                }
            }
        }

        //daat99.ResourceHelper.AddWoodResources(this);
        public static void AddWoodResources(CraftSystem system)
        {
            bool first = true;
            foreach ( ResourceData data in Resources )
            {
                if ( data.ResourceType == CraftResourceType.Wood )
                {
                    if ( first )
                    {
                        system.SetSubRes( data.RawType, data.Name );
                        first = false;
                    }
                    system.AddSubRes( data.RawType, data.Name, data.MinSkill, data.CantCraftMessage );
                }
            }
        }
       
        //daat99.ResourceHelper.AddScaleResources(this);
        public static void AddScaleResources(CraftSystem system)
        {   
            bool first = true;
            foreach ( ResourceData data in Resources )
            {
                if ( data.ResourceType == CraftResourceType.Scales )
                {
                    if ( first )
                    {
                        system.SetSubRes2( data.ItemType, data.Name );
                        first = false;
                    }
                    system.AddSubRes2( data.ItemType, data.Name, data.MinSkill, data.CantCraftMessage );
                }
            }
        }
       
        //daat99.ResourceHelper.AddTailorResources(this);
        public static void AddTailorResources(CraftSystem system)
        {
            bool first = true;
            foreach ( ResourceData data in Resources )
            {
                if ( data.ResourceType == CraftResourceType.Leather )
                {
                    if ( first )
                    {
                        system.SetSubRes( data.ItemType, data.Name );
                        first = false;
                    }
                    system.AddSubRes( data.ItemType, data.Name, data.MinSkill, data.CantCraftMessage );
                }
            }
        }
        #endregion AddCraftingResources

        public class ResourceData
        {
            public static ResourceData EMPTY = new ResourceData(CraftResourceType.None, CraftResource.None, "", null, null, 0.0, 0);
            public CraftResource CraftResource;
            public string Name;
            public double MinSkill;
            public int CantCraftMessage;
            public Type RawType;
            public Type ItemType;
            public CraftResourceType ResourceType;
            public int Level;
           
            public ResourceData( CraftResourceType resourceType, CraftResource craftResource, string name, Type itemType, Type raw, double minSkill, int cantCraftMessage)
            {
                this.ResourceType = resourceType;
                this.CraftResource = craftResource;
                this.Name = name;
                this.RawType = raw;
                this.ItemType = itemType;
                this.MinSkill = minSkill;
                this.CantCraftMessage = cantCraftMessage;
                this.Level = (int)craftResource;
            }
        }

        public static CraftResource GetLastCraftResourceFromType(CraftResource resource)
        {
            switch (CraftResources.GetType(resource))
            {
                case CraftResourceType.Metal:
                    return CraftResource.Platinum;
                case CraftResourceType.Leather:
                    return CraftResource.EtherealLeather;
                case CraftResourceType.Wood:
                    return CraftResource.Petrified;
                case CraftResourceType.Scales:
                    return CraftResource.GoldScales;
            }
            return CraftResource.None;
        }

        public static CraftResource GetFirstCraftResourceFromType(CraftResource resource)
        {
            switch (CraftResources.GetType(resource))
            {
                case CraftResourceType.Metal:
                    return CraftResource.Iron;
                case CraftResourceType.Leather:
                    return CraftResource.RegularLeather;
                case CraftResourceType.Wood:
                    return CraftResource.RegularWood;
                case CraftResourceType.Scales:
                    return CraftResource.RedScales;
            }
            return CraftResource.None;
        }

        public static Type[][] GetTypesTable()
        {
            return new Type[][]
            {
                //OSI woods
                new Type[]{ typeof( Log ),                 typeof( Board ) },
                new Type[]{ typeof( OakLog ),             typeof( OakBoard ) },
                new Type[]{ typeof( AshLog ),             typeof( AshBoard ) },
                new Type[]{ typeof( YewLog ),             typeof( YewBoard ) },
                new Type[]{ typeof( HeartwoodLog ),     typeof( HeartwoodBoard ) },
                new Type[]{ typeof( BloodwoodLog ),     typeof( BloodwoodBoard ) },
                new Type[]{ typeof( FrostwoodLog ),     typeof( FrostwoodBoard ) },
                //OWLTR custom woods
                new Type[]{ typeof( EbonyLog ),         typeof( EbonyBoard ) },
                new Type[]{ typeof( BambooLog ),         typeof( BambooBoard ) },
                new Type[]{ typeof( PurpleHeartLog ),     typeof( PurpleHeartBoard ) },
                new Type[]{ typeof( RedwoodLog ),         typeof( RedwoodBoard ) },
                new Type[]{ typeof( PetrifiedLog ),     typeof( PetrifiedBoard ) },
                //OSI leathers
                new Type[]{ typeof( Leather ),             typeof( Hides ) },
                new Type[]{ typeof( SpinedLeather ),     typeof( SpinedHides ) },
                new Type[]{ typeof( HornedLeather ),     typeof( HornedHides ) },
                new Type[]{ typeof( BarbedLeather ),     typeof( BarbedHides ) },
                //OWLTR leathers
                new Type[]{ typeof( PolarLeather ),     typeof( PolarHides ) },
                new Type[]{ typeof( SyntheticLeather ), typeof( SyntheticHides ) },
                new Type[]{ typeof( BlazeLeather ),     typeof( BlazeHides ) },
                new Type[]{ typeof( DaemonicLeather ),     typeof( DaemonicHides ) },
                new Type[]{ typeof( ShadowLeather ),     typeof( ShadowHides ) },
                new Type[]{ typeof( FrostLeather ),     typeof( FrostHides ) },
                new Type[]{ typeof( EtherealLeather ),     typeof( EtherealHides ) },
                //OSI other items
                new Type[]{ typeof( BlankMap ),         typeof( BlankScroll ) },
                new Type[]{ typeof( Cloth ),             typeof( UncutCloth ) },
                new Type[]{ typeof( CheeseWheel ),         typeof( CheeseWedge ) },
                new Type[]{ typeof( Pumpkin ),             typeof( SmallPumpkin ) },
                new Type[]{ typeof( WoodenBowlOfPeas ), typeof( PewterBowlOfPeas ) }
            };
        }
    }
}
 
It looks like the call to CraftResources.GetInfo on line 70 is returning null. Perhaps there is a data file that is not getting loaded properly? Where do you configure your custom resources?
 
CraftResourceInfo info = CraftResources.GetInfo(resultCraftResource);

This is returning null. Something wrong with your CraftResources.cs, did you do the necessary edits?
 
Kinda only place where it could get it :

Could it be because
Code:
            new CraftResourceInfo(0x8AB, 1053101, "Valorite", CraftAttributeInfo.Valorite,    CraftResource.Valorite, typeof(ValoriteIngot),    typeof(ValoriteOre), typeof(ValoriteGranite)),
            new CraftResourceInfo( 1161,    0,        "Blaze",        CraftAttributeInfo.Blaze,        CraftResource.Blaze,            typeof( BlazeIngot ),        typeof( BlazeOre ),            typeof( BlazeGranite ) ),

Original has 1053101 but daats one 0 ?



Code:
using System;
using System.Collections;
using daat99;

namespace Server.Items
{
    public enum CraftResource
    {
        None = 0,
        Iron = 1,
        DullCopper,
        ShadowIron,
        Copper,
        Bronze,
        Gold,
        Agapite,
        Verite,
        Valorite,
        //daat99 OWLTR start - custom ores
        Blaze,
        Ice,
        Toxic,
        Electrum,
        Platinum,
        //daat99 OWLTR end - custom ores

        RegularLeather = 101,
        SpinedLeather,
        HornedLeather,
        BarbedLeather,
        //daat99 OWLTR start - custom leather
        PolarLeather,
        SyntheticLeather,
        BlazeLeather,
        DaemonicLeather,
        ShadowLeather,
        FrostLeather,
        EtherealLeather,
        //daat99 OWLTR end - custom leather

        RedScales = 201,
        YellowScales,
        BlackScales,
        GreenScales,
        WhiteScales,
        BlueScales,
        //daat99 OWLTR start - custom scales
        CopperScales,
        SilverScales,
        GoldScales,
        //daat99 OWLTR end - custom scales

        //daat99 OWLTR start - custom wood
        RegularWood = 301,
        OakWood,
        AshWood,
        YewWood,
        Heartwood,
        Bloodwood,
        Frostwood,
        Ebony,
        Bamboo,
        PurpleHeart,
        Redwood,
        Petrified
        //daat99 OWLTR end - custom wood
    }

    public enum CraftResourceType
    {
        None,
        Metal,
        Leather,
        Scales,
        Wood
    }

    public class CraftAttributeInfo
    {
        private int m_WeaponFireDamage;
        private int m_WeaponColdDamage;
        private int m_WeaponPoisonDamage;
        private int m_WeaponEnergyDamage;
        private int m_WeaponChaosDamage;
        private int m_WeaponDirectDamage;
        private int m_WeaponDurability;
        private int m_WeaponLuck;
        private int m_WeaponGoldIncrease;
        private int m_WeaponLowerRequirements;

        private int m_ArmorPhysicalResist;
        private int m_ArmorFireResist;
        private int m_ArmorColdResist;
        private int m_ArmorPoisonResist;
        private int m_ArmorEnergyResist;
        private int m_ArmorDurability;
        private int m_ArmorLuck;
        private int m_ArmorGoldIncrease;
        private int m_ArmorLowerRequirements;

        private int m_RunicMinAttributes;
        private int m_RunicMaxAttributes;
        private int m_RunicMinIntensity;
        private int m_RunicMaxIntensity;

        public int WeaponFireDamage
        {
            get
            {
                return this.m_WeaponFireDamage;
            }
            set
            {
                this.m_WeaponFireDamage = value;
            }
        }
        public int WeaponColdDamage
        {
            get
            {
                return this.m_WeaponColdDamage;
            }
            set
            {
                this.m_WeaponColdDamage = value;
            }
        }
        public int WeaponPoisonDamage
        {
            get
            {
                return this.m_WeaponPoisonDamage;
            }
            set
            {
                this.m_WeaponPoisonDamage = value;
            }
        }
        public int WeaponEnergyDamage
        {
            get
            {
                return this.m_WeaponEnergyDamage;
            }
            set
            {
                this.m_WeaponEnergyDamage = value;
            }
        }
        public int WeaponChaosDamage
        {
            get
            {
                return this.m_WeaponChaosDamage;
            }
            set
            {
                this.m_WeaponChaosDamage = value;
            }
        }
        public int WeaponDirectDamage
        {
            get
            {
                return this.m_WeaponDirectDamage;
            }
            set
            {
                this.m_WeaponDirectDamage = value;
            }
        }
        public int WeaponDurability
        {
            get
            {
                return this.m_WeaponDurability;
            }
            set
            {
                this.m_WeaponDurability = value;
            }
        }
        public int WeaponLuck
        {
            get
            {
                return this.m_WeaponLuck;
            }
            set
            {
                this.m_WeaponLuck = value;
            }
        }
        public int WeaponGoldIncrease
        {
            get
            {
                return this.m_WeaponGoldIncrease;
            }
            set
            {
                this.m_WeaponGoldIncrease = value;
            }
        }
        public int WeaponLowerRequirements
        {
            get
            {
                return this.m_WeaponLowerRequirements;
            }
            set
            {
                this.m_WeaponLowerRequirements = value;
            }
        }

        public int ArmorPhysicalResist
        {
            get
            {
                return this.m_ArmorPhysicalResist;
            }
            set
            {
                this.m_ArmorPhysicalResist = value;
            }
        }
        public int ArmorFireResist
        {
            get
            {
                return this.m_ArmorFireResist;
            }
            set
            {
                this.m_ArmorFireResist = value;
            }
        }
        public int ArmorColdResist
        {
            get
            {
                return this.m_ArmorColdResist;
            }
            set
            {
                this.m_ArmorColdResist = value;
            }
        }
        public int ArmorPoisonResist
        {
            get
            {
                return this.m_ArmorPoisonResist;
            }
            set
            {
                this.m_ArmorPoisonResist = value;
            }
        }
        public int ArmorEnergyResist
        {
            get
            {
                return this.m_ArmorEnergyResist;
            }
            set
            {
                this.m_ArmorEnergyResist = value;
            }
        }
        public int ArmorDurability
        {
            get
            {
                return this.m_ArmorDurability;
            }
            set
            {
                this.m_ArmorDurability = value;
            }
        }
        public int ArmorLuck
        {
            get
            {
                return this.m_ArmorLuck;
            }
            set
            {
                this.m_ArmorLuck = value;
            }
        }
        public int ArmorGoldIncrease
        {
            get
            {
                return this.m_ArmorGoldIncrease;
            }
            set
            {
                this.m_ArmorGoldIncrease = value;
            }
        }
        public int ArmorLowerRequirements
        {
            get
            {
                return this.m_ArmorLowerRequirements;
            }
            set
            {
                this.m_ArmorLowerRequirements = value;
            }
        }

        public int RunicMinAttributes
        {
            get
            {
                return this.m_RunicMinAttributes;
            }
            set
            {
                this.m_RunicMinAttributes = value;
            }
        }
        public int RunicMaxAttributes
        {
            get
            {
                return this.m_RunicMaxAttributes;
            }
            set
            {
                this.m_RunicMaxAttributes = value;
            }
        }
        public int RunicMinIntensity
        {
            get
            {
                return this.m_RunicMinIntensity;
            }
            set
            {
                this.m_RunicMinIntensity = value;
            }
        }
        public int RunicMaxIntensity
        {
            get
            {
                return this.m_RunicMaxIntensity;
            }
            set
            {
                this.m_RunicMaxIntensity = value;
            }
        }

        #region Mondain's Legacy
        private int m_WeaponDamage;
        private int m_WeaponHitChance;
        private int m_WeaponHitLifeLeech;
        private int m_WeaponRegenHits;
        private int m_WeaponSwingSpeed;

        private int m_ArmorDamage;
        private int m_ArmorHitChance;
        private int m_ArmorRegenHits;
        private int m_ArmorMage;

        private int m_ShieldPhysicalResist;
        private int m_ShieldFireResist;
        private int m_ShieldColdResist;
        private int m_ShieldPoisonResist;
        private int m_ShieldEnergyResist;

        public int WeaponDamage
        {
            get
            {
                return this.m_WeaponDamage;
            }
            set
            {
                this.m_WeaponDamage = value;
            }
        }
        public int WeaponHitChance
        {
            get
            {
                return this.m_WeaponHitChance;
            }
            set
            {
                this.m_WeaponHitChance = value;
            }
        }
        public int WeaponHitLifeLeech
        {
            get
            {
                return this.m_WeaponHitLifeLeech;
            }
            set
            {
                this.m_WeaponHitLifeLeech = value;
            }
        }
        public int WeaponRegenHits
        {
            get
            {
                return this.m_WeaponRegenHits;
            }
            set
            {
                this.m_WeaponRegenHits = value;
            }
        }
        public int WeaponSwingSpeed
        {
            get
            {
                return this.m_WeaponSwingSpeed;
            }
            set
            {
                this.m_WeaponSwingSpeed = value;
            }
        }

        public int ArmorDamage
        {
            get
            {
                return this.m_ArmorDamage;
            }
            set
            {
                this.m_ArmorDamage = value;
            }
        }
        public int ArmorHitChance
        {
            get
            {
                return this.m_ArmorHitChance;
            }
            set
            {
                this.m_ArmorHitChance = value;
            }
        }
        public int ArmorRegenHits
        {
            get
            {
                return this.m_ArmorRegenHits;
            }
            set
            {
                this.m_ArmorRegenHits = value;
            }
        }
        public int ArmorMage
        {
            get
            {
                return this.m_ArmorMage;
            }
            set
            {
                this.m_ArmorMage = value;
            }
        }

        public int ShieldPhysicalResist
        {
            get
            {
                return this.m_ShieldPhysicalResist;
            }
            set
            {
                this.m_ShieldPhysicalResist = value;
            }
        }
        public int ShieldFireResist
        {
            get
            {
                return this.m_ShieldFireResist;
            }
            set
            {
                this.m_ShieldFireResist = value;
            }
        }
        public int ShieldColdResist
        {
            get
            {
                return this.m_ShieldColdResist;
            }
            set
            {
                this.m_ShieldColdResist = value;
            }
        }
        public int ShieldPoisonResist
        {
            get
            {
                return this.m_ShieldPoisonResist;
            }
            set
            {
                this.m_ShieldPoisonResist = value;
            }
        }
        public int ShieldEnergyResist
        {
            get
            {
                return this.m_ShieldEnergyResist;
            }
            set
            {
                this.m_ShieldEnergyResist = value;
            }
        }
        #endregion

        public CraftAttributeInfo()
        {
        }

        public static readonly CraftAttributeInfo Blank;
        public static readonly CraftAttributeInfo DullCopper, ShadowIron, Copper, Bronze, Golden, Agapite, Verite, Valorite, Blaze, Ice, Toxic, Electrum, Platinum;
        public static readonly CraftAttributeInfo Spined, Horned, Barbed, Polar, Synthetic, BlazeL, Daemonic, Shadow, Frost, Ethereal;
        public static readonly CraftAttributeInfo RedScales, YellowScales, BlackScales, GreenScales, WhiteScales, BlueScales, CopperScales, SilverScales, GoldScales;
        public static readonly CraftAttributeInfo OakWood, AshWood, YewWood, Heartwood, Bloodwood, Frostwood, Ebony, Bamboo, PurpleHeart, Redwood, Petrified;

        static CraftAttributeInfo()
        {
            Blank = new CraftAttributeInfo();

            //daat99 OWLTR start - custom resources
            bool Uber = OWLTROptionsManager.IsEnabled(OWLTROptionsManager.OPTIONS_ENUM.UBBER_RESOURCES);
            CraftAttributeInfo dullCopper = DullCopper = new CraftAttributeInfo();

            dullCopper.ArmorPhysicalResist = Uber ? 1 : Utility.Random(2);
            dullCopper.ArmorFireResist = Uber ? 1 : Utility.Random(2);
            dullCopper.ArmorColdResist = Uber ? 1 : Utility.Random(2);
            dullCopper.ArmorPoisonResist = Uber ? 1 : Utility.Random(2);
            dullCopper.ArmorEnergyResist = Uber ? 1 : Utility.Random(2);
            dullCopper.ArmorDurability = 10;
            dullCopper.WeaponDurability = 10;
            dullCopper.ArmorLowerRequirements = 5;
            dullCopper.WeaponLowerRequirements = 5;
            dullCopper.RunicMinAttributes = 1;
            dullCopper.RunicMaxAttributes = Uber ? 2 : 1;
            dullCopper.RunicMinIntensity = Uber ? 25 : 10;
            dullCopper.RunicMaxIntensity = Uber ? 100 : 25;

            CraftAttributeInfo shadowIron = ShadowIron = new CraftAttributeInfo();

            shadowIron.ArmorPhysicalResist = Uber ? 2 : Utility.Random(3);
            shadowIron.ArmorFireResist = Uber ? 1 : Utility.Random(2);
            shadowIron.ArmorColdResist = Uber ? 1 : Utility.Random(2);
            shadowIron.ArmorPoisonResist = Uber ? 1 : Utility.Random(2);
            shadowIron.ArmorEnergyResist = Uber ? 1 : Utility.Random(2);
            shadowIron.ArmorDurability = 20;
            shadowIron.WeaponDurability = 20;
            shadowIron.ArmorLowerRequirements = 10;
            shadowIron.WeaponLowerRequirements = 10;
            shadowIron.WeaponColdDamage = 20;
            shadowIron.RunicMinAttributes = 1;
            shadowIron.RunicMaxAttributes = Uber ? 3 : 2;
            shadowIron.RunicMinIntensity = Uber ? 30 : 15;
            shadowIron.RunicMaxIntensity = Uber ? 100 : 30;

            CraftAttributeInfo copper = Copper = new CraftAttributeInfo();

            copper.ArmorPhysicalResist = Uber ? 2 : Utility.Random(3);
            copper.ArmorFireResist = Uber ? 2 : Utility.Random(3);
            copper.ArmorColdResist = Uber ? 2 : Utility.Random(3);
            copper.ArmorPoisonResist = Uber ? 2 : Utility.Random(3);
            copper.ArmorEnergyResist = Uber ? 2 : Utility.Random(3);
            copper.ArmorDurability = 30;
            copper.WeaponDurability = 30;
            copper.ArmorLowerRequirements = 15;
            copper.WeaponLowerRequirements = 15;
            copper.WeaponPoisonDamage = 10;
            copper.WeaponEnergyDamage = 20;
            copper.RunicMinAttributes = 2;
            copper.RunicMaxAttributes = Uber ? 3 : 2;
            copper.RunicMinIntensity = Uber ? 40 : 20;
            copper.RunicMaxIntensity = Uber ? 100 : 40;

            CraftAttributeInfo bronze = Bronze = new CraftAttributeInfo();

            bronze.ArmorPhysicalResist = Uber ? 2 : Utility.Random(3);
            bronze.ArmorFireResist = Uber ? 3 : Utility.Random(4);
            bronze.ArmorColdResist = Uber ? 2 : Utility.Random(3);
            bronze.ArmorPoisonResist = Uber ? 2 : Utility.Random(3);
            bronze.ArmorEnergyResist = Uber ? 2 : Utility.Random(3);
            bronze.ArmorDurability = 40;
            bronze.WeaponDurability = 40;
            bronze.ArmorLowerRequirements = 20;
            bronze.WeaponLowerRequirements = 20;
            bronze.WeaponFireDamage = 40;
            bronze.RunicMinAttributes = 2;
            bronze.RunicMaxAttributes = Uber ? 4 : 3;
            bronze.RunicMinIntensity = Uber ? 45 : 25;
            bronze.RunicMaxIntensity = Uber ? 100 : 45;

            CraftAttributeInfo golden = Golden = new CraftAttributeInfo();

            golden.ArmorPhysicalResist = Uber ? 3 : Utility.Random(4);
            golden.ArmorFireResist = Uber ? 3 : Utility.Random(4);
            golden.ArmorColdResist = Uber ? 3 : Utility.Random(4);
            golden.ArmorPoisonResist = Uber ? 3 : Utility.Random(4);
            golden.ArmorEnergyResist = Uber ? 3 : Utility.Random(4);
            golden.ArmorDurability = 55;
            golden.WeaponDurability = 55;
            golden.ArmorLowerRequirements = 25;
            golden.WeaponLowerRequirements = 25;
            golden.ArmorLuck = 40;
            golden.ArmorLowerRequirements = 30;
            golden.WeaponLuck = 40;
            golden.WeaponLowerRequirements = 50;
            golden.RunicMinAttributes = 2;
            golden.RunicMaxAttributes = Uber ? 5 : 3;
            golden.RunicMinIntensity = Uber ? 50 : 30;
            golden.RunicMaxIntensity = Uber ? 100 : 50;

            CraftAttributeInfo agapite = Agapite = new CraftAttributeInfo();

            agapite.ArmorPhysicalResist = Uber ? 3 : Utility.Random(4);
            agapite.ArmorFireResist = Uber ? 3 : Utility.Random(4);
            agapite.ArmorColdResist = Uber ? 4 : Utility.Random(5);
            agapite.ArmorPoisonResist = Uber ? 3 : Utility.Random(4);
            agapite.ArmorEnergyResist = Uber ? 3 : Utility.Random(4);
            agapite.ArmorDurability = 70;
            agapite.WeaponDurability = 70;
            agapite.ArmorLowerRequirements = 30;
            agapite.WeaponLowerRequirements = 30;
            agapite.WeaponColdDamage = 30;
            agapite.WeaponEnergyDamage = 20;
            agapite.RunicMinAttributes = 3;
            agapite.RunicMaxAttributes = Uber ? 5 : 3;
            agapite.RunicMinIntensity = Uber ? 55 : 35;
            agapite.RunicMaxIntensity = Uber ? 100 : 55;

            CraftAttributeInfo verite = Verite = new CraftAttributeInfo();

            verite.ArmorPhysicalResist = Uber ? 4 : Utility.Random(5);
            verite.ArmorFireResist = Uber ? 4 : Utility.Random(5);
            verite.ArmorColdResist = Uber ? 4 : Utility.Random(5);
            verite.ArmorPoisonResist = Uber ? 4 : Utility.Random(5);
            verite.ArmorEnergyResist = Uber ? 4 : Utility.Random(5);
            verite.ArmorDurability = 85;
            verite.WeaponDurability = 85;
            verite.ArmorLowerRequirements = 40;
            verite.WeaponLowerRequirements = 40;
            verite.WeaponPoisonDamage = 40;
            verite.WeaponEnergyDamage = 20;
            verite.RunicMinAttributes = 3;
            verite.RunicMaxAttributes = Uber ? 5 : 4;
            verite.RunicMinIntensity = Uber ? 65 : 40;
            verite.RunicMaxIntensity = Uber ? 100 : 65;

            CraftAttributeInfo valorite = Valorite = new CraftAttributeInfo();

            valorite.ArmorPhysicalResist = Uber ? 4 : Utility.Random(5);
            valorite.ArmorFireResist = Uber ? 4 : Utility.Random(5);
            valorite.ArmorColdResist = Uber ? 4 : Utility.Random(5);
            valorite.ArmorPoisonResist = Uber ? 5 : Utility.Random(6);
            valorite.ArmorEnergyResist = Uber ? 4 : Utility.Random(5);
            valorite.ArmorDurability = 100;
            valorite.WeaponDurability = 100;
            valorite.ArmorLowerRequirements = 50;
            valorite.WeaponLowerRequirements = 50;
            valorite.WeaponFireDamage = 10;
            valorite.WeaponColdDamage = 20;
            valorite.WeaponPoisonDamage = 10;
            valorite.WeaponEnergyDamage = 20;
            valorite.RunicMinAttributes = 4;
            valorite.RunicMaxAttributes = Uber ? 6 : 4;
            valorite.RunicMinIntensity = Uber ? 70 : 45;
            valorite.RunicMaxIntensity = Uber ? 100 : 70;

            CraftAttributeInfo blaze = Blaze = new CraftAttributeInfo();

            blaze.ArmorPhysicalResist = Uber ? 5 : Utility.Random(6);
            blaze.ArmorFireResist = Uber ? 5 : Utility.Random(6);
            blaze.ArmorColdResist = Uber ? 5 : Utility.Random(6);
            blaze.ArmorPoisonResist = Uber ? 5 : Utility.Random(6);
            blaze.ArmorEnergyResist = Uber ? 5 : Utility.Random(6);
            blaze.ArmorDurability = 125;
            blaze.WeaponDurability = 125;
            blaze.ArmorLowerRequirements = 60;
            blaze.WeaponLowerRequirements = 60;
            blaze.WeaponFireDamage = 100;
            blaze.RunicMinAttributes = 4;
            blaze.RunicMaxAttributes = Uber ? 7 : 5;
            blaze.RunicMinIntensity = Uber ? 75 : 50;
            blaze.RunicMaxIntensity = Uber ? 100 : 75;

            CraftAttributeInfo ice = Ice = new CraftAttributeInfo();

            ice.ArmorPhysicalResist = Uber ? 5 : Utility.Random(6);
            ice.ArmorFireResist = Uber ? 5 : Utility.Random(6);
            ice.ArmorColdResist = Uber ? 5 : Utility.Random(6);
            ice.ArmorPoisonResist = Uber ? 5 : Utility.Random(6);
            ice.ArmorEnergyResist = Uber ? 6 : Utility.Random(7);
            ice.ArmorDurability = 150;
            ice.WeaponDurability = 150;
            ice.ArmorLowerRequirements = 70;
            ice.WeaponLowerRequirements = 70;
            ice.WeaponColdDamage = 100;
            ice.RunicMinAttributes = 5;
            ice.RunicMaxAttributes = Uber ? 8 : 5;
            ice.RunicMinIntensity = Uber ? 80 : 55;
            ice.RunicMaxIntensity = Uber ? 100 : 80;

            CraftAttributeInfo toxic = Toxic = new CraftAttributeInfo();

            toxic.ArmorPhysicalResist = Uber ? 6 : Utility.Random(7);
            toxic.ArmorFireResist = Uber ? 6 : Utility.Random(7);
            toxic.ArmorColdResist = Uber ? 6 : Utility.Random(7);
            toxic.ArmorPoisonResist = Uber ? 6 : Utility.Random(7);
            toxic.ArmorEnergyResist = Uber ? 6 : Utility.Random(7);
            toxic.ArmorDurability = 175;
            toxic.WeaponDurability = 175;
            toxic.ArmorLowerRequirements = 80;
            toxic.WeaponLowerRequirements = 80;
            toxic.WeaponPoisonDamage = 100;
            toxic.RunicMinAttributes = 5;
            toxic.RunicMaxAttributes = Uber ? 8 : 6;
            toxic.RunicMinIntensity = Uber ? 90 : 60;
            toxic.RunicMaxIntensity = Uber ? 100 : 90;

            CraftAttributeInfo electrum = Electrum = new CraftAttributeInfo();

            electrum.ArmorPhysicalResist = Uber ? 7 : Utility.Random(8);
            electrum.ArmorFireResist = Uber ? 7 : Utility.Random(8);
            electrum.ArmorColdResist = Uber ? 7 : Utility.Random(8);
            electrum.ArmorPoisonResist = Uber ? 7 : Utility.Random(8);
            electrum.ArmorEnergyResist = Uber ? 7 : Utility.Random(8);
            electrum.ArmorDurability = 200;
            electrum.WeaponDurability = 200;
            electrum.ArmorLowerRequirements = 90;
            electrum.WeaponLowerRequirements = 90;
            electrum.WeaponEnergyDamage = 100;
            electrum.RunicMinAttributes = 5;
            electrum.RunicMaxAttributes = Uber ? 9 : 6;
            electrum.RunicMinIntensity = Uber ? 100 : 65;
            electrum.RunicMaxIntensity = Uber ? 100 : 100;

            CraftAttributeInfo platinum = Platinum = new CraftAttributeInfo();

            platinum.ArmorPhysicalResist = Uber ? 8 : Utility.Random(9);
            platinum.ArmorFireResist = Uber ? 8 : Utility.Random(9);
            platinum.ArmorColdResist = Uber ? 8 : Utility.Random(9);
            platinum.ArmorPoisonResist = Uber ? 8 : Utility.Random(9);
            platinum.ArmorEnergyResist = Uber ? 8 : Utility.Random(9);
            platinum.ArmorDurability = 250;
            platinum.WeaponDurability = 250;
            platinum.ArmorLowerRequirements = 100;
            platinum.WeaponLowerRequirements = 100;
            platinum.RunicMinAttributes = 6;
            platinum.RunicMaxAttributes = Uber ? 9 : 7;
            platinum.RunicMinIntensity = Uber ? 105 : 70;
            platinum.RunicMaxIntensity = Uber ? 110 : 105;

            CraftAttributeInfo spined = Spined = new CraftAttributeInfo();

            spined.ArmorPhysicalResist = Uber ? 1 : Utility.Random(2);
            spined.ArmorFireResist = Uber ? 1 : Utility.Random(2);
            spined.ArmorColdResist = Uber ? 1 : Utility.Random(2);
            spined.ArmorPoisonResist = Uber ? 1 : Utility.Random(2);
            spined.ArmorEnergyResist = Uber ? 1 : Utility.Random(2);
            spined.ArmorDurability = 25;
            spined.ArmorLowerRequirements = 20;
            spined.ArmorLuck = 40;
            spined.RunicMinAttributes = 1;
            spined.RunicMaxAttributes = Uber ? 3 : 2;
            spined.RunicMinIntensity = Uber ? 20 : 10;
            spined.RunicMaxIntensity = Uber ? 100 : 20;

            CraftAttributeInfo horned = Horned = new CraftAttributeInfo();

            horned.ArmorPhysicalResist = Uber ? 2 : Utility.Random(3);
            horned.ArmorFireResist = Uber ? 2 : Utility.Random(3);
            horned.ArmorColdResist = Uber ? 2 : Utility.Random(3);
            horned.ArmorPoisonResist = Uber ? 2 : Utility.Random(3);
            horned.ArmorEnergyResist = Uber ? 2 : Utility.Random(3);
            horned.ArmorDurability = 50;
            horned.ArmorLowerRequirements = 30;
            horned.RunicMinAttributes = 2;
            horned.RunicMaxAttributes = Uber ? 3 : 2;
            horned.RunicMinIntensity = Uber ? 30 : 15;
            horned.RunicMaxIntensity = Uber ? 100 : 30;

            CraftAttributeInfo barbed = Barbed = new CraftAttributeInfo();

            barbed.ArmorPhysicalResist = Uber ? 3 : Utility.Random(4);
            barbed.ArmorFireResist = Uber ? 3 : Utility.Random(4);
            barbed.ArmorColdResist = Uber ? 3 : Utility.Random(4);
            barbed.ArmorPoisonResist = Uber ? 3 : Utility.Random(4);
            barbed.ArmorEnergyResist = Uber ? 3 : Utility.Random(4);
            barbed.ArmorDurability = 75;
            barbed.ArmorLowerRequirements = 40;
            barbed.RunicMinAttributes = 2;
            barbed.RunicMaxAttributes = Uber ? 4 : 3;
            barbed.RunicMinIntensity = Uber ? 35 : 20;
            barbed.RunicMaxIntensity = Uber ? 100 : 35;

            CraftAttributeInfo polar = Polar = new CraftAttributeInfo();

            polar.ArmorPhysicalResist = Uber ? 4 : Utility.Random(5);
            polar.ArmorFireResist = Uber ? 3 : Utility.Random(4);
            polar.ArmorColdResist = Uber ? 4 : Utility.Random(5);
            polar.ArmorPoisonResist = Uber ? 3 : Utility.Random(4);
            polar.ArmorEnergyResist = Uber ? 4 : Utility.Random(5);
            polar.ArmorDurability = 100;
            polar.ArmorLowerRequirements = 50;
            polar.RunicMinAttributes = 3;
            polar.RunicMaxAttributes = Uber ? 5 : 3;
            polar.RunicMinIntensity = Uber ? 45 : 25;
            polar.RunicMaxIntensity = Uber ? 100 : 45;

            CraftAttributeInfo synthetic = Synthetic = new CraftAttributeInfo();

            synthetic.ArmorPhysicalResist = Uber ? 4 : Utility.Random(5);
            synthetic.ArmorFireResist = Uber ? 4 : Utility.Random(5);
            synthetic.ArmorColdResist = Uber ? 4 : Utility.Random(5);
            synthetic.ArmorPoisonResist = Uber ? 4 : Utility.Random(5);
            synthetic.ArmorEnergyResist = Uber ? 4 : Utility.Random(5);
            synthetic.ArmorLowerRequirements = 60;
            synthetic.ArmorDurability = 125;
            synthetic.RunicMinAttributes = 3;
            synthetic.RunicMaxAttributes = Uber ? 5 : 4;
            synthetic.RunicMinIntensity = Uber ? 50 : 30;
            synthetic.RunicMaxIntensity = Uber ? 100 : 50;

            CraftAttributeInfo blazel = BlazeL = new CraftAttributeInfo();

            blazel.ArmorPhysicalResist = Uber ? 4 : Utility.Random(5);
            blazel.ArmorFireResist = Uber ? 5 : Utility.Random(6);
            blazel.ArmorColdResist = Uber ? 4 : Utility.Random(5);
            blazel.ArmorPoisonResist = Uber ? 5 : Utility.Random(6);
            blazel.ArmorEnergyResist = Uber ? 4 : Utility.Random(5);
            blazel.ArmorLowerRequirements = 60;
            blazel.ArmorDurability = 125;
            blazel.RunicMinAttributes = 4;
            blazel.RunicMaxAttributes = Uber ? 6 : 4;
            blazel.RunicMinIntensity = Uber ? 60 : 35;
            blazel.RunicMaxIntensity = Uber ? 100 : 60;

            CraftAttributeInfo daemonic = Daemonic = new CraftAttributeInfo();

            daemonic.ArmorPhysicalResist = Uber ? 5 : Utility.Random(6);
            daemonic.ArmorFireResist = Uber ? 5 : Utility.Random(6);
            daemonic.ArmorColdResist = Uber ? 5 : Utility.Random(6);
            daemonic.ArmorPoisonResist = Uber ? 5 : Utility.Random(6);
            daemonic.ArmorEnergyResist = Uber ? 5 : Utility.Random(6);
            daemonic.ArmorDurability = 150;
            daemonic.ArmorLowerRequirements = 70;
            daemonic.RunicMinAttributes = 4;
            daemonic.RunicMaxAttributes = Uber ? 7 : 5;
            daemonic.RunicMinIntensity = Uber ? 65 : 40;
            daemonic.RunicMaxIntensity = Uber ? 100 : 65;

            CraftAttributeInfo shadow = Shadow = new CraftAttributeInfo();

            shadow.ArmorPhysicalResist = Uber ? 6 : Utility.Random(7);
            shadow.ArmorFireResist = Uber ? 6 : Utility.Random(7);
            shadow.ArmorColdResist = Uber ? 6 : Utility.Random(7);
            shadow.ArmorPoisonResist = Uber ? 6 : Utility.Random(7);
            shadow.ArmorEnergyResist = Uber ? 6 : Utility.Random(7);
            shadow.ArmorDurability = 175;
            shadow.ArmorLowerRequirements = 80;
            shadow.RunicMinAttributes = 5;
            shadow.RunicMaxAttributes = Uber ? 7 : 5;
            shadow.RunicMinIntensity = Uber ? 75 : 45;
            shadow.RunicMaxIntensity = Uber ? 100 : 75;

            CraftAttributeInfo frost = Frost = new CraftAttributeInfo();

            frost.ArmorPhysicalResist = Uber ? 7 : Utility.Random(8);
            frost.ArmorFireResist = Uber ? 7 : Utility.Random(8);
            frost.ArmorColdResist = Uber ? 7 : Utility.Random(8);
            frost.ArmorPoisonResist = Uber ? 7 : Utility.Random(8);
            frost.ArmorEnergyResist = Uber ? 7 : Utility.Random(8);
            frost.ArmorDurability = 200;
            frost.ArmorLowerRequirements = 90;
            frost.RunicMinAttributes = 5;
            frost.RunicMaxAttributes = Uber ? 8 : 6;
            frost.RunicMinIntensity = Uber ? 80 : 50;
            frost.RunicMaxIntensity = Uber ? 100 : 80;

            CraftAttributeInfo ethereal = Ethereal = new CraftAttributeInfo();

            ethereal.ArmorPhysicalResist = Uber ? 8 : Utility.Random(9);
            ethereal.ArmorFireResist = Uber ? 8 : Utility.Random(9);
            ethereal.ArmorColdResist = Uber ? 8 : Utility.Random(9);
            ethereal.ArmorPoisonResist = Uber ? 8 : Utility.Random(9);
            ethereal.ArmorEnergyResist = Uber ? 8 : Utility.Random(9);
            ethereal.ArmorDurability = 250;
            ethereal.ArmorLowerRequirements = 100;
            ethereal.RunicMinAttributes = 6;
            ethereal.RunicMaxAttributes = Uber ? 9 : 7;
            ethereal.RunicMinIntensity = Uber ? 100 : 60;
            ethereal.RunicMaxIntensity = Uber ? 110 : 100;

            CraftAttributeInfo red = RedScales = new CraftAttributeInfo();

            red.ArmorFireResist = 10;
            red.ArmorColdResist = -3;

            CraftAttributeInfo yellow = YellowScales = new CraftAttributeInfo();

            yellow.ArmorPhysicalResist = -3;
            yellow.ArmorLuck = 20;

            CraftAttributeInfo black = BlackScales = new CraftAttributeInfo();

            black.ArmorPhysicalResist = 10;
            black.ArmorEnergyResist = -3;

            CraftAttributeInfo green = GreenScales = new CraftAttributeInfo();

            green.ArmorFireResist = -3;
            green.ArmorPoisonResist = 10;

            CraftAttributeInfo white = WhiteScales = new CraftAttributeInfo();

            white.ArmorPhysicalResist = -3;
            white.ArmorColdResist = 10;

            CraftAttributeInfo blue = BlueScales = new CraftAttributeInfo();

            blue.ArmorPoisonResist = -3;
            blue.ArmorEnergyResist = 10;

            CraftAttributeInfo coppers = CopperScales = new CraftAttributeInfo();

            coppers.ArmorPoisonResist = Uber ? 6 : Utility.Random(7);
            coppers.ArmorPhysicalResist = Uber ? 6 : Utility.Random(7);
            coppers.ArmorEnergyResist = Uber ? 6 : Utility.Random(7);

            CraftAttributeInfo silver = SilverScales = new CraftAttributeInfo();

            silver.ArmorColdResist = Uber ? 7 : Utility.Random(8);
            silver.ArmorEnergyResist = Uber ? 7 : Utility.Random(8);
            silver.ArmorPhysicalResist = Uber ? 7 : Utility.Random(8);

            CraftAttributeInfo gold = GoldScales = new CraftAttributeInfo();

            gold.ArmorPoisonResist = Uber ? 8 : Utility.Random(9);
            gold.ArmorColdResist = Uber ? 8 : Utility.Random(9);
            gold.ArmorPhysicalResist = Uber ? 8 : Utility.Random(9);
            gold.ArmorEnergyResist = Uber ? 8 : Utility.Random(9);
            gold.ArmorFireResist = Uber ? 8 : Utility.Random(9);

            CraftAttributeInfo oak = OakWood = new CraftAttributeInfo();

            oak.WeaponColdDamage = 20;
            oak.WeaponDurability = 10;
            oak.WeaponLowerRequirements = 5;
            oak.RunicMinAttributes = 1;
            oak.RunicMaxAttributes = Uber ? 2 : 2;
            oak.RunicMinIntensity = Uber ? 10 : 5;
            oak.RunicMaxIntensity = 100;

            CraftAttributeInfo ash = AshWood = new CraftAttributeInfo();

            ash.WeaponFireDamage = 40;
            ash.WeaponDurability = 25;
            ash.WeaponLowerRequirements = 10;
            ash.RunicMinAttributes = 2;
            ash.RunicMaxAttributes = Uber ? 3 : 2;
            ash.RunicMinIntensity = Uber ? 15 : 10;
            ash.RunicMaxIntensity = 100;

            CraftAttributeInfo yew = YewWood = new CraftAttributeInfo();

            yew.WeaponPoisonDamage = 10;
            yew.WeaponEnergyDamage = 20;
            yew.WeaponDurability = 50;
            yew.WeaponLowerRequirements = 20;
            yew.RunicMinAttributes = 1;
            yew.RunicMaxAttributes = Uber ? 4 : 3;
            yew.RunicMinIntensity = Uber ? 20 : 15;
            yew.RunicMaxIntensity = 100;

            CraftAttributeInfo heartwood = Heartwood = new CraftAttributeInfo();

            heartwood.WeaponColdDamage = 30;
            heartwood.WeaponEnergyDamage = 20;
            heartwood.WeaponDurability = 75;
            heartwood.WeaponLowerRequirements = 30;
            heartwood.RunicMinAttributes = 2;
            heartwood.RunicMaxAttributes = Uber ? 5 : 3;
            heartwood.RunicMinIntensity = Uber ? 30 : 20;
            heartwood.RunicMaxIntensity = 100;

            CraftAttributeInfo bloodwood = Bloodwood = new CraftAttributeInfo();

            bloodwood.WeaponPoisonDamage = 40;
            bloodwood.WeaponEnergyDamage = 20;
            bloodwood.WeaponDurability = 100;
            bloodwood.WeaponLowerRequirements = 40;
            bloodwood.RunicMinAttributes = 3;
            bloodwood.RunicMaxAttributes = Uber ? 5 : 3;
            bloodwood.RunicMinIntensity = Uber ? 40 : 25;
            bloodwood.RunicMaxIntensity = 100;

            CraftAttributeInfo Frostwood = Frostwood = new CraftAttributeInfo();

            Frostwood.WeaponDurability = 125;
            Frostwood.WeaponLowerRequirements = 50;
            Frostwood.WeaponFireDamage = 25;
            Frostwood.WeaponColdDamage = 25;
            Frostwood.WeaponPoisonDamage = 25;
            Frostwood.WeaponEnergyDamage = 25;
            Frostwood.RunicMinAttributes = 2;
            Frostwood.RunicMaxAttributes = Uber ? 6 : 4;
            Frostwood.RunicMinIntensity = Uber ? 50 : 30;
            Frostwood.RunicMaxIntensity = 100;

            CraftAttributeInfo ebony = Ebony = new CraftAttributeInfo();

            ebony.WeaponDurability = 150;
            ebony.WeaponLowerRequirements = 60;
            ebony.WeaponColdDamage = 100;
            ebony.RunicMinAttributes = 3;
            ebony.RunicMaxAttributes = Uber ? 6 : 4;
            ebony.RunicMinIntensity = Uber ? 60 : 35;
            ebony.RunicMaxIntensity = 100;

            CraftAttributeInfo bamboo = Bamboo = new CraftAttributeInfo();

            bamboo.WeaponDurability = 175;
            bamboo.WeaponLowerRequirements = 70;
            bamboo.WeaponEnergyDamage = 100;
            bamboo.RunicMinAttributes = 4;
            bamboo.RunicMaxAttributes = Uber ? 7 : 4;
            bamboo.RunicMinIntensity = Uber ? 70 : 40;
            bamboo.RunicMaxIntensity = 100;

            CraftAttributeInfo purpleheart = PurpleHeart = new CraftAttributeInfo();

            purpleheart.WeaponDurability = 200;
            purpleheart.WeaponLowerRequirements = 80;
            purpleheart.WeaponFireDamage = 100;
            purpleheart.RunicMinAttributes = 3;
            purpleheart.RunicMaxAttributes = Uber ? 7 : 5;
            purpleheart.RunicMinIntensity = Uber ? 80 : 50;
            purpleheart.RunicMaxIntensity = 100;

            CraftAttributeInfo redwood = Redwood = new CraftAttributeInfo();

            redwood.WeaponDurability = 225;
            redwood.WeaponLowerRequirements = 90;
            redwood.WeaponPoisonDamage = 100;
            redwood.RunicMinAttributes = 4;
            redwood.RunicMaxAttributes = Uber ? 8 : 5;
            redwood.RunicMinIntensity = Uber ? 90 : 55;
            redwood.RunicMaxIntensity = 100;

            CraftAttributeInfo petrified = Petrified = new CraftAttributeInfo();

            petrified.WeaponDurability = 250;
            petrified.WeaponLowerRequirements = 100;
            petrified.RunicMinAttributes = 5;
            petrified.RunicMaxAttributes = Uber ? 8 : 5;
            petrified.RunicMinIntensity = Uber ? 100 : 60;
            petrified.RunicMaxIntensity = 100;
            //daat99 OWLTR end - custom resources
        }
    }

    public class CraftResourceInfo
    {
        private readonly int m_Hue;
        private readonly int m_Number;
        private readonly string m_Name;
        private readonly CraftAttributeInfo m_AttributeInfo;
        private readonly CraftResource m_Resource;
        private readonly Type[] m_ResourceTypes;

        public int Hue
        {
            get
            {
                return this.m_Hue;
            }
        }
        public int Number
        {
            get
            {
                return this.m_Number;
            }
        }
        public string Name
        {
            get
            {
                return this.m_Name;
            }
        }
        public CraftAttributeInfo AttributeInfo
        {
            get
            {
                return this.m_AttributeInfo;
            }
        }
        public CraftResource Resource
        {
            get
            {
                return this.m_Resource;
            }
        }
        public Type[] ResourceTypes
        {
            get
            {
                return this.m_ResourceTypes;
            }
        }

        public CraftResourceInfo(int hue, int number, string name, CraftAttributeInfo attributeInfo, CraftResource resource, params Type[] resourceTypes)
        {
            this.m_Hue = hue;
            this.m_Number = number;
            this.m_Name = name;
            this.m_AttributeInfo = attributeInfo;
            this.m_Resource = resource;
            this.m_ResourceTypes = resourceTypes;

            for (int i = 0; i < resourceTypes.Length; ++i)
                CraftResources.RegisterType(resourceTypes[i], resource);
        }
    }

    public class CraftResources
    {
        private static readonly CraftResourceInfo[] m_MetalInfo = new CraftResourceInfo[]
        {
            new CraftResourceInfo(0x000, 1053109, "Iron", CraftAttributeInfo.Blank, CraftResource.Iron, typeof(IronIngot), typeof(IronOre), typeof(Granite)),
            new CraftResourceInfo(0x973, 1053108, "Dull Copper",    CraftAttributeInfo.DullCopper,    CraftResource.DullCopper, typeof(DullCopperIngot),    typeof(DullCopperOre),    typeof(DullCopperGranite)),
            new CraftResourceInfo(0x966, 1053107, "Shadow Iron",    CraftAttributeInfo.ShadowIron,    CraftResource.ShadowIron, typeof(ShadowIronIngot),    typeof(ShadowIronOre),    typeof(ShadowIronGranite)),
            new CraftResourceInfo(0x96D, 1053106, "Copper", CraftAttributeInfo.Copper, CraftResource.Copper, typeof(CopperIngot), typeof(CopperOre), typeof(CopperGranite)),
            new CraftResourceInfo(0x972, 1053105, "Bronze", CraftAttributeInfo.Bronze, CraftResource.Bronze, typeof(BronzeIngot), typeof(BronzeOre), typeof(BronzeGranite)),
            new CraftResourceInfo(0x8A5, 1053104, "Gold", CraftAttributeInfo.Golden, CraftResource.Gold, typeof(GoldIngot), typeof(GoldOre), typeof(GoldGranite)),
            new CraftResourceInfo(0x979, 1053103, "Agapite", CraftAttributeInfo.Agapite, CraftResource.Agapite, typeof(AgapiteIngot), typeof(AgapiteOre), typeof(AgapiteGranite)),
            new CraftResourceInfo(0x89F, 1053102, "Verite", CraftAttributeInfo.Verite, CraftResource.Verite, typeof(VeriteIngot), typeof(VeriteOre), typeof(VeriteGranite)),
            new CraftResourceInfo(0x8AB, 1053101, "Valorite", CraftAttributeInfo.Valorite,    CraftResource.Valorite, typeof(ValoriteIngot),    typeof(ValoriteOre), typeof(ValoriteGranite)),
            new CraftResourceInfo( 1161,    0,        "Blaze",        CraftAttributeInfo.Blaze,        CraftResource.Blaze,            typeof( BlazeIngot ),        typeof( BlazeOre ),            typeof( BlazeGranite ) ),
            new CraftResourceInfo( 1152,    0,        "Ice",            CraftAttributeInfo.Ice,            CraftResource.Ice,                typeof( IceIngot ),            typeof( IceOre ),            typeof( IceGranite ) ),
            new CraftResourceInfo( 1272,    0,        "Toxic",        CraftAttributeInfo.Toxic,        CraftResource.Toxic,            typeof( ToxicIngot ),        typeof( ToxicOre ),            typeof( ToxicGranite ) ),
            new CraftResourceInfo( 1278,    0,        "Electrum",        CraftAttributeInfo.Electrum,    CraftResource.Electrum,            typeof( ElectrumIngot ),    typeof( ElectrumOre ),        typeof( ElectrumGranite ) ),
            new CraftResourceInfo( 1153,    0,        "Platinum",        CraftAttributeInfo.Platinum,    CraftResource.Platinum,            typeof( PlatinumIngot ),    typeof( PlatinumOre ),        typeof( PlatinumGranite ) ),
        };

        private static readonly CraftResourceInfo[] m_ScaleInfo = new CraftResourceInfo[]
        {
            new CraftResourceInfo(0x66D, 1053129, "Red Scales",    CraftAttributeInfo.RedScales, CraftResource.RedScales, typeof(RedScales)),
                new CraftResourceInfo( 54,    1053130,    "Yellow Scales",    CraftAttributeInfo.YellowScales,    CraftResource.YellowScales,        typeof( YellowScales ) ),
            new CraftResourceInfo(0x455, 1053131, "Black Scales",    CraftAttributeInfo.BlackScales, CraftResource.BlackScales, typeof(BlackScales)),
            new CraftResourceInfo(0x851, 1053132, "Green Scales",    CraftAttributeInfo.GreenScales, CraftResource.GreenScales, typeof(GreenScales)),
                new CraftResourceInfo( 1153,  1053133,    "White Scales",        CraftAttributeInfo.WhiteScales,        CraftResource.WhiteScales,        typeof( WhiteScales ) ),
                new CraftResourceInfo( 0x8B0, 1053134,    "Blue Scales",        CraftAttributeInfo.BlueScales,        CraftResource.BlueScales,        typeof( BlueScales ) ),
            new CraftResourceInfo( 0x96D,    0,        "Copper Scales",    CraftAttributeInfo.CopperScales,    CraftResource.CopperScales,        typeof( CopperScales ) ),
            new CraftResourceInfo( 0x8FD,    0,        "Silver Scales",    CraftAttributeInfo.SilverScales,    CraftResource.SilverScales,        typeof( SilverScales ) ),
            new CraftResourceInfo( 49,      0,        "Gold Scales",        CraftAttributeInfo.GoldScales,        CraftResource.GoldScales,        typeof( GoldScales ) ),
        };

        private static readonly CraftResourceInfo[] m_LeatherInfo = new CraftResourceInfo[]
        {
            new CraftResourceInfo(0x000, 1049353, "Normal", CraftAttributeInfo.Blank, CraftResource.RegularLeather,    typeof(Leather), typeof(Hides)),
                new CraftResourceInfo( 0x8ac, 1049354,        "Spined",        CraftAttributeInfo.Spined,            CraftResource.SpinedLeather,    typeof( SpinedLeather ),    typeof( SpinedHides ) ),
                new CraftResourceInfo( 0x845, 1049355,        "Horned",        CraftAttributeInfo.Horned,            CraftResource.HornedLeather,    typeof( HornedLeather ),    typeof( HornedHides ) ),
                new CraftResourceInfo( 0x1C1, 1049356,        "Barbed",        CraftAttributeInfo.Barbed,            CraftResource.BarbedLeather,    typeof( BarbedLeather ),    typeof( BarbedHides ) ),
            new CraftResourceInfo( 1150,    0,            "Polar",        CraftAttributeInfo.Polar,            CraftResource.PolarLeather,        typeof( PolarLeather ),        typeof( PolarHides ) ),
            new CraftResourceInfo( 1023,    0,            "Synthetic",    CraftAttributeInfo.Synthetic,        CraftResource.SyntheticLeather,    typeof( SyntheticLeather ),    typeof( SyntheticHides ) ),
            new CraftResourceInfo( 1260,    0,            "Blaze",        CraftAttributeInfo.BlazeL,            CraftResource.BlazeLeather,        typeof( BlazeLeather ),        typeof( BlazeHides ) ),
            new CraftResourceInfo( 32,        0,            "Daemonic",        CraftAttributeInfo.Daemonic,        CraftResource.DaemonicLeather,    typeof( DaemonicLeather ),    typeof( DaemonicHides ) ),
            new CraftResourceInfo( 0x966,    0,            "Shadow",        CraftAttributeInfo.Shadow,            CraftResource.ShadowLeather,    typeof( ShadowLeather ),    typeof( ShadowHides ) ),
            new CraftResourceInfo( 93,        0,            "Frost",        CraftAttributeInfo.Frost,            CraftResource.FrostLeather,        typeof( FrostLeather ),        typeof( FrostHides ) ),
            new CraftResourceInfo( 1159,    0,            "Ethereal",        CraftAttributeInfo.Ethereal,        CraftResource.EtherealLeather,    typeof( EtherealLeather ),    typeof( EtherealHides ) ),
            //daat99 OWLTR end - custom leather
        };

        private static readonly CraftResourceInfo[] m_AOSLeatherInfo = new CraftResourceInfo[]
        {
            new CraftResourceInfo(0x000, 1049353, "Normal", CraftAttributeInfo.Blank, CraftResource.RegularLeather,    typeof(Leather), typeof(Hides)),
            new CraftResourceInfo(0x8AC, 1049354, "Spined", CraftAttributeInfo.Spined, CraftResource.SpinedLeather,    typeof(SpinedLeather),    typeof(SpinedHides)),
            new CraftResourceInfo(0x845, 1049355, "Horned", CraftAttributeInfo.Horned, CraftResource.HornedLeather,    typeof(HornedLeather),    typeof(HornedHides)),
            new CraftResourceInfo(0x851, 1049356, "Barbed", CraftAttributeInfo.Barbed, CraftResource.BarbedLeather,    typeof(BarbedLeather),    typeof(BarbedHides)),
            new CraftResourceInfo( 1150,    0,            "Polar",        CraftAttributeInfo.Polar,            CraftResource.PolarLeather,        typeof( PolarLeather ),        typeof( PolarHides ) ),
            new CraftResourceInfo( 1023,    0,            "Synthetic",    CraftAttributeInfo.Synthetic,        CraftResource.SyntheticLeather,    typeof( SyntheticLeather ),    typeof( SyntheticHides ) ),
            new CraftResourceInfo( 1260,    0,            "Blaze",        CraftAttributeInfo.BlazeL,            CraftResource.BlazeLeather,        typeof( BlazeLeather ),        typeof( BlazeHides ) ),
            new CraftResourceInfo( 32,        0,            "Daemonic",        CraftAttributeInfo.Daemonic,        CraftResource.DaemonicLeather,    typeof( DaemonicLeather ),    typeof( DaemonicHides ) ),
            new CraftResourceInfo( 0x966,    0,            "Shadow",        CraftAttributeInfo.Shadow,            CraftResource.ShadowLeather,    typeof( ShadowLeather ),    typeof( ShadowHides ) ),
            new CraftResourceInfo( 93,        0,            "Frost",        CraftAttributeInfo.Frost,            CraftResource.FrostLeather,        typeof( FrostLeather ),        typeof( FrostHides ) ),
            new CraftResourceInfo( 1159,    0,            "Ethereal",        CraftAttributeInfo.Ethereal,        CraftResource.EtherealLeather,    typeof( EtherealLeather ),    typeof( EtherealHides ) ),
        };

        private static readonly CraftResourceInfo[] m_WoodInfo = new CraftResourceInfo[]
        {
                //daat99 OWLTR start - custom wood
                new CraftResourceInfo( 0, 0,    "Normal",        CraftAttributeInfo.Blank,        CraftResource.RegularWood,    typeof(Board),                typeof( Log ) ),
                new CraftResourceInfo( 1281, 0, "Oak",            CraftAttributeInfo.OakWood,        CraftResource.OakWood,        typeof(OakBoard),            typeof( OakLog ) ),
                new CraftResourceInfo( 488,  0, "Ash",            CraftAttributeInfo.AshWood,        CraftResource.AshWood,        typeof(AshBoard),            typeof( AshLog ) ),
                new CraftResourceInfo( 2313, 0, "Yew",            CraftAttributeInfo.YewWood,        CraftResource.YewWood,        typeof(YewBoard),            typeof( YewLog ) ),
                new CraftResourceInfo( 1262, 0,    "Heartwood",    CraftAttributeInfo.Heartwood,    CraftResource.Heartwood,    typeof(HeartwoodBoard),        typeof( HeartwoodLog ) ),
                new CraftResourceInfo( 1194, 0,    "Bloodwood",    CraftAttributeInfo.Bloodwood,    CraftResource.Bloodwood,    typeof(BloodwoodBoard),        typeof( BloodwoodLog ) ),
                new CraftResourceInfo( 1266, 0,    "Frostwood",    CraftAttributeInfo.Frostwood,    CraftResource.Frostwood,    typeof(FrostwoodBoard),        typeof( FrostwoodLog ) ),
                new CraftResourceInfo( 1457, 0, "Ebony",        CraftAttributeInfo.Ebony,        CraftResource.Ebony,        typeof(EbonyBoard),            typeof( EbonyLog ) ),
                new CraftResourceInfo( 1719, 0,    "Bamboo",        CraftAttributeInfo.Bamboo,        CraftResource.Bamboo,        typeof(BambooBoard),        typeof( BambooLog ) ),
                new CraftResourceInfo( 114,  0, "PurpleHeart",    CraftAttributeInfo.PurpleHeart,    CraftResource.PurpleHeart,    typeof(PurpleHeartBoard),    typeof( PurpleHeartLog ) ),
                new CraftResourceInfo( 37,   0,    "Redwood",        CraftAttributeInfo.Redwood,        CraftResource.Redwood,        typeof(RedwoodBoard),        typeof( RedwoodLog ) ),
                new CraftResourceInfo( 1153, 0, "Petrified",    CraftAttributeInfo.Petrified,    CraftResource.Petrified,    typeof(PetrifiedBoard),        typeof( PetrifiedLog ) ),
                //daat99 OWLTR end - custom wood
        };

        /// <summary>
        /// Returns true if '<paramref name="resource"/>' is None, Iron, RegularLeather or RegularWood. False if otherwise.
        /// </summary>
        public static bool IsStandard(CraftResource resource)
        {
            return (resource == CraftResource.None || resource == CraftResource.Iron || resource == CraftResource.RegularLeather || resource == CraftResource.RegularWood);
        }

        private static Hashtable m_TypeTable;

        /// <summary>
        /// Registers that '<paramref name="resourceType"/>' uses '<paramref name="resource"/>' so that it can later be queried by <see cref="CraftResources.GetFromType"/>
        /// </summary>
        public static void RegisterType(Type resourceType, CraftResource resource)
        {
            if (m_TypeTable == null)
                m_TypeTable = new Hashtable();

            m_TypeTable[resourceType] = resource;
        }

        /// <summary>
        /// Returns the <see cref="CraftResource"/> value for which '<paramref name="resourceType"/>' uses -or- CraftResource.None if an unregistered type was specified.
        /// </summary>
        public static CraftResource GetFromType(Type resourceType)
        {
            if (m_TypeTable == null)
                return CraftResource.None;

            object obj = m_TypeTable[resourceType];

            if (!(obj is CraftResource))
                return CraftResource.None;

            return (CraftResource)obj;
        }

        /// <summary>
        /// Returns a <see cref="CraftResourceInfo"/> instance describing '<paramref name="resource"/>' -or- null if an invalid resource was specified.
        /// </summary>
        public static CraftResourceInfo GetInfo(CraftResource resource)
        {
            CraftResourceInfo[] list = null;

            switch (GetType(resource))
            {
                case CraftResourceType.Metal:
                    list = m_MetalInfo;
                    break;
                case CraftResourceType.Leather:
                    list = Core.AOS ? m_AOSLeatherInfo : m_LeatherInfo;
                    break;
                case CraftResourceType.Scales:
                    list = m_ScaleInfo;
                    break;
                case CraftResourceType.Wood:
                    list = m_WoodInfo;
                    break;
            }

            if (list != null)
            {
                int index = GetIndex(resource);

                if (index >= 0 && index < list.Length)
                    return list[index];
            }

            return null;
        }

        /// <summary>
        /// Returns a <see cref="CraftResourceType"/> value indiciating the type of '<paramref name="resource"/>'.
        /// </summary>
        public static CraftResourceType GetType(CraftResource resource)
        {
            if (resource >= CraftResource.Iron && resource <= CraftResource.Valorite)
                return CraftResourceType.Metal;

            if (resource >= CraftResource.RegularLeather && resource <= CraftResource.BarbedLeather)
                return CraftResourceType.Leather;

            if (resource >= CraftResource.RedScales && resource <= CraftResource.BlueScales)
                return CraftResourceType.Scales;

            if (resource >= CraftResource.RegularWood && resource <= CraftResource.Frostwood)
                return CraftResourceType.Wood;

            return CraftResourceType.None;
        }

        /// <summary>
        /// Returns the first <see cref="CraftResource"/> in the series of resources for which '<paramref name="resource"/>' belongs.
        /// </summary>
        public static CraftResource GetStart(CraftResource resource)
        {
            switch (GetType(resource))
            {
                case CraftResourceType.Metal:
                    return CraftResource.Iron;
                case CraftResourceType.Leather:
                    return CraftResource.RegularLeather;
                case CraftResourceType.Scales:
                    return CraftResource.RedScales;
                case CraftResourceType.Wood:
                    return CraftResource.RegularWood;
            }

            return CraftResource.None;
        }

        /// <summary>
        /// Returns the index of '<paramref name="resource"/>' in the seriest of resources for which it belongs.
        /// </summary>
        public static int GetIndex(CraftResource resource)
        {
            CraftResource start = GetStart(resource);

            if (start == CraftResource.None)
                return 0;

            return (int)(resource - start);
        }

        /// <summary>
        /// Returns the <see cref="CraftResourceInfo.Number"/> property of '<paramref name="resource"/>' -or- 0 if an invalid resource was specified.
        /// </summary>
        public static int GetLocalizationNumber(CraftResource resource)
        {
            CraftResourceInfo info = GetInfo(resource);

            return (info == null ? 0 : info.Number);
        }

        /// <summary>
        /// Returns the <see cref="CraftResourceInfo.Hue"/> property of '<paramref name="resource"/>' -or- 0 if an invalid resource was specified.
        /// </summary>
        public static int GetHue(CraftResource resource)
        {
            CraftResourceInfo info = GetInfo(resource);

            return (info == null ? 0 : info.Hue);
        }

        /// <summary>
        /// Returns the <see cref="CraftResourceInfo.Name"/> property of '<paramref name="resource"/>' -or- an empty string if the resource specified was invalid.
        /// </summary>
        public static string GetName(CraftResource resource)
        {
            CraftResourceInfo info = GetInfo(resource);

            return (info == null ? String.Empty : info.Name);
        }

        /// <summary>
        /// Returns the <see cref="CraftResource"/> value which represents '<paramref name="info"/>' -or- CraftResource.None if unable to convert.
        /// </summary>
        public static CraftResource GetFromOreInfo(OreInfo info)
        {
            //daat99 OWLTR start - custom leather
            if ( info.Name.IndexOf( "Leather" ) >= 0 && info.Level >= 0 && info.Level <=10 )
                return (CraftResource)(info.Level+101);

            //daat99 OWLTR start - custom ores
            if ( info.Level >= 0 && info.Level <= 13 )
                return (CraftResource)(info.Level+1);
            //daat99 OWLTR end - custom ores

            if ( info.Level >= 301 && info.Level <= 312 )
                return (CraftResource)info.Level;
            //daat99 OWLTR end - custom wood

            return CraftResource.None;
        }

        /// <summary>
        /// Returns the <see cref="CraftResource"/> value which represents '<paramref name="info"/>', using '<paramref name="material"/>' to help resolve leather OreInfo instances.
        /// </summary>
        public static CraftResource GetFromOreInfo(OreInfo info, ArmorMaterialType material)
        {
            if (material == ArmorMaterialType.Studded || material == ArmorMaterialType.Leather || material == ArmorMaterialType.Spined ||
                material == ArmorMaterialType.Horned || material == ArmorMaterialType.Barbed || material == ArmorMaterialType.Polar ||
                material == ArmorMaterialType.Synthetic || material == ArmorMaterialType.BlazeL || material == ArmorMaterialType.Daemonic ||
                material == ArmorMaterialType.Shadow || material == ArmorMaterialType.Frost || material == ArmorMaterialType.Ethereal )
            {
                if ( info.Level >= 0 && info.Level <=10 )
                    return (CraftResource)(info.Level+101);

                return CraftResource.None;
            }

            return GetFromOreInfo(info);
        }
    }

    // NOTE: This class is only for compatability with very old RunUO versions.
    // No changes to it should be required for custom resources.
    public class OreInfo
    {
        public static readonly OreInfo Iron = new OreInfo(0, 0x000, "Iron");
        public static readonly OreInfo DullCopper = new OreInfo(1, 0x973, "Dull Copper");
        public static readonly OreInfo ShadowIron = new OreInfo(2, 0x966, "Shadow Iron");
        public static readonly OreInfo Copper = new OreInfo(3, 0x96D, "Copper");
        public static readonly OreInfo Bronze = new OreInfo(4, 0x972, "Bronze");
        public static readonly OreInfo Gold = new OreInfo(5, 0x8A5, "Gold");
        public static readonly OreInfo Agapite = new OreInfo(6, 0x979, "Agapite");
        public static readonly OreInfo Verite = new OreInfo(7, 0x89F, "Verite");
        public static readonly OreInfo Valorite = new OreInfo(8, 0x8AB, "Valorite");
        public static readonly OreInfo Blaze        = new OreInfo(  9, 1161, "Blaze" );
        public static readonly OreInfo Ice            = new OreInfo( 10, 1152, "Ice" );
        public static readonly OreInfo Toxic        = new OreInfo( 11, 1272, "Toxic" );
        public static readonly OreInfo Electrum        = new OreInfo( 12, 1278, "Electrum" );
        public static readonly OreInfo Platinum        = new OreInfo( 13, 1153, "Platinum" );

        private readonly int m_Level;
        private readonly int m_Hue;
        private readonly string m_Name;

        public OreInfo(int level, int hue, string name)
        {
            this.m_Level = level;
            this.m_Hue = hue;
            this.m_Name = name;
        }

        public int Level
        {
            get
            {
                return this.m_Level;
            }
        }

        public int Hue
        {
            get
            {
                return this.m_Hue;
            }
        }

        public string Name
        {
            get
            {
                return this.m_Name;
            }
        }
    }
}
 
So here's your problem. CraftResource determines the class of a resource by comparing the integer ID to known resource types. In the case of metal, it says, "Is this between Iron and Valorite?" If so it's metal. If not it goes on to check for other types. If it can't figure out what type of resource it is, it returns null.

For now edit the GetType method. Replace the end resource types with your last custom resource type. That should do it.
 
Back