Beispiel #1
0
        /// <summary>Loads a new animal from a content pack.</summary>
        private void AddNewAnimalEntry(AnimalData animalData, IContentPack contentPack, string animalName)
        {
            // set the shop display icon
            if (animalData.AnimalShopInfo != null)
            {
                animalData.AnimalShopInfo.ShopIcon = GetSpriteByPath(Path.Combine(animalName, $"shopdisplay.png"), contentPack);
            }

            // loop through each sub type to get sprites, resolve tokens, and validate
            var validTypes = new List <AnimalSubType>();

            foreach (var type in animalData.Types)
            {
                if (LoadAnimalSubType(type, contentPack, animalName))
                {
                    validTypes.Add(type);
                }
            }

            // set the data types to be the valid types
            animalData.Types = validTypes;

            // ensure there were valid sub types
            if (animalData.Types.Count == 0)
            {
                this.Monitor.Log($"No valid sub types for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName}.\n Animal will not be added.", LogLevel.Error);
                return;
            }

            // create, validate, and add the animal
            var animal = new Animal(
                name: animalName,
                data: animalData
                );

            if (!animal.IsValid())
            {
                this.Monitor.Log($"Animal is not valid at Content pack: {contentPack.Manifest.Name} >> Animal: {animalName}", LogLevel.Error);
                return;
            }

            Animals.Add(animal);

            // construct data string for game to use
            foreach (var subType in animal.Data.Types)
            {
                DataStrings.Add(subType.Name, $"{animal.Data.DaysToProduce}/{animal.Data.DaysTillMature}///{animal.Data.SoundId}//////////{subType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{animal.Data.FrontAndBackSpriteWidth}/{animal.Data.FrontAndBackSpriteHeight}/{animal.Data.SideSpriteWidth}/{animal.Data.SideSpriteHeight}/{animal.Data.FullnessDrain}/{animal.Data.HappinessDrain}//0/{animal.Data.AnimalShopInfo?.BuyPrice}/{subType.Name}/");
            }
        }
        /// <summary>Load all the sprites for the new animals from the loaded content packs.</summary>
        public void LoadContentPacks()
        {
            // loading Json Assets early is only required on connected clients - Game1.IsClient can't be used as that doesn't get set yet - this should have no effect on host
            LoadJAEarly();

            foreach (IContentPack contentPack in this.Helper.ContentPacks.GetOwned())
            {
                Monitor.Log($"Loading {contentPack.Manifest.Name}");

                // loop through each animal folder in the current content pack
                foreach (var animalFolder in Directory.GetDirectories(contentPack.DirectoryPath))
                {
                    var animalFolderSplit = animalFolder.Split(Path.DirectorySeparatorChar);
                    var animalName        = animalFolderSplit[animalFolderSplit.Length - 1];

                    // ensure content.json file exists
                    if (!File.Exists(Path.Combine(animalFolder, "content.json")))
                    {
                        this.Monitor.Log($"Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} doesn't contain a content.json file.", LogLevel.Error);
                        continue;
                    }

                    // serialize and validate content.json file
                    AnimalData animalData = contentPack.LoadAsset <AnimalData>(Path.Combine(animalName, "content.json"));
                    if (!animalData.IsValid(animalName))
                    {
                        this.Monitor.Log($"Content.json is not valid for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName}", LogLevel.Error);
                        continue;
                    }

                    // loop through each sub type and add them (such as colour varients etc)
                    List <AnimalSubType> animalSubTypes = new List <AnimalSubType>();
                    foreach (var type in animalData.Types)
                    {
                        // get sprites
                        var sprites = new AnimalSprites(
                            adultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"{type.Name}.png"), contentPack),
                            babySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"Baby {type.Name}.png"), contentPack),
                            harvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", $"Harvested {type.Name}.png"), contentPack),
                            springAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"{type.Name}.png"), contentPack),
                            springHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"Harvested {type.Name}.png"), contentPack),
                            springBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "spring", $"Baby {type.Name}.png"), contentPack),
                            summerAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"{type.Name}.png"), contentPack),
                            summerHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"Harvested {type.Name}.png"), contentPack),
                            summerBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "summer", $"Baby {type.Name}.png"), contentPack),
                            fallAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"{type.Name}.png"), contentPack),
                            fallHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"Harvested {type.Name}.png"), contentPack),
                            fallBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "fall", $"Baby {type.Name}.png"), contentPack),
                            winterAdultSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"{type.Name}.png"), contentPack),
                            winterHarvestedSpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"Harvested {type.Name}.png"), contentPack),
                            winterBabySpriteSheet: GetSpriteByPath(Path.Combine(animalName, "assets", "winter", $"Baby {type.Name}.png"), contentPack)
                            );

                        // ensure sprites are valid
                        if (!sprites.IsValid())
                        {
                            this.Monitor.Log($"Sprites are not valid for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} >> Subtype: {type}", LogLevel.Error);
                            continue;
                        }
                        type.Sprites = sprites;

                        // resolve API tokens in data and validate it
                        type.ResolveTokens();
                        if (!type.IsValid())
                        {
                            this.Monitor.Log($"Data is not valid for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName} >> Subtype: {type.Name}", LogLevel.Error);
                            continue;
                        }

                        animalSubTypes.Add(type);
                    }

                    // ensure there were valid sub types
                    if (animalSubTypes.Count == 0)
                    {
                        this.Monitor.Log($"No valid sub types for Content pack: {contentPack.Manifest.Name} >> Animal: {animalName}.\n Animal will not be added.", LogLevel.Error);
                        continue;
                    }

                    // create, validate, and add the animal
                    var animal = new Animal(
                        name: animalName,
                        data: animalData,
                        shopIcon: GetSpriteByPath(Path.Combine(animalName, $"shopdisplay.png"), contentPack),
                        subTypes: animalSubTypes
                        );

                    if (!animal.IsValid())
                    {
                        this.Monitor.Log($"Animal is not valid at Content pack: {contentPack.Manifest.Name} >> Animal: {animalName}", LogLevel.Error);
                        continue;
                    }

                    Animals.Add(animal);

                    // construct data string for game to use
                    foreach (var subType in animal.SubTypes)
                    {
                        DataStrings.Add(subType.Name, $"{animal.Data.DaysToProduce}/{animal.Data.DaysTillMature}///{animal.Data.SoundId}//////////{subType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{animal.Data.FrontAndBackSpriteWidth}/{animal.Data.FrontAndBackSpriteHeight}/{animal.Data.SideSpriteWidth}/{animal.Data.SideSpriteHeight}/{animal.Data.FullnessDrain}/{animal.Data.HappinessDrain}//0/{animal.Data.AnimalShopInfo?.BuyPrice}/{subType.Name}/");
                    }
                }
            }

            // print all added farm animals to trace
            PrintAnimalData();

            // invalidate farm animal cache to add the new data strings to it
            this.Helper.Content.InvalidateCache("Data/FarmAnimals");
        }
Beispiel #3
0
        /// <summary>Load all the default animals into the datastrings. This is so content packs can also edit default animals.</summary>
        private void LoadDefaultAnimals()
        {
            //
            // Chicken
            //
            // create chicken produce objects for white/blue and brown chickens
            var chickenProduce = new AnimalProduce(new AnimalProduceSeason(
                                                       products: new List <AnimalProduct> {
                new AnimalProduct("176", HarvestType.Lay, null)
            },
                                                       deluxeProducts: new List <AnimalProduct> {
                new AnimalProduct("174", HarvestType.Lay, null)
            }));

            var brownChickenProduce = new AnimalProduce(new AnimalProduceSeason(
                                                            products: new List <AnimalProduct> {
                new AnimalProduct("180", HarvestType.Lay, null)
            },
                                                            deluxeProducts: new List <AnimalProduct> {
                new AnimalProduct("182", HarvestType.Lay, null)
            }));

            // create animal sprites objects for the 3 chicken types
            var whiteChickenSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "White Chicken")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyWhite Chicken")));
            var brownChickenSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Brown Chicken")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyBrown Chicken")));
            var blueChickenSprites  = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Blue Chicken")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyBlue Chicken")));

            // create chick sub types (checking for the event for the blue chicken)
            var chickenTypes = new List <AnimalSubType>();

            chickenTypes.Add(new AnimalSubType("White Chicken", chickenProduce, whiteChickenSprites));
            chickenTypes.Add(new AnimalSubType("Brown Chicken", brownChickenProduce, brownChickenSprites));

            // TODO: Game1.player is null at this point
            //if (Game1.player.eventsSeen.Contains(3900074)) // add the ability to get blue chicken if the player has seen the shane event for it
            //    chickenTypes.Add(new AnimalSubType("Blue Chicken", chickenProduce, blueChickenSprites));

            // create and add the chicken object
            var chickenShopInfo = new AnimalShopInfo(
                description: Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11334")) + Environment.NewLine + Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11335")),
                buyPrice: 800,
                shopIcon: GetSubTexture(Game1.content.Load <Texture2D>(Path.Combine("LooseSprites", "Cursors")), new Rectangle(0, 448, 32, 16)));
            var chickenData = new AnimalData("Chicken", true, false, chickenShopInfo, chickenTypes, 1, 3, "cluck", 16, 16, 16, 16, 4, 7, new List <string> {
                "Coop", "Big Coop", "Deluxe Coop"
            }, 2, 1900, new List <Season> {
                Season.Spring, Season.Summer, Season.Fall
            });

            Animals.Add(new Animal("Chicken", chickenData));

            // construct data string for game to use
            foreach (var chickenSubType in chickenData.Types)
            {
                DataStrings.Add(chickenSubType.Name, $"{chickenData.DaysToProduce}/{chickenData.DaysTillMature}///{chickenData.SoundId}//////////{chickenSubType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{chickenData.FrontAndBackSpriteWidth}/{chickenData.FrontAndBackSpriteHeight}/{chickenData.SideSpriteWidth}/{chickenData.SideSpriteHeight}/{chickenData.FullnessDrain}/{chickenData.HappinessDrain}//0/{chickenData.AnimalShopInfo?.BuyPrice}/{chickenSubType.Name}/");
            }

            //
            // Duck
            //
            // create duck produce object
            var duckProduce = new AnimalProduce(new AnimalProduceSeason(
                                                    products: new List <AnimalProduct> {
                new AnimalProduct("442", HarvestType.Lay, null)
            },
                                                    deluxeProducts: new List <AnimalProduct> {
                new AnimalProduct("444", HarvestType.Lay, null)
            }));

            // create duck sprites
            var duckSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Duck")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyWhite Chicken")));

            // create duck sub type
            var duckTypes = new List <AnimalSubType>();

            duckTypes.Add(new AnimalSubType("Duck", duckProduce, duckSprites));

            // create and add duck object
            var duckShopInfo = new AnimalShopInfo(
                description: Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11337")) + Environment.NewLine + Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11335")),
                buyPrice: 4000,
                shopIcon: GetSubTexture(Game1.content.Load <Texture2D>(Path.Combine("LooseSprites", "Cursors")), new Rectangle(0, 464, 32, 16)));
            var duckData = new AnimalData("Duck", true, false, duckShopInfo, duckTypes, 2, 5, "Duck", 16, 16, 16, 16, 3, 8, new List <string> {
                "Big Coop", "Deluxe Coop"
            }, 2, 1900, new List <Season> {
                Season.Spring, Season.Summer, Season.Fall
            });

            Animals.Add(new Animal("Duck", duckData));

            // construct data string for game to use
            foreach (var duckSubType in duckData.Types)
            {
                DataStrings.Add(duckSubType.Name, $"{duckData.DaysToProduce}/{duckData.DaysTillMature}///{duckData.SoundId}//////////{duckSubType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{duckData.FrontAndBackSpriteWidth}/{duckData.FrontAndBackSpriteHeight}/{duckData.SideSpriteWidth}/{duckData.SideSpriteHeight}/{duckData.FullnessDrain}/{duckData.HappinessDrain}//0/{duckData.AnimalShopInfo?.BuyPrice}/{duckSubType.Name}/");
            }

            //
            // Rabbit
            //
            // create rabbit produce object
            var rabbitProduce = new AnimalProduce(new AnimalProduceSeason(
                                                      products: new List <AnimalProduct> {
                new AnimalProduct("440", HarvestType.Lay, null)
            },
                                                      deluxeProducts: new List <AnimalProduct> {
                new AnimalProduct("446", HarvestType.Lay, null)
            }));

            // create rabbit sprites
            var rabbitSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Rabbit")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyRabbit")));

            // create rabbit sub type
            var rabbitTypes = new List <AnimalSubType>();

            rabbitTypes.Add(new AnimalSubType("Rabbit", rabbitProduce, rabbitSprites));

            // create and add rabbit object
            var rabbitShopInfo = new AnimalShopInfo(
                description: Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11340")) + Environment.NewLine + Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11335")),
                buyPrice: 8000,
                shopIcon: GetSubTexture(Game1.content.Load <Texture2D>(Path.Combine("LooseSprites", "Cursors")), new Rectangle(64, 464, 32, 16)));
            var rabbitData = new AnimalData("Rabbit", true, false, rabbitShopInfo, rabbitTypes, 4, 6, "rabbit", 16, 16, 16, 16, 10, 5, new List <string> {
                "Deluxe Coop"
            }, 2, 1900, new List <Season> {
                Season.Spring, Season.Summer, Season.Fall
            });

            Animals.Add(new Animal("Rabbit", rabbitData));

            // construct data string for game to use
            foreach (var rabbitSubType in rabbitData.Types)
            {
                DataStrings.Add(rabbitSubType.Name, $"{rabbitData.DaysToProduce}/{rabbitData.DaysTillMature}///{rabbitData.SoundId}//////////{rabbitSubType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{rabbitData.FrontAndBackSpriteWidth}/{rabbitData.FrontAndBackSpriteHeight}/{rabbitData.SideSpriteWidth}/{rabbitData.SideSpriteHeight}/{rabbitData.FullnessDrain}/{rabbitData.HappinessDrain}//0/{rabbitData.AnimalShopInfo?.BuyPrice}/{rabbitSubType.Name}/");
            }

            //
            // Dinosaur
            //
            // create dinosaur produce object
            var dinosaurProduce = new AnimalProduce(new AnimalProduceSeason(
                                                        products: new List <AnimalProduct> {
                new AnimalProduct("107", HarvestType.Lay, null)
            }));

            // create dinosaur sprites
            var dinosaurSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Dinosaur")));

            // create dinosaur sub type
            var dinosaurTypes = new List <AnimalSubType>();

            dinosaurTypes.Add(new AnimalSubType("Dinosaur", dinosaurProduce, dinosaurSprites));

            // create and add dinosaur object
            var dinosaurData = new AnimalData("Dinosaur", true, false, null, dinosaurTypes, 7, 0, "none", 16, 16, 16, 16, 1, 8, new List <string> {
                "Deluxe Coop"
            }, 2, 1900, new List <Season> {
                Season.Spring, Season.Summer, Season.Fall
            });

            Animals.Add(new Animal("Dinosaur", dinosaurData));

            // construct data string for game to use
            foreach (var dinosaurSubType in dinosaurData.Types)
            {
                DataStrings.Add(dinosaurSubType.Name, $"{dinosaurData.DaysToProduce}/{dinosaurData.DaysTillMature}///{dinosaurData.SoundId}//////////{dinosaurSubType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{dinosaurData.FrontAndBackSpriteWidth}/{dinosaurData.FrontAndBackSpriteHeight}/{dinosaurData.SideSpriteWidth}/{dinosaurData.SideSpriteHeight}/{dinosaurData.FullnessDrain}/{dinosaurData.HappinessDrain}//0/{dinosaurData.AnimalShopInfo?.BuyPrice}/{dinosaurSubType.Name}/");
            }

            //
            // Cow
            //
            // create cow produce object
            var cowProduce = new AnimalProduce(new AnimalProduceSeason(
                                                   products: new List <AnimalProduct> {
                new AnimalProduct("184", HarvestType.Tool, "Milk Pail")
            },
                                                   deluxeProducts: new List <AnimalProduct> {
                new AnimalProduct("186", HarvestType.Tool, "Milk Pail")
            }));

            // create cow sprites
            var whiteCowSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "White Cow")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyWhite Cow")));
            var brownCowSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Brown Cow")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyBrown Cow")));

            // create cow sub types
            var cowTypes = new List <AnimalSubType>();

            cowTypes.Add(new AnimalSubType("White Cow", cowProduce, whiteCowSprites));
            cowTypes.Add(new AnimalSubType("Brown Cow", cowProduce, brownCowSprites));

            // create and add cow object
            var cowShopInfo = new AnimalShopInfo(
                description: Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11343")) + Environment.NewLine + Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11344")),
                buyPrice: 1500,
                shopIcon: GetSubTexture(Game1.content.Load <Texture2D>(Path.Combine("LooseSprites", "Cursors")), new Rectangle(32, 448, 32, 16)));
            var cowData = new AnimalData("Cow", true, false, cowShopInfo, cowTypes, 1, 5, "cow", 32, 32, 32, 32, 15, 5, new List <string> {
                "Barn", "Big Barn", "Deluxe Barn"
            }, 2, 1900, new List <Season> {
                Season.Spring, Season.Summer, Season.Fall
            });

            Animals.Add(new Animal("Cow", cowData));

            // construct data string for game to use
            foreach (var cowSubType in cowData.Types)
            {
                DataStrings.Add(cowSubType.Name, $"{cowData.DaysToProduce}/{cowData.DaysTillMature}///{cowData.SoundId}//////////{cowSubType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{cowData.FrontAndBackSpriteWidth}/{cowData.FrontAndBackSpriteHeight}/{cowData.SideSpriteWidth}/{cowData.SideSpriteHeight}/{cowData.FullnessDrain}/{cowData.HappinessDrain}//0/{cowData.AnimalShopInfo?.BuyPrice}/{cowSubType.Name}/");
            }

            //
            // Goat
            //
            // create goat produce object
            var goatProduce = new AnimalProduce(new AnimalProduceSeason(
                                                    products: new List <AnimalProduct> {
                new AnimalProduct("436", HarvestType.Tool, "Milk Pail")
            },
                                                    deluxeProducts: new List <AnimalProduct> {
                new AnimalProduct("438", HarvestType.Tool, "Milk Pail")
            }));

            // create goat sprites
            var goatSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Goat")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyGoat")));

            // create goat sub type
            var goatTypes = new List <AnimalSubType>();

            goatTypes.Add(new AnimalSubType("Goat", goatProduce, goatSprites));

            // create and add goat object
            var goatShopInfo = new AnimalShopInfo(
                description: Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11349")) + Environment.NewLine + Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11344")),
                buyPrice: 4000,
                shopIcon: GetSubTexture(Game1.content.Load <Texture2D>(Path.Combine("LooseSprites", "Cursors")), new Rectangle(64, 448, 32, 16)));
            var goatData = new AnimalData("Goat", true, false, goatShopInfo, goatTypes, 2, 5, "goat", 32, 32, 32, 32, 10, 5, new List <string> {
                "Big Barn", "Deluxe Barn"
            }, 2, 1900, new List <Season> {
                Season.Spring, Season.Summer, Season.Fall
            });

            Animals.Add(new Animal("Goat", goatData));

            // construct data string for game to use
            foreach (var goatSubType in goatData.Types)
            {
                DataStrings.Add(goatSubType.Name, $"{goatData.DaysToProduce}/{goatData.DaysTillMature}///{goatData.SoundId}//////////{goatSubType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{goatData.FrontAndBackSpriteWidth}/{goatData.FrontAndBackSpriteHeight}/{goatData.SideSpriteWidth}/{goatData.SideSpriteHeight}/{goatData.FullnessDrain}/{goatData.HappinessDrain}//0/{goatData.AnimalShopInfo?.BuyPrice}/{goatSubType.Name}/");
            }

            //
            // Pig
            //
            // create pig produce object
            var pigProduce = new AnimalProduce(new AnimalProduceSeason(
                                                   products: new List <AnimalProduct> {
                new AnimalProduct("430", HarvestType.Forage, null)
            }));

            // create pig sprites
            var pigSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Pig")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabyPig")));

            // create pig sub type
            var pigTypes = new List <AnimalSubType>();

            pigTypes.Add(new AnimalSubType("Pig", pigProduce, pigSprites));

            // create and add pig object
            var pigShopInfo = new AnimalShopInfo(
                description: Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11346")) + Environment.NewLine + Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11344")),
                buyPrice: 16000,
                shopIcon: GetSubTexture(Game1.content.Load <Texture2D>(Path.Combine("LooseSprites", "Cursors")), new Rectangle(0, 480, 32, 16)));
            var pigData = new AnimalData("Pig", true, false, pigShopInfo, pigTypes, 2, 5, "pig", 32, 32, 32, 32, 20, 5, new List <string> {
                "Deluxe Barn"
            }, 2, 1900, new List <Season> {
                Season.Spring, Season.Summer, Season.Fall
            });

            Animals.Add(new Animal("Pig", pigData));

            // construct data string for game to use
            foreach (var pigSubType in pigData.Types)
            {
                DataStrings.Add(pigSubType.Name, $"{pigData.DaysToProduce}/{pigData.DaysTillMature}///{pigData.SoundId}//////////{pigSubType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{pigData.FrontAndBackSpriteWidth}/{pigData.FrontAndBackSpriteHeight}/{pigData.SideSpriteWidth}/{pigData.SideSpriteHeight}/{pigData.FullnessDrain}/{pigData.HappinessDrain}//0/{pigData.AnimalShopInfo?.BuyPrice}/{pigSubType.Name}/");
            }

            //
            // Sheep
            //
            // create sheep produce object
            var sheepProduce = new AnimalProduce(new AnimalProduceSeason(
                                                     products: new List <AnimalProduct> {
                new AnimalProduct("440", HarvestType.Tool, "Shears")
            }));

            // create sheep sprites
            var sheepSprites = new AnimalSprites(Game1.content.Load <Texture2D>(Path.Combine("Animals", "Sheep")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "BabySheep")), Game1.content.Load <Texture2D>(Path.Combine("Animals", "ShearedSheep")));

            // create sheep sub type
            var sheepTypes = new List <AnimalSubType>();

            sheepTypes.Add(new AnimalSubType("Sheep", sheepProduce, sheepSprites));

            // create and add sheep object
            var sheepShopInfo = new AnimalShopInfo(
                description: Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11352")) + Environment.NewLine + Game1.content.LoadString(Path.Combine("Strings", "StringsFromCSFiles:PurchaseAnimalsMenu.cs.11344")),
                buyPrice: 8000,
                shopIcon: GetSubTexture(Game1.content.Load <Texture2D>(Path.Combine("LooseSprites", "Cursors")), new Rectangle(32, 464, 32, 16)));
            var sheepData = new AnimalData("Sheep", true, false, sheepShopInfo, sheepTypes, 2, 5, "sheep", 32, 32, 32, 32, 20, 5, new List <string> {
                "Deluxe Barn"
            }, 2, 1900, new List <Season> {
                Season.Spring, Season.Summer, Season.Fall
            });

            Animals.Add(new Animal("Sheep", sheepData));

            // construct data string for game to use
            foreach (var sheepSubType in sheepData.Types)
            {
                DataStrings.Add(sheepSubType.Name, $"{sheepData.DaysToProduce}/{sheepData.DaysTillMature}///{sheepData.SoundId}//////////{sheepSubType.Sprites.HasDifferentSpriteSheetWhenHarvested()}//{sheepData.FrontAndBackSpriteWidth}/{sheepData.FrontAndBackSpriteHeight}/{sheepData.SideSpriteWidth}/{sheepData.SideSpriteHeight}/{sheepData.FullnessDrain}/{sheepData.HappinessDrain}//0/{sheepData.AnimalShopInfo?.BuyPrice}/{sheepSubType.Name}/");
            }
        }