public bool ShouldDieOfOldAge(FarmAnimal animal) { int age = animal.GetDaysOwned(); var ages = GetMinAndMaxAnimalAgeInYears(animal); // convert years to days int minAge = ages.Item1 * 28 * 4; int maxAge = ages.Item2 * 28 * 4; if (age >= minAge) { double ran = Game1.random.NextDouble(); double mappedValue = Map(age, minAge, maxAge, 0, 1); if (ran < mappedValue) { return(true); } } return(false); }
public override void draw(SpriteBatch b) { if (!movingAnimal && !Game1.globalFade) { b.Draw(Game1.fadeToBlackRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.Black * 0.75f); Game1.drawDialogueBox(xPositionOnScreen, yPositionOnScreen + 128, width, height - 128, speaker: false, drawOnlyBox: true); if ((byte)animal.harvestType != 2) { textBox.Draw(b); } int age = (animal.GetDaysOwned() + 1) / 28 + 1; string ageText = (age <= 1) ? Game1.content.LoadString("Strings\\UI:AnimalQuery_Age1") : Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeN", age); if ((int)animal.age < (byte)animal.ageWhenMature) { ageText += Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeBaby"); } Utility.drawTextWithShadow(b, ageText, Game1.smallFont, new Vector2(xPositionOnScreen + IClickableMenu.spaceToClearSideBorder + 32, yPositionOnScreen + IClickableMenu.spaceToClearTopBorder + 16 + 128), Game1.textColor); int yOffset = 0; if (parentName != null) { yOffset = 21; Utility.drawTextWithShadow(b, Game1.content.LoadString("Strings\\UI:AnimalQuery_Parent", parentName), Game1.smallFont, new Vector2(xPositionOnScreen + IClickableMenu.spaceToClearSideBorder + 32, 32 + yPositionOnScreen + IClickableMenu.spaceToClearTopBorder + 16 + 128), Game1.textColor); } int halfHeart = (int)((loveLevel * 1000.0 % 200.0 >= 100.0) ? (loveLevel * 1000.0 / 200.0) : (-100.0)); for (int i = 0; i < 5; i++) { b.Draw(Game1.mouseCursors, new Vector2(xPositionOnScreen + 96 + 32 * i, yOffset + yPositionOnScreen - 32 + 320), new Microsoft.Xna.Framework.Rectangle(211 + ((loveLevel * 1000.0 <= (double)((i + 1) * 195)) ? 7 : 0), 428, 7, 6), Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.89f); if (halfHeart == i) { b.Draw(Game1.mouseCursors, new Vector2(xPositionOnScreen + 96 + 32 * i, yOffset + yPositionOnScreen - 32 + 320), new Microsoft.Xna.Framework.Rectangle(211, 428, 4, 6), Color.White, 0f, Vector2.Zero, 4f, SpriteEffects.None, 0.891f); } } Utility.drawTextWithShadow(b, Game1.parseText(animal.getMoodMessage(), Game1.smallFont, width - IClickableMenu.spaceToClearSideBorder * 2 - 64), Game1.smallFont, new Vector2(xPositionOnScreen + IClickableMenu.spaceToClearSideBorder + 32, yOffset + yPositionOnScreen + 384 - 64 + 4), Game1.textColor); okButton.draw(b); sellButton.draw(b); moveHomeButton.draw(b); if (allowReproductionButton != null) { allowReproductionButton.draw(b); } if (confirmingSell) { b.Draw(Game1.fadeToBlackRect, Game1.graphics.GraphicsDevice.Viewport.Bounds, Color.Black * 0.75f); Game1.drawDialogueBox(Game1.uiViewport.Width / 2 - 160, Game1.uiViewport.Height / 2 - 192, 320, 256, speaker: false, drawOnlyBox: true); string confirmText = Game1.content.LoadString("Strings\\UI:AnimalQuery_ConfirmSell"); b.DrawString(Game1.dialogueFont, confirmText, new Vector2((float)(Game1.uiViewport.Width / 2) - Game1.dialogueFont.MeasureString(confirmText).X / 2f, Game1.uiViewport.Height / 2 - 96 + 8), Game1.textColor); yesButton.draw(b); noButton.draw(b); } else if (hoverText != null && hoverText.Length > 0) { IClickableMenu.drawHoverText(b, hoverText, Game1.smallFont); } } else if (!Game1.globalFade) { string s = Game1.content.LoadString("Strings\\UI:AnimalQuery_ChooseBuilding", animal.displayHouse, animal.displayType); Game1.drawDialogueBox(32, -64, (int)Game1.dialogueFont.MeasureString(s).X + IClickableMenu.borderWidth * 2 + 16, 128 + IClickableMenu.borderWidth * 2, speaker: false, drawOnlyBox: true); b.DrawString(Game1.dialogueFont, s, new Vector2(32 + IClickableMenu.spaceToClearSideBorder * 2 + 8, 44f), Game1.textColor); okButton.draw(b); } drawMouse(b); }
/// <summary>Invoked when the menu should get drawn.</summary> /// <param name="b">The sprite batch to draw the menu to.</param> public override void draw(SpriteBatch b) { if (CurrentStage == AnimalQueryMenuStage.Main || CurrentStage == AnimalQueryMenuStage.ConfirmingSell) // when the animal is being sold, the main menu should be drawn underneath { // dark background b.Draw( texture: Game1.fadeToBlackRect, destinationRectangle: Game1.graphics.GraphicsDevice.Viewport.Bounds, color: Color.Black * .75f ); // menu background Game1.drawDialogueBox( x: this.xPositionOnScreen, y: this.yPositionOnScreen + 128, width: DefaultWidth, height: DefaultHeight - 128, speaker: false, drawOnlyBox: true ); // name box NameTextBox.Draw(b); // age var ageInMonths = (Animal.GetDaysOwned() + 1) / 28 + 1; var ageText = (ageInMonths <= 1) ? Game1.content.LoadString("Strings\\UI:AnimalQuery_Age1") : Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeN", ageInMonths); if (Animal.age < Animal.ageWhenMature) { ageText += Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeBaby"); // append '(Baby)' on the end } Utility.drawTextWithShadow( b: b, text: ageText, font: Game1.smallFont, position: new Vector2(this.xPositionOnScreen + IClickableMenu.spaceToClearSideBorder + 32, this.yPositionOnScreen + IClickableMenu.spaceToClearTopBorder + 16 + 128), color: Game1.textColor ); // parent var yOffset = 0; if (ParentName != null) { yOffset = 21; Utility.drawTextWithShadow( b: b, text: Game1.content.LoadString("Strings\\UI:AnimalQuery_Parent", ParentName), font: Game1.smallFont, position: new Vector2(this.xPositionOnScreen + IClickableMenu.spaceToClearSideBorder + 32, 32 + this.yPositionOnScreen + IClickableMenu.spaceToClearTopBorder + 16 + 128), color: Game1.textColor ); } // hearts var halfHeart = (LoveLevel * 1000 % 200 >= 100) // half heart refers to which heart should be displayed as a half heart (if any) ? LoveLevel * 1000 / 200 : -100; for (int i = 0; i < 5; i++) { var sourceRectangle = new Rectangle(211 + ((LoveLevel * 1000 <= ((i + 1) * 195)) ? 7 : 0), 428, 7, 6); var layerDepth = .89f; if (halfHeart == 1) { sourceRectangle = new Rectangle(211, 428, 4, 6); layerDepth = .891f; } b.Draw( texture: Game1.mouseCursors, position: new Vector2(this.xPositionOnScreen + 96 + 32 * i, yOffset + this.yPositionOnScreen - 32 + 320), sourceRectangle: sourceRectangle, color: Color.White, rotation: 0, origin: Vector2.Zero, scale: 4, effects: SpriteEffects.None, layerDepth: layerDepth ); } // mood message Utility.drawTextWithShadow( b: b, text: Game1.parseText(Animal.getMoodMessage(), Game1.smallFont, AnimalQueryMenu.width - IClickableMenu.spaceToClearSideBorder * 2 - 64), font: Game1.smallFont, position: new Vector2(base.xPositionOnScreen + IClickableMenu.spaceToClearSideBorder + 32, yOffset + base.yPositionOnScreen + 384 - 64 + 4), color: Game1.textColor ); // buttons MoveHomeButton.draw(b); SellButton.draw(b); OkButton.draw(b); if (AllowReproductionButton != null) // this is null when the animal can't reproduce { AllowReproductionButton.draw(b); } // hover text if (!string.IsNullOrEmpty(HoverText)) { IClickableMenu.drawHoverText(b, HoverText, Game1.smallFont); } // draw the overlayed sell menu if needed if (CurrentStage == AnimalQueryMenuStage.ConfirmingSell) { // dark background b.Draw( texture: Game1.fadeToBlackRect, destinationRectangle: Game1.graphics.GraphicsDevice.Viewport.Bounds, color: Color.Black * .75f ); // menu background Game1.drawDialogueBox( x: Game1.uiViewport.Width / 2 - 160, y: Game1.uiViewport.Height / 2 - 192, width: 320, height: 256, speaker: false, drawOnlyBox: true ); // 'Are you sure?' label var confirmText = Game1.content.LoadString("Strings\\UI:AnimalQuery_ConfirmSell"); b.DrawString( spriteFont: Game1.dialogueFont, text: confirmText, position: new Vector2(Game1.uiViewport.Width / 2 - Game1.dialogueFont.MeasureString(confirmText).X / 2, Game1.uiViewport.Height / 2 - 96 + 8), color: Game1.textColor ); // buttons ConfirmSellButton.draw(b); DenySellButton.draw(b); } } else if (CurrentStage == AnimalQueryMenuStage.Rehoming) { // back button BackButton.draw(b); // housing string var buildingsString = ""; var animal = ModEntry.Instance.Api.GetAnimalByInternalSubtypeName(Animal.type); if (animal != null) { buildingsString = Utilities.ConstructBuildingString(animal.Buildings); } var housingString = $"Choose a {buildingsString} for your {animal.Name}"; SpriteText.drawStringWithScrollBackground( b: b, s: housingString, x: Game1.uiViewport.Width / 2 - SpriteText.getWidthOfString(housingString) / 2, y: 16 ); } this.drawMouse(b); }
private void CalculateDeathMessage(FarmAnimal animal, string cause) { // animal.age is the value that doesn't increase if you haven't fed the animal int age = animal.GetDaysOwned() + 1; string causeString = Helper.Translation.Get($"Cause.{cause}"); string ageString; if (age >= 28 * 4) { int yearCount = (age / (28 * 4)) + 1; ageString = Helper.Translation.Get(yearCount == 1 ? "Age.year" : "Age.years", new { yearCount }); int restAge = age - (yearCount * 28 * 4); if (restAge >= 28) { int monthCount = (restAge / 28) + 1; if (yearCount == 1) { ageString = Helper.Translation.Get(monthCount == 1 ? "Age.yearAndMonth" : "Age.yearAndMonths", new { yearCount, monthCount }); } else { ageString = Helper.Translation.Get(monthCount == 1 ? "Age.yearsAndMonth" : "Age.yearsAndMonths", new { yearCount, monthCount }); } } } else { if (age >= 28) { int monthCount = (age / 28) + 1; ageString = Helper.Translation.Get(monthCount == 1 ? "Age.month" : "Age.months", new { monthCount }); } else { ageString = Helper.Translation.Get(age == 1 ? "Age.day" : "Age.days", new { dayCount = age }); } } string happiness; if (animal.happiness < 30) { happiness = Helper.Translation.Get("Happiness.sad"); } else if (animal.happiness < 200) { happiness = Helper.Translation.Get("Happiness.fine"); } else { happiness = Helper.Translation.Get("Happiness.happy"); } double hearts = animal.friendshipTowardFarmer < 1000 ? animal.friendshipTowardFarmer / 200.0 : 5; double withHalfHearts = ((int)(hearts * 2.0)) / 2.0; string loveString = Helper.Translation.Get(withHalfHearts == 1 ? "Love.heart" : "Love.hearts", new { heartCount = withHalfHearts }); // if the locale is the default locale, keep the english animal type string animalType = string.IsNullOrWhiteSpace(Helper.Translation.Locale) ? animal.type.Value.ToLower() : animal.displayType; string message = Helper.Translation.Get("AnimalDeathMessage", new { animalType, animalName = animal.name, cause = causeString, entireAgeText = ageString, happinessText = happiness, lovestring = loveString }); PostMessage(message); }
internal static void AnimalQueryMenuPatch(AnimalQueryMenu __instance, bool ___confirmingSell, FarmAnimal ___animal, TextBox ___textBox, string ___parentName) { try { int x = Game1.getMouseX(true), y = Game1.getMouseY(true); // Mouse x and y position bool isCPressed = MainClass.Config.PrimaryInfoKey.JustPressed(); // For narrating animal details bool isEscPressed = Game1.input.GetKeyboardState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape); // For escaping/unselecting from the animal name text box string toSpeak = " ", details = " "; if (___textBox.Selected) { toSpeak = ___textBox.Text; if (isEscPressed) { ___textBox.Selected = false; } } else { if (isCPressed & !isNarratingAnimalInfo) { string name = ___animal.displayName; string type = ___animal.displayType; int age = (___animal.GetDaysOwned() + 1) / 28 + 1; string ageText = (age <= 1) ? Game1.content.LoadString("Strings\\UI:AnimalQuery_Age1") : Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeN", age); string parent = ""; if ((int)___animal.age.Value < (byte)___animal.ageWhenMature.Value) { ageText += Game1.content.LoadString("Strings\\UI:AnimalQuery_AgeBaby"); } if (___parentName != null) { parent = Game1.content.LoadString("Strings\\UI:AnimalQuery_Parent", ___parentName); } details = $"Name: {name} Type: {type} \n\t Age: {ageText} {parent}"; animalQueryMenuQuery = " "; isNarratingAnimalInfo = true; Task.Delay(200).ContinueWith(_ => { isNarratingAnimalInfo = false; }); } if (__instance.okButton != null && __instance.okButton.containsPoint(x, y)) { toSpeak = "OK button"; } else if (__instance.sellButton != null && __instance.sellButton.containsPoint(x, y)) { toSpeak = $"Sell for {___animal.getSellPrice()}g button"; } else if (___confirmingSell && __instance.yesButton != null && __instance.yesButton.containsPoint(x, y)) { toSpeak = "Confirm selling animal"; } else if (___confirmingSell && __instance.noButton != null && __instance.noButton.containsPoint(x, y)) { toSpeak = "Cancel selling animal"; } else if (__instance.moveHomeButton != null && __instance.moveHomeButton.containsPoint(x, y)) { toSpeak = "Change home building button"; } else if (__instance.allowReproductionButton != null && __instance.allowReproductionButton.containsPoint(x, y)) { toSpeak = ((___animal.allowReproduction.Value) ? "Enabled" : "Disabled") + " allow reproduction button"; } else if (__instance.textBoxCC != null && __instance.textBoxCC.containsPoint(x, y)) { toSpeak = "Animal name text box"; } } if (animalQueryMenuQuery != toSpeak) { animalQueryMenuQuery = toSpeak; MainClass.ScreenReader.Say($"{details} {toSpeak}", true); } } catch (System.Exception e) { MainClass.ErrorLog($"Unable to narrate Text:\n{e.Message}\n{e.StackTrace}"); } }