/// <summary>Determines the quality that the produce should be.</summary> /// <param name="animal">The animal that is dropping the product.</param> /// <param name="produce">The produce that is being dropped.</param> /// <returns>4 when the product should be iridium quality, 2 when the product should be gold quality, 1 when the product should be silver quality, or 0 when the product should be normal quality.</returns> public static int DetermineProductQuality(FarmAnimal animal, AnimalProduce produce) { // check if the product is allowed to have different qualities if (produce.StandardQualityOnly) { return(0); } // determine base quality chance (using the base game algorithm) var qualityChance = animal.friendshipTowardFarmer / 1000f - (1 - animal.happiness / 255f); // apply profession bonuses if (animal.isCoopDweller() && Game1.getFarmer(animal.ownerID).professions.Contains(Farmer.butcher) || // for some reason the CoopMaster profession constant is called Butcher !animal.isCoopDweller() && Game1.getFarmer(animal.ownerID).professions.Contains(Farmer.shepherd)) { qualityChance += .33f; } // choose quality if (qualityChance >= .95f && Game1.random.NextDouble() < qualityChance / 2) { return(4); } if (Game1.random.NextDouble() < qualityChance / 2) { return(2); } if (Game1.random.NextDouble() < qualityChance) { return(1); } return(0); }
/// <summary>Determines if the upgraded product in an animal produce should be dropped.</summary> /// <param name="produce">The animal produce to use determine whether the upgraded product should be dropped.</param> /// <param name="animal">The animal that is producing the product.</param> /// <returns><see langword="null"/> if neither the default product or upgraded product could be dropped, <see langword="true"/> if the upgraded product should be dropped; otherwise, <see langword="false"/>.</returns> public static bool?ShouldDropUpgradedProduct(AnimalProduce produce, FarmAnimal animal) { // determine if the upgraded product should be dropped var canDropDefaultProduct = produce.DefaultProductId != -1 && animal.friendshipTowardFarmer >= produce.DefaultProductMinFriendship && animal.friendshipTowardFarmer <= produce.DefaultProductMaxFriendship; var canDropUpgradedProduct = produce.UpgradedProductId != -1 && animal.friendshipTowardFarmer >= produce.UpgradedProductMinFriendship && animal.friendshipTowardFarmer <= produce.UpgradedProductMaxFriendship; // ensure a product can be dropped at all if (!canDropDefaultProduct && !canDropUpgradedProduct) { return(null); } var dropUpgradedProduct = false; if (canDropDefaultProduct && canDropUpgradedProduct) { // determine which product should get dropped if (produce.PercentChanceForUpgradedProduct == null) { var happinessModifier = 0f; if (animal.happiness > 200) { happinessModifier = animal.happiness * 1.5f; } else if (animal.happiness >= 100) { happinessModifier = animal.happiness - 100; } // check if upgraded product is rare, and use the base game algorithm to determine if the rare product should be dropped if (produce.UpgradedProductIsRare) { dropUpgradedProduct = Game1.random.NextDouble() < (animal.friendshipTowardFarmer + happinessModifier) / 5000 + Game1.player.team.AverageDailyLuck() + (Game1.player.team.AverageDailyLuck() * .02f); } // use the base game algorithm to determine if the upgraded product should get dropped else { dropUpgradedProduct = Game1.random.NextDouble() < (animal.friendshipTowardFarmer + happinessModifier) / 1200; } } else { dropUpgradedProduct = Game1.random.NextDouble() * 100 + 1 <= produce.PercentChanceForUpgradedProduct; } } else if (canDropUpgradedProduct) // make sure to return true if only the upgraded product is able to be dropped { dropUpgradedProduct = true; } return(dropUpgradedProduct); }
/// <summary>Determines the amount of product should be dropped.</summary> /// <param name="produce">The produce that is being dropped.</param> /// <returns>The stack size of the product to drop.</returns> public static int DetermineDropAmount(AnimalProduce produce) { var amount = produce.Amount; if (Game1.random.NextDouble() * 100 + 1 <= produce.PercentChanceForOneExtra) { amount++; } return(amount); }
/// <summary>Determines the number of days a produce should take to produce.</summary> /// <param name="produce">The produce to determine the days to produce for.</param> /// <returns>The number of days the product should take to produce.</returns> public static int DetermineDaysToProduce(AnimalProduce produce) { var daysToProduce = produce.DaysToProduce; if (produce.ProduceFasterWithCoopMaster && Game1.player.professions.Contains(Farmer.butcher)) { daysToProduce--; } if (produce.ProduceFasterWithShepherd && Game1.player.professions.Contains(Farmer.shepherd)) { daysToProduce--; } return(Math.Max(0, daysToProduce)); }
/// <summary>Print the passed <see cref="AnimalProduce"/>.</summary> /// <param name="animalProduce">The <see cref="AnimalProduce"/> to print.</param> private void PrintAnimalProduce(AnimalProduce animalProduce) { if (animalProduce.AllSeasons != null) { PrintAnimalProduceSeason(animalProduce.AllSeasons); } if (animalProduce.Spring != null) { PrintAnimalProduceSeason(animalProduce.Spring); } if (animalProduce.Summer != null) { PrintAnimalProduceSeason(animalProduce.Summer); } if (animalProduce.Fall != null) { PrintAnimalProduceSeason(animalProduce.Fall); } if (animalProduce.Winter != null) { PrintAnimalProduceSeason(animalProduce.Winter); } }
/// <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}/"); } }