Exemplo n.º 1
0
        internal void CheckForFirstHorse(object sender, NpcListChangedEventArgs e)
        {
            // FirstHorseReceived status already known
            if (Creator.FirstHorseReceived)
            {
                Helper.Events.World.NpcListChanged -= CheckForFirstHorse;
            }

            // Check for the arrival of the vanilla horse
            else if (e != null && e.Added != null)
            {
                foreach (NPC npc in e.Added)
                {
                    if (npc is Horse horse)
                    {
                        if (ModApi.IsNotATractorOrCart(horse))
                        {
                            // The first horse is given to the host player
                            AddCreature(horse, 0, Game1.MasterPlayer);
                            Creator.FirstHorseReceived = true;
                            this.Helper.Events.World.NpcListChanged -= this.CheckForFirstHorse;
                            return;
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        /****************************
        ** Additional Functionality
        *****************************/

        /// <summary>Calls a horse that the player owns to the player's location</summary>
        /// <returns>Returns true if a horse was successfully called.</returns>
        internal static bool CallHorse(long id = 0)
        {
            // Make sure that the player is calling the horse while outside
            if (!Game1.player.currentLocation.IsOutdoors)
            {
                ModEntry.SMonitor.Log("You cannot call for a horse while indoors.", LogLevel.Warn);
                Game1.chatBox.addInfoMessage("You hear your Grandfather's voice echo in your head.. \"Now is not the time to use that.\"");
                return(false);
            }

            // Teleport the horse with the given ID or the last horse ridden
            List <Horse> taxis = ModApi.GetHorses().ToList();

            taxis.Reverse();
            foreach (Horse taxi in taxis)
            {
                if (ModApi.IsWildHorse(taxi))
                {
                    continue;
                }
                else if (id != 0 && GetShortID(taxi) == id)
                {
                    Game1.warpCharacter(taxi, Game1.player.currentLocation, Game1.player.getTileLocation());
                    return(true);
                }
                else if (id == 0)
                {
                    Game1.warpCharacter(taxi, Game1.player.currentLocation, Game1.player.getTileLocation());
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 3
0
        private static Character GetCreature(long longID)
        {
            // Check that LongID belongs to a creature in the database, or is otherwise a Stray or WildHorse.
            if (IDToCategory.ContainsKey(longID))
            {
                switch (IDToCategory[longID])
                {
                case CreatureCategory.Pet:
                    foreach (Pet pet in ModApi.GetPets())
                    {
                        if (GetLongID(pet) == longID)
                        {
                            return(pet);
                        }
                    }
                    return(null);

                case CreatureCategory.Horse:
                    foreach (Horse horse in ModApi.GetHorses())
                    {
                        if (GetLongID(horse) == longID)
                        {
                            return(horse);
                        }
                    }
                    return(null);

                case CreatureCategory.Animal:
                    foreach (FarmAnimal animal in ModApi.GetAnimals())
                    {
                        if (GetLongID(animal) == longID)
                        {
                            return(animal);
                        }
                    }
                    return(null);

                default:
                    return(null);
                }
            }
            else
            {
                if (ModApi.IsStray(longID))
                {
                    if (Creator.StrayInfo != null)
                    {
                        return(Creator.StrayInfo.PetInstance);
                    }
                }
                else if (ModApi.IsWildHorse(longID))
                {
                    if (Creator.HorseInfo != null)
                    {
                        return(Creator.HorseInfo.HorseInstance);
                    }
                }
                return(null);
            }
        }
Exemplo n.º 4
0
        /// <summary>Removes the Pet, Horse, or FarmAnimal with the given LongID from the A&S database</summary>
        internal void RemoveCreature(long longID)
        {
            if (!ModApi.IsInDatabase(longID))
            {
                return;
            }

            // Ensure creature is not on map
            Character creature = GetCreature(longID);

            if (creature != null && (creature is Pet || creature is Horse))
            {
                Game1.removeThisCharacterFromAllLocations(creature as NPC);
            }
            // Remove FarmAnimal-specific ID markers from lists
            else if (AnimalLongToShortIDs.ContainsKey(longID))
            {
                int shortID = AnimalLongToShortIDs[longID];
                AnimalLongToShortIDs.Remove(longID);
                AnimalShortToLongIDs.Remove(shortID);
            }

            // Scrub internal IDs and skin mapping from system
            IDToCategory.Remove(longID);
            SkinMap.Remove(longID);
        }
Exemplo n.º 5
0
        /// <summary>Returns an unused Short ID for a new creature to use.</summary>
        private int GetUnusedShortID()
        {
            int newShortID = 1;

            // Gather all current ShortIDs
            List <int> usedIDs = new List <int>();

            foreach (Horse horse in ModApi.GetHorses())
            {
                usedIDs.Add(GetShortID(horse));
            }
            foreach (Pet pet in ModApi.GetPets())
            {
                usedIDs.Add(GetShortID(pet));
            }
            foreach (FarmAnimal animal in ModApi.GetAnimals())
            {
                usedIDs.Add(GetShortID(animal));
            }

            // Find an unused ShortID and return it
            while (usedIDs.Contains(newShortID))
            {
                newShortID++;
            }
            return(newShortID);
        }
Exemplo n.º 6
0
 public static void ClearUnownedPets()
 {
     foreach (NPC npc in Utility.getAllCharacters())
     {
         if (npc is Horse horse && ModApi.IsWildHorse(horse))
         {
             Game1.removeThisCharacterFromAllLocations(horse);
         }
Exemplo n.º 7
0
 /// <summary>Returns an enumerable list of all owned Pet instances. This excludes strays.</summary>
 public static IEnumerable <Pet> GetPets()
 {
     foreach (NPC npc in Utility.getAllCharacters())
     {
         if (npc is Pet pet && !ModApi.IsStray(pet))
         {
             yield return(pet);
         }
     }
 }
Exemplo n.º 8
0
 /// <summary>Update BeingRidden, such that horses can be manually re-added on dismount, preventing the disappearence of dismounted multihorses.</summary>
 internal static void HorseMountedCheck(object sender, NpcListChangedEventArgs e)
 {
     foreach (NPC npc in e.Removed)
     {
         if (npc is Horse horse && horse.rider != null && !ModApi.IsWildHorse(horse))
         {
             BeingRidden.Add(horse);
         }
     }
 }
Exemplo n.º 9
0
        internal static int GetRandomSkin(string type)
        {
            type = Sanitize(type);
            if (!ModApi.HasSkins(type))
            {
                return(0);
            }
            int randomLookup = Randomizer.Next(0, Assets[type].Keys.Count);

            return(Assets[type].ElementAt(randomLookup).Key);
        }
Exemplo n.º 10
0
        /************************
        ** Skin Handling
        *************************/

        /// <param name="creature">The creature (Pet, Horse, or FarmAnimal) to set the skin for</param>
        /// <param name="skinID">The file ID of the skin to set.</param>
        internal static int SetSkin(Character creature, int skinID)
        {
            if (!ModApi.IsInDatabase(creature) || !ModApi.HasSkins(ModApi.GetInternalType(creature)))
            {
                return(0);
            }

            SkinMap[GetLongID(creature)] = skinID;
            UpdateSkin(creature);
            return(skinID);
        }
Exemplo n.º 11
0
        internal static AnimalSkin GetSkin(Character creature)
        {
            if (!ModApi.HasSkins(ModApi.GetInternalType(creature)) || !ModApi.IsInDatabase(creature))
            {
                return(null);
            }


            int    skinID;
            string type = ModApi.GetInternalType(creature);

            // Take care of Strays and WildHorses
            if (Creator.StrayInfo != null && ModApi.IsStray(creature))
            {
                skinID = Creator.StrayInfo.SkinID;
            }
            else if (Creator.HorseInfo != null && ModApi.IsWildHorse(creature))
            {
                skinID = Creator.HorseInfo.SkinID;
            }
            // Take care of FarmAnimal subtypes
            else if (creature is FarmAnimal animal)
            {
                skinID = SkinMap[GetLongID(creature)];

                if (ModApi.HasBabySprite(type) && animal.age.Value < animal.ageWhenMature.Value)
                {
                    type = "baby" + type;
                }
                else if (ModApi.HasShearedSprite(type) && animal.showDifferentTextureWhenReadyForHarvest.Value && animal.currentProduce.Value <= 0)
                {
                    type = "sheared" + type;
                }
            }
            // Take care of owned Pets and Horses
            else
            {
                skinID = SkinMap[GetLongID(creature)];
            }


            if (!Assets[ModApi.GetInternalType(creature)].ContainsKey(skinID))
            {
                ModEntry.SMonitor.Log($"{creature.Name}'s skin ID no longer exists in `/assets/skins`. Skin will be randomized.", LogLevel.Alert);
                skinID = RandomizeSkin(creature);
            }
            else if (skinID == 0)
            {
                return(null);
            }

            return(GetSkin(type, skinID));
        }
Exemplo n.º 12
0
        internal static int GetRandomSkin(string type)
        {
            type = Sanitize(type);
            if (!ModApi.HasSkins(type))
            {
                return(0);
            }
            // ** TODO: Find out why erroring with stray spawn, issue in GetSkin likely.
            // Issue related to lack of cat skins? Fix this
            // Android: A Button works, but not right click
            int randomLookup = Randomizer.Next(0, Assets[type].Keys.Count);

            return(Assets[type].ElementAt(randomLookup).Key);
        }
Exemplo n.º 13
0
        /****************************
        ** Additional Functionality
        *****************************/

        /// <summary>Calls a horse that the player owns to the player's location</summary>
        /// <returns>Returns true if a horse was successfully called.</returns>
        internal static bool CallHorse(int id = 0)
        {
            // Make sure that the player is calling the horse while outside
            if (!Game1.player.currentLocation.IsOutdoors)
            {
                Game1.chatBox.addInfoMessage("You hear your Grandfather's voice echo in your head.. \"Now is not the time to use that.\"");
                return(false);
            }

            // Teleport the first horse you find that the player actually owns
            List <Horse> taxis = ModApi.GetHorses().ToList();

            taxis.Reverse();
            foreach (Horse taxi in taxis)
            {
                long longID = GetLongID(taxi);

                // If the player called for a specific horse
                if (id != 0 && GetShortID(taxi) == id)
                {
                    // Ensure that the player owns this horse
                    if (HorseOwnershipMap[longID] != Game1.player)
                    {
                        SMonitor.Log($"Horse {id} ({taxi.Name}) does not belong to this player. (Belongs to ({HorseOwnershipMap[longID].Name}))", LogLevel.Error);
                        return(false);
                    }

                    Game1.warpCharacter(taxi, Game1.player.currentLocation, Game1.player.getTileLocation());
                    return(true);
                }
                // Otherwise
                else if (id == 0)
                {
                    // Ensure that the player owns this horse
                    if (HorseOwnershipMap[longID] != Game1.player)
                    {
                        continue;
                    }
                    else
                    {
                        Game1.warpCharacter(taxi, Game1.player.currentLocation, Game1.player.getTileLocation());
                        return(true);
                    }
                }
            }

            SMonitor.Log("This player does not own any horses to call.", LogLevel.Debug);
            return(false);
        }
Exemplo n.º 14
0
        /// <summary>Refreshes the texture of the creature's sprite if the texture it has is different from the one in the skin mapping</summary>
        internal static void UpdateSkin(Character creature)
        {
            if (!ModApi.IsInDatabase(creature) && !ModApi.IsStray(creature) && !ModApi.IsWildHorse(creature))
            {
                return;
            }

            AnimalSkin skin = GetSkin(creature);

            if (skin != null && creature.Sprite.textureName.Value != skin.AssetKey)
            {
                int[] spriteInfo = ModApi.GetSpriteInfo(creature);
                creature.Sprite = new AnimatedSprite(skin.AssetKey, spriteInfo[0], spriteInfo[1], spriteInfo[2]);
            }
        }
Exemplo n.º 15
0
 /// <summary>Returns an enumerable list of all existing Horse instances. This includes WildHorses and excludes tractors.</summary>
 public static IEnumerable <Horse> GetAllHorses()
 {
     foreach (NPC npc in Utility.getAllCharacters())
     {
         if (npc is Horse horse && ModApi.IsNotATractorOrCart(horse))
         {
             yield return(horse);
         }
     }
     // Horses being ridden don't technically exist, and must be added separately
     foreach (Horse horse in ModEntry.BeingRidden)
     {
         yield return(horse);
     }
 }
Exemplo n.º 16
0
        /// <summary>Removes the Pet, Horse, or FarmAnimal with the given LongID from the A&S database</summary>
        internal void RemoveCreature(long longID)
        {
            if (!ModApi.IsInDatabase(longID))
            {
                return;
            }

            // Ensure creature is not on map
            Character creature = GetCreature(longID);

            if (creature != null && (creature is Pet || creature is Horse))
            {
                Game1.removeThisCharacterFromAllLocations(creature as NPC);
            }

            // Scrub internal IDs and skin mapping from system
            IDToCategory.Remove(longID);
            SkinMap.Remove(longID);
        }
Exemplo n.º 17
0
        internal static int GetShortID(Character creature)
        {
            if (!ModApi.IsInDatabase(creature))
            {
                return(0);
            }

            if (creature is Pet pet)
            {
                return(pet.Manners);
            }
            else if (creature is Horse horse)
            {
                return(horse.Manners);
            }
            else if (creature is FarmAnimal animal && AnimalLongToShortIDs.ContainsKey(GetLongID(animal)))
            {
                return(AnimalLongToShortIDs[GetLongID(animal)]);
            }
            return(0);
        }
Exemplo n.º 18
0
        /// <summary>Determines whether an animal has been removed or added in the game, and either removes or adds it to the A&S database.</summary>
        internal void AnimalListChangeCheck()
        {
            if (Game1.getFarm() != null && AnimalCount != Game1.getFarm().getAllFarmAnimals().Count)
            {
                List <long>       existingAnimalIDs = new List <long>();
                List <FarmAnimal> newAnimals        = new List <FarmAnimal>();

                // Check for new animals and populate lists containing existing and new animals
                foreach (FarmAnimal animal in ModApi.GetAnimals().ToList())
                {
                    if (!ModApi.IsInDatabase(animal))
                    {
                        newAnimals.Add(animal);
                    }
                    else
                    {
                        existingAnimalIDs.Add(animal.myID.Value);
                    }
                }

                // Remove animals that no longer exist
                List <long> animalIDs = new List <long>(SkinMap.Keys);
                foreach (long id in animalIDs)
                {
                    if (IDToCategory[id] == CreatureCategory.Animal && !existingAnimalIDs.Contains(id))
                    {
                        RemoveCreature(id);
                    }
                }

                // Add new animals
                foreach (FarmAnimal animal in newAnimals)
                {
                    AddCreature(animal);
                }

                // Update last known animal count
                AnimalCount = Game1.getFarm().getAllFarmAnimals().Count;
            }
        }
Exemplo n.º 19
0
        /// <summary>Adds the given Pet, Horse, or FarmAnimal into the A&S database</summary>
        internal void AddCreature(Character creature, int skinID = 0, Farmer owner = null)
        {
            string type = ModApi.GetInternalType(creature);

            if (ModApi.IsInDatabase(creature) || !ModApi.IsRegisteredType(type))
            {
                return;
            }

            // Set internal IDs
            SetShortID(creature, GetUnusedShortID());
            IDToCategory[GetLongID(creature)] = ModApi.GetCreatureCategory(type);

            // Set ownership
            if (creature is Horse)
            {
                if (owner != null)
                {
                    HorseOwnershipMap.Add(GetLongID(creature), owner);
                    // DEBUG
                    Monitor.Log($"Horse ID: {GetShortID(creature)}\nOwner: {owner.Name}", LogLevel.Debug);
                }
                else
                {
                    Monitor.Log($"No adopter able to be detected. Horse {GetShortID(creature)} will be owned by the host player.", LogLevel.Debug);
                    HorseOwnershipMap.Add(GetLongID(creature), Game1.MasterPlayer);
                }
            }

            // Give a skin
            if (skinID != 0)
            {
                SetSkin(creature, skinID);
            }
            else
            {
                RandomizeSkin(creature);
            }
        }
Exemplo n.º 20
0
        /****************************
        ** Additional Functionality
        *****************************/

        /// <summary>Calls a horse that the player owns to the player's location</summary>
        /// <returns>Returns true if a horse was successfully called.</returns>
        internal static bool CallHorse(long id = 0)
        {
            // Make sure that the player is calling the horse while outside
            if (!Game1.player.currentLocation.IsOutdoors)
            {
                ModEntry.SMonitor.Log("You cannot call for a horse while indoors.", LogLevel.Alert);
                Game1.chatBox.addInfoMessage("You hear your Grandfather's voice echo in your head.. \"Now is not the time to use that.\"");
                return(false);
            }

            // Teleport the first horse you find that the player actually owns
            foreach (Horse taxi in ModApi.GetHorses())
            {
                if (ModApi.IsInDatabase(taxi) && (id == 0 || id == GetLongID(taxi)))
                {
                    Game1.warpCharacter(taxi, Game1.player.currentLocation, Game1.player.getTileLocation());
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 21
0
        /// <summary>Adds the given Pet, Horse, or FarmAnimal into the A&S database</summary>
        internal void AddCreature(Character creature, int skinID = 0)
        {
            string type = ModApi.GetInternalType(creature);

            if (ModApi.IsInDatabase(creature) || !ModApi.IsRegisteredType(type))
            {
                return;
            }

            // Set internal IDs
            SetShortID(creature, GetUnusedShortID());
            IDToCategory[GetLongID(creature)] = ModApi.GetCreatureCategory(type);

            // Give a skin
            if (skinID != 0)
            {
                SetSkin(creature, skinID);
            }
            else
            {
                RandomizeSkin(creature);
            }
        }
Exemplo n.º 22
0
        /// <summary>Calls all horses owned by the player to return to the player's stable</summary>
        internal static void CorralHorses()
        {
            // Find the farm's stable
            Stable horsehut = null;

            foreach (Building building in Game1.getFarm().buildings)
            {
                if (building is Stable)
                {
                    horsehut = building as Stable;
                }
            }

            if (horsehut != null)
            {
                // WARP THEM. WARP THEM ALL.
                int     stableX    = int.Parse(horsehut.tileX.ToString()) + 1;
                int     stableY    = int.Parse(horsehut.tileY.ToString()) + 1;
                Vector2 stableWarp = new Vector2(stableX, stableY);

                foreach (Horse horse in ModApi.GetHorses())
                {
                    if (!ModApi.IsWildHorse(horse))
                    {
                        Game1.warpCharacter(horse, "farm", stableWarp);
                    }
                }

                ModEntry.SMonitor.Log("All horses have been warped to the stable.", LogLevel.Info);
                return;
            }

            // Player does not own a stable
            ModEntry.SMonitor.Log("NOTICE: You don't have a stable to warp to!", LogLevel.Error);
            Game1.chatBox.addInfoMessage("Your Grandfather's voice echoes in your head.. \"You aren't yet ready for this gift.\"");
        }
Exemplo n.º 23
0
        /// <summary>Calls all horses owned by the player to return to the player's stable</summary>
        internal static void CorralHorses()
        {
            // Gather the taxis
            List <Horse> horses = new List <Horse>();

            foreach (Horse horse in ModApi.GetHorses())
            {
                horses.Add(horse);
            }

            // Ensure you own at least one taxi
            if (horses.Count == 0)
            {
                ModEntry.SMonitor.Log("NOTICE: You do not own any horses", LogLevel.Error);
                Game1.chatBox.addInfoMessage("Your Grandfather's voice echoes in your head.. \"You aren't yet ready for this gift.\"");
                return;
            }

            // Find the farm's stable(s)
            List <Stable> horsehuts = new List <Stable>();

            foreach (Building building in Game1.getFarm().buildings)
            {
                if (building is Stable stable)
                {
                    foreach (Horse horse in horses)
                    {
                        if (stable.HorseId == horse.HorseId)
                        {
                            horsehuts.Add(building as Stable);
                            break;
                        }
                    }
                }
            }

            // Player does not own a stable
            if (horsehuts.Count == 0)
            {
                ModEntry.SMonitor.Log("NOTICE: You don't have a stable to warp to!", LogLevel.Error);
                Game1.chatBox.addInfoMessage("Your Grandfather's voice echoes in your head.. \"You aren't yet ready for this gift.\"");
                return;
            }

            // WARP THEM. WARP THEM ALL.
            foreach (Horse horse in horses)
            {
                foreach (Stable stable in horsehuts)
                {
                    if (horse.HorseId == stable.HorseId)
                    {
                        int     stableX    = int.Parse(stable.tileX.ToString()) + 1;
                        int     stableY    = int.Parse(stable.tileY.ToString()) + 1;
                        Vector2 stableWarp = new Vector2(stableX, stableY);
                        Game1.warpCharacter(horse, "farm", stableWarp);
                        break;
                    }
                }
            }


            ModEntry.SMonitor.Log("All horses have been warped to the stable.", LogLevel.Info);
        }
Exemplo n.º 24
0
 /// <summary>Initiate A&S data on farm</summary>
 public void UpdateCreatureCount()
 {
     // TODO: Put this where it belongs. Use to load game, then check in UpdateTicked to make sure all farmhands and host have animals and skins known
     if (Game1.getFarm() != null)
     {
         Game1.getFarm().modData[$"{this.ModManifest.UniqueID}/count-farmanimals"] = Game1.getFarm().getAllFarmAnimals().Count.ToString();
         Game1.getFarm().modData[$"{this.ModManifest.UniqueID}/count-pets"]        = ModApi.GetPets().Count().ToString();
         Game1.getFarm().modData[$"{this.ModManifest.UniqueID}/count-horses"]      = ModApi.GetHorses().Count().ToString();
     }
 }
Exemplo n.º 25
0
 internal static int RandomizeSkin(Character creature)
 {
     return(SetSkin(creature, GetRandomSkin(ModApi.GetInternalType(creature))));
 }
Exemplo n.º 26
0
        /// <summary>
        /// Given the ID for an animal, pet, or horse, and that creature's type, return the AnimalSkin mapped to that creature.
        /// Return null if the creature type isn't handled.
        /// </summary>
        internal AnimalSkin GetSkin(Character creature)
        {
            switch (creature)
            {
            case Horse horse:
                // No horse skins are loaded
                if (HorseAssets[Sanitize(horse.GetType().Name)].Count == 0)
                {
                    return(null);
                }

                // A wild horse is being checked
                if (horse.Manners == WildHorse.WildID)
                {
                    return(GetSkinFromID(horse.GetType().Name, Creator.HorseInfo.SkinID));
                }
                // Horse is not in system
                else if (horse.Manners == 0 || !HorseSkinMap.ContainsKey(horse.Manners))
                {
                    this.Monitor.Log($"Horse not in system: {horse.Name}", LogLevel.Error);
                    return(null);
                }

                // Ensure skin ID given is a valid number for the given horse type
                int horseSkinID = HorseSkinMap[horse.Manners];
                if (horseSkinID < 1 || horseSkinID > HorseAssets[Sanitize(horse.GetType().Name)].Count)
                {
                    this.Monitor.Log($"{horse.Name}'s skin ID no longer exists in `/assets/skins`. Skin will be randomized.", LogLevel.Alert);
                    horseSkinID = SetRandomSkin(horse);
                }

                // Horse has a skin. Return it.
                return(GetSkinFromID(horse.GetType().Name, horseSkinID));

            case Pet pet:
                string petType = Sanitize(pet.GetType().Name);

                // Break out of unhandled types
                if (!ModApi.GetHandledPetTypes().Contains(petType))
                {
                    break;
                }
                else if (PetAssets[Sanitize(pet.GetType().Name)].Count == 0)
                {
                    return(null);
                }

                // A stray pet is being checked
                if (pet.Manners == Stray.StrayID)
                {
                    return(GetSkinFromID(pet.GetType().Name, Creator.StrayInfo.SkinID));
                }
                // Pet is not in system
                else if (pet.Manners == 0 || !PetSkinMap.ContainsKey(pet.Manners))
                {
                    this.Monitor.Log($"Pet not in system: {pet.Name}", LogLevel.Error);
                    return(null);
                }

                // Ensure skin ID given is a current valid number for the given pet type
                int petSkinID = PetSkinMap[pet.Manners];
                if (petSkinID < 1 || petSkinID > PetAssets[petType].Count)
                {
                    this.Monitor.Log($"{pet.Name}'s skin ID no longer exists in `/assets/skins`. Skin will be randomized.", LogLevel.Alert);
                    petSkinID = SetRandomSkin(pet);
                }
                return(GetSkinFromID(petType, petSkinID));

            case FarmAnimal animal:
                string animalType = Sanitize(animal.type.Value);

                // Break out of unhandled types
                if (!ModApi.GetHandledAnimalTypes().Contains(animalType))
                {
                    break;
                }
                else if (AnimalAssets[Sanitize(animal.type.Value)].Count == 0)
                {
                    return(null);
                }

                // Set sub-type if applicable
                if (ModApi.HasBabySprite(animalType) && animal.age.Value < animal.ageWhenMature.Value)
                {
                    animalType = "baby" + animalType;
                }
                else if (ModApi.HasShearedSprite(animalType) && animal.currentProduce.Value <= 0)
                {
                    animalType = "sheared" + animalType;
                }

                // Animal is not in system
                if (!AnimalSkinMap.ContainsKey(animal.myID.Value))
                {
                    return(null);
                }

                // Ensure skin ID given is a current valid number for the given animal type
                int animalSkinID = AnimalSkinMap[animal.myID.Value];
                if (animalSkinID < 1 || animalSkinID > AnimalAssets[animalType].Count)
                {
                    this.Monitor.Log($"{animal.Name}'s skin ID is no longer exists in `/assets/skins`. Skin will be randomized.", LogLevel.Alert);
                    animalSkinID = SetRandomSkin(animal);
                }
                return(GetSkinFromID(animalType, animalSkinID));

            default:
                break;
            }
            return(null);
        }