/// <summary>
        /// Function used to parse a phrase and attempt to locate an object matching
        /// the given parameters.
        /// </summary>
        public static TargetResult FindTargetEntity(this Biota biote, string phrase, int allowedLocations)
        {
            var result = new TargetResult
            {
                FirstParameter  = phrase.FirstWord(),
                SecondParameter = phrase.SecondWord(),
                Quantity        = 1
            };

            if (string.IsNullOrEmpty(result.FirstParameter) || allowedLocations == 0)
            {
                return(result);
            }

            result = ParseQuantity(result);
            result = ParseFirstParameter(result, biote, allowedLocations);

            //// no optional parameters were supplied, return the results
            if (string.IsNullOrEmpty(result.SecondParameter))
            {
                return(result);
            }

            result = ParseSecondParameter(result, biote, allowedLocations);

            return(result);
        }
 /// <summary>
 ///  Helper function that quickly populates the TargetResult object with data
 /// </summary>
 internal static TargetResult Populate(this TargetResult value, IGameEntity entity, IGameEntity biote,
                                       Globals.EntityLocationTypes type)
 {
     value.FoundEntity             = entity;
     value.FoundEntityLocation     = biote;
     value.FoundEntityLocationType = type;
     return(value);
 }
        internal static TargetResult ParseFirstParameter(TargetResult result, IGameEntity entity, int allowedLocations)
        {
            IGameEntity target;

            //// Look in inventory first
            if ((allowedLocations & Globals.EntityLocationTypes.Inventory.GetValue()) != 0)
            {
                target = FindEntityInInventory(entity, result.FirstParameter);
                if (target != null)
                {
                    return(result.Populate(target, entity, Globals.EntityLocationTypes.Inventory));
                }
            }

            //// Look in equipment second
            if ((allowedLocations & Globals.EntityLocationTypes.Equipment.GetValue()) != 0)
            {
                target = FindEntityInEquipment(entity, result.FirstParameter);
                if (target != null)
                {
                    return(result.Populate(target, entity, Globals.EntityLocationTypes.Equipment));
                }
            }

            //// Look on ground third
            if ((allowedLocations & Globals.EntityLocationTypes.Space.GetValue()) != 0)
            {
                target = FindEntity(entity.Location, result.FirstParameter);
                if (target != null)
                {
                    return(result.Populate(target, entity.Location, Globals.EntityLocationTypes.Space));
                }
            }

            //// look in abilities
            if ((allowedLocations & Globals.EntityLocationTypes.Ability.GetValue()) != 0)
            {
                return(result);
            }

            //// look in Effects
            if ((allowedLocations & Globals.EntityLocationTypes.Effects.GetValue()) != 0)
            {
                return(result);
            }

            //// Look in Recipes
            if ((allowedLocations & Globals.EntityLocationTypes.Recipes.GetValue()) != 0)
            {
                target = FindEntityInRecipes(entity, result.FirstParameter);
                if (target != null)
                {
                    return(result.Populate(target, null, Globals.EntityLocationTypes.Recipes));
                }
            }
            return(result);
        }
 /// <summary>
 /// Parse the quantity if one was provided
 /// </summary>
 internal static TargetResult ParseQuantity(TargetResult result)
 {
     if (!result.FirstParameter.StartsWith("#"))
     {
         return(result);
     }
     result.Quantity = result.FirstParameter.ParseQuantity();
     if (result.Quantity <= 0)
     {
         result.Quantity = 1;
     }
     result.FirstParameter = result.FirstParameter.Remove(0, result.FirstParameter.IndexOf('#') + 1);
     return(result);
 }
        internal static TargetResult ParseSecondParameter(TargetResult result, IGameEntity entity, int allowedLocations)
        {
            IGameEntity secondTarget;
            IGameEntity target;

            //// second parameter could be a container, check inventory
            if ((allowedLocations & Globals.EntityLocationTypes.Inventory.GetValue()) != 0)
            {
                secondTarget = FindEntityInInventory(entity, result.SecondParameter);
                if (secondTarget != null)
                {
                    target = FindEntity(secondTarget, result.SecondParameter);
                    if (target != null)
                    {
                        return(result.Populate(target, secondTarget, Globals.EntityLocationTypes.Container));
                    }
                }
            }

            //// second parameter in equipment
            if ((allowedLocations & Globals.EntityLocationTypes.Equipment.GetValue()) != 0)
            {
                secondTarget = FindEntityInEquipment(entity, result.SecondParameter);
                if (secondTarget != null)
                {
                    target = FindEntity(secondTarget, result.SecondParameter);
                    if (target != null)
                    {
                        return(result.Populate(target, secondTarget, Globals.EntityLocationTypes.Container));
                    }
                }
            }

            //// second parameter on ground
            if ((allowedLocations & Globals.EntityLocationTypes.Space.GetValue()) == 0)
            {
                return(result);
            }
            secondTarget = FindEntity(entity.Location, result.SecondParameter);

            if (secondTarget == null)
            {
                return(result);
            }
            if (secondTarget is Mobile)
            {
                //// NPC Inventory
                if ((allowedLocations & Globals.EntityLocationTypes.MobileInventory.GetValue()) != 0)
                {
                    target = FindEntityInInventory(secondTarget.CastAs <IBiota>(), result.FirstParameter);
                    if (target != null)
                    {
                        return(result.Populate(target, secondTarget, Globals.EntityLocationTypes.MobileInventory));
                    }
                }

                //// NPC Equipment
                if ((allowedLocations & Globals.EntityLocationTypes.MobileEquipment.GetValue()) != 0)
                {
                    target = FindEntityInEquipment(secondTarget.CastAs <IBiota>(), result.FirstParameter);
                    if (target != null)
                    {
                        return(result.Populate(target, secondTarget, Globals.EntityLocationTypes.MobileEquipment));
                    }
                }

                //// NPC Shop
                if ((allowedLocations & Globals.EntityLocationTypes.Shop.GetValue()) == 0)
                {
                    return(result);
                }
                target = FindEntityInShop(secondTarget, result.FirstParameter);
                if (target != null)
                {
                    return(result.Populate(target, secondTarget, Globals.EntityLocationTypes.Shop));
                }
            }
            else
            {
                target = FindEntity(secondTarget, result.SecondParameter);
                if (target != null)
                {
                    return(result.Populate(target, secondTarget, Globals.EntityLocationTypes.Container));
                }
            }

            return(result);
        }