/// <summary>Apply the mod textures to the given menu, if applicable.</summary> /// <param name="menu">The menu to change.</param> private void ApplyTextures(IClickableMenu menu) { // vanilla menu if (menu is CarpenterMenu carpenterMenu) { if (carpenterMenu.CurrentBlueprint.maxOccupants == this.MaxOccupantsID) { Building building = this.Helper.Reflection.GetField <Building>(carpenterMenu, "currentBuilding").GetValue(); if (building.texture.Value != this.GarageTexture) { building.texture = new Lazy <Texture2D>(() => this.GarageTexture); } } return; } // Farm Expansion & Pelican Fiber menus bool isFarmExpansion = menu.GetType().FullName == this.FarmExpansionMenuFullName; bool isPelicanFiber = !isFarmExpansion && menu.GetType().FullName == this.PelicanFiberMenuFullName; if (isFarmExpansion || isPelicanFiber) { BluePrint currentBlueprint = this.Helper.Reflection.GetProperty <BluePrint>(menu, isFarmExpansion ? "CurrentBlueprint" : "currentBlueprint").GetValue(); if (currentBlueprint.maxOccupants == this.MaxOccupantsID) { Building building = this.Helper.Reflection.GetField <Building>(menu, "currentBuilding").GetValue(); if (building.texture.Value != this.GarageTexture) { building.texture = new Lazy <Texture2D>(() => this.GarageTexture); } } } }
private void Input_ButtonPressed(object sender, ButtonPressedEventArgs e) { if (!Config.EnableMod) return; if (placedSign != null && Game1.activeClickableMenu != null && Game1.player?.currentLocation?.lastQuestionKey?.Equals("CS_Choose_Template") == true) { IClickableMenu menu = Game1.activeClickableMenu; if (menu == null || menu.GetType() != typeof(DialogueBox)) return; DialogueBox db = menu as DialogueBox; int resp = db.selectedResponse; List<Response> resps = db.responses; if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null || resps[resp].responseKey == "cancel") return; Monitor.Log($"Answered {Game1.player.currentLocation.lastQuestionKey} with {resps[resp].responseKey}"); placedSign.modData[templateKey] = resps[resp].responseKey; placedSign = null; } else if (Helper.Input.IsDown(Config.ModKey) && e.Button == Config.ResetKey) { foreach(var pack in loadedContentPacks) { Helper.ConsoleCommands.Trigger("patch", new string[] { "reload", pack }); } ReloadSignData(); Helper.Input.Suppress(Config.ResetKey); } }
private void Input_ButtonPressed(object sender, ButtonPressedEventArgs e) { //Monitor.Log($"last question key: {Game1.player?.currentLocation?.lastQuestionKey}"); if (Context.CanPlayerMove && e.Button == Config.PatioWizardKey && Game1.player?.currentLocation == Game1.getFarm()) { StartWizard(); } else if (Game1.activeClickableMenu != null && Game1.player?.currentLocation?.lastQuestionKey?.StartsWith("CSP_Wizard_Questions") == true && Game1.player?.currentLocation == Game1.getFarm()) { IClickableMenu menu = Game1.activeClickableMenu; if (menu == null || menu.GetType() != typeof(DialogueBox)) { return; } DialogueBox db = menu as DialogueBox; int resp = db.selectedResponse; List <Response> resps = db.responses; if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null) { return; } Monitor.Log($"Answered {Game1.player.currentLocation.lastQuestionKey} with {resps[resp].responseKey}"); CSPWizardDialogue(Game1.player.currentLocation.lastQuestionKey, resps[resp].responseKey); return; } }
public static void onUpdate(object sender, EventArgs args) { try { if (Multiplayer.mode != Mode.Singleplayer) { Multiplayer.update(); } // We need our load menu to be able to do things if (Game1.activeClickableMenu is TitleMenu) { TitleMenu title = (TitleMenu)Game1.activeClickableMenu; if (DEBUG) { Util.SetInstanceField(typeof(TitleMenu), title, "chuckleFishTimer", 0); Util.SetInstanceField(typeof(TitleMenu), title, "logoFadeTimer", 0); Util.SetInstanceField(typeof(TitleMenu), title, "fadeFromWhiteTimer", 0); } IClickableMenu submenu = (IClickableMenu)Util.GetInstanceField(typeof(TitleMenu), title, "subMenu"); if (submenu != null && submenu.GetType() == typeof(LoadGameMenu)) { Util.SetInstanceField(typeof(TitleMenu), title, "subMenu", new NewLoadMenu()); } } prevMenu = Game1.activeClickableMenu; } catch (Exception e) { Log.Async("Exception during update: " + e); } }
private void OnMenuChanged(object s, EventArgsClickableMenuChanged e) { if (e.NewMenu?.GetType().FullName != "CJBItemSpawner.ItemMenu") { return; } Log.Trace("Overriding CJB Item Spawner menu items..."); CurrentMenu = e.NewMenu; var itemListField = _itemListField ?? (_itemListField = CurrentMenu.GetType().GetInstanceField("itemList")); var itemList = CurrentMenu.GetFieldValue <List <Item> >(itemListField); for (var i = 0; i < itemList.Count; ++i) { var item = itemList[i] as Object; if (item == null) { continue; } itemList[i] = Wrapper.Instance.Wrap(item); } var loadInventoryMethod = _loadInventoryMethod ?? (_loadInventoryMethod = CurrentMenu.GetType().GetInstanceMethod("loadInventory")); loadInventoryMethod.Invoke(CurrentMenu, null); Log.Trace("Overrided CJB Item Spawner menu items."); }
/// <summary>Get the hovered item from an arbitrary menu.</summary> /// <param name="menu">The menu whose hovered item to find.</param> private Item GetItemFromMenu(IClickableMenu menu) { // game menu if (menu is GameMenu gameMenu) { IClickableMenu page = this.Helper.Reflection.GetField <List <IClickableMenu> >(gameMenu, "pages").GetValue()[gameMenu.currentTab]; if (page is InventoryPage) { return(this.Helper.Reflection.GetField <Item>(page, "hoveredItem").GetValue()); } else if (page is CraftingPage) { return(this.Helper.Reflection.GetField <Item>(page, "hoverItem").GetValue()); } } // from inventory UI else if (menu is MenuWithInventory inventoryMenu) { return(inventoryMenu.hoveredItem); } // CJB mods else if (menu.GetType().FullName == "CJBItemSpawner.ItemMenu") { return(this.Helper.Reflection.GetField <Item>(menu, "HoveredItem").GetValue()); } return(null); }
private static void Input_ButtonPressed(object sender, StardewModdingAPI.Events.ButtonPressedEventArgs e) { if (Game1.activeClickableMenu != null && Game1.player.currentLocation is MineShaft && Game1.player.currentLocation.lastQuestionKey == "UndergroundSecrets_Question") { IClickableMenu menu = Game1.activeClickableMenu; if (menu == null || menu.GetType() != typeof(DialogueBox)) { return; } DialogueBox db = menu as DialogueBox; int resp = db.selectedResponse; List <Response> resps = db.responses; if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null) { return; } Game1.player.currentLocation.lastQuestionKey = ""; helper.Events.Input.ButtonPressed -= Input_ButtonPressed; AnswerResult(resps[resp].responseKey); return; } }
private static void Events_MenuChanged(IClickableMenu newMenu) { Log.AsyncY("NEW MENU: " + newMenu.GetType()); if (newMenu is GameMenu) { Game1.activeClickableMenu = SGameMenu.ConstructFromBaseClass(Game1.activeClickableMenu as GameMenu); } }
/// <inheritdoc cref="IGameLoopEvents.UpdateTicked"/> /// <param name="sender">The event sender.</param> /// <param name="e">The event data.</param> private void OnUpdateTicked(object?sender, UpdateTickedEventArgs e) { if (!this.IsEnabled) { return; } // multiplayer: override textures in the current location if (Context.IsWorldReady && Game1.currentLocation != null) { uint updateRate = Game1.currentLocation.farmers.Count > 1 ? this.TextureUpdateRateWithMultiplePlayers : this.TextureUpdateRateWithSinglePlayer; if (e.IsMultipleOf(updateRate)) { foreach (Horse horse in this.GetTractorsIn(Game1.currentLocation)) { this.TextureManager.ApplyTextures(horse, this.IsTractor); } foreach (Stable stable in this.GetGaragesIn(Game1.currentLocation)) { this.TextureManager.ApplyTextures(stable, this.IsGarage); } } } // override blueprint texture if (Game1.activeClickableMenu != null) { IClickableMenu menu = Game1.activeClickableMenu; bool isFarmExpansion = menu.GetType().FullName == this.FarmExpansionMenuFullName; bool isPelicanFiber = !isFarmExpansion && menu.GetType().FullName == this.PelicanFiberMenuFullName; this.TextureManager.ApplyTextures( menu: menu, isFarmExpansion: isFarmExpansion, isPelicanFiber: isPelicanFiber, isGarage: blueprint => blueprint.maxOccupants == this.MaxOccupantsID, reflection: this.Helper.Reflection ); } // update tractor effects if (Context.IsPlayerFree) { this.TractorManager.Update(); } }
private void OnClickableMenuClosed(IClickableMenu priorMenu) { Utils.DebugLog(previousMenu.GetType().ToString() + " menu closed."); if (currentGiftHelper != null) { Utils.DebugLog("[OnClickableMenuClosed] Closing current helper: " + currentGiftHelper.GetType().ToString()); UnsubscribeEvents(); currentGiftHelper.OnClose(); } }
private bool IsCookingMenu(IClickableMenu menu) { if (_farmHouse == null || _farmHouse.upgradeLevel == 0) { return(false); } if (menu is CraftingPage) { return(true); } if (_isCookingSkillLoaded && menu.GetType() == Type.GetType("CookingSkill.NewCraftingPage, CookingSkill")) { return(true); } return(false); }
private void DebugPrintMenuInfo(IClickableMenu priorMenu, IClickableMenu newMenu) { #if DEBUG try { string priorName = "None"; if (priorMenu != null) { priorName = priorMenu.GetType().Name; } string newName = newMenu.GetType().Name; Utils.DebugLog("Menu changed from: " + priorName + " to " + newName); } catch (Exception ex) { Utils.DebugLog("Error getting menu name: " + ex); } #endif }
public static bool Prefix_changeShirt(Farmer __instance, int whichShirt) { try { if (Game1.activeClickableMenu is TitleMenu) { IClickableMenu sub = (IClickableMenu)typeof(TitleMenu).GetField("_subMenu", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); string submenu = sub == null ? "null" : sub.GetType().ToString().ToLower(); if (!submenu.Contains("character")) { return(true); } } int max = CustomShirtsMod.vanillaShirts.Height / 32 * (CustomShirtsMod.vanillaShirts.Width / 8) - 1; if (whichShirt >= 0 && whichShirt <= max) { return(true); } if (whichShirt > 0) { whichShirt = -1 * ((CustomShirtsMod.shirts.Count + (max - whichShirt)) + 1); } if (whichShirt * -1 > CustomShirtsMod.shirts.Count) { return(true); } __instance.shirt.Set(whichShirt); __instance.FarmerRenderer.changeShirt(whichShirt); CustomShirtsMod.recolor = true; return(false); } catch { return(true); } }
private static void Input_ButtonPressed(object sender, StardewModdingAPI.Events.ButtonPressedEventArgs e) { if (Game1.activeClickableMenu != null && Game1.player.currentLocation is MineShaft && Game1.player.currentLocation.lastQuestionKey == "UndergroundSecrets_Question") { IClickableMenu menu = Game1.activeClickableMenu; if (menu == null || menu.GetType() != typeof(DialogueBox)) { return; } int resp = (int)typeof(DialogueBox).GetField("selectedResponse", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); List <Response> resps = (List <Response>) typeof(DialogueBox).GetField("responses", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null) { return; } Game1.player.currentLocation.lastQuestionKey = ""; helper.Events.Input.ButtonPressed -= Input_ButtonPressed; AnswerResult(resps[resp].responseKey); return; } }
public static void Input_ButtonPressed(object sender, ButtonPressedEventArgs e) { if (Game1.player == null || Game1.player.currentLocation == null) { ModEntry.myButtonDown = false; return; } if (false && e.Button == SButton.Q) { SwimUtils.SeaMonsterSay("The quick brown fox jumped over the slow lazy dog."); } if (Game1.activeClickableMenu != null && Game1.player.currentLocation.Name == "ScubaCrystalCave" && Game1.player.currentLocation.lastQuestionKey.StartsWith("SwimMod_Mariner_")) { IClickableMenu menu = Game1.activeClickableMenu; if (menu == null || menu.GetType() != typeof(DialogueBox)) { return; } int resp = (int)typeof(DialogueBox).GetField("selectedResponse", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); List <Response> resps = (List <Response>) typeof(DialogueBox).GetField("responses", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null) { return; } Game1.player.currentLocation.lastQuestionKey = ""; SwimDialog.OldMarinerDialogue(resps[resp].responseKey); return; } if (false && e.Button == SButton.Q) { var v1 = Game1.game1; return; //Game1.player.currentLocation.overlayObjects[Game1.player.getTileLocation() + new Vector2(0, 1)] = new Chest(0, new List<Item>() { Helper.Input.IsDown(SButton.LeftShift) ? (Item)(new StardewValley.Object(434, 1)) : (new Hat(ModEntry.scubaMaskID)) }, Game1.player.getTileLocation() + new Vector2(0, 1), false, 0); } if (e.Button == Config.DiveKey && ModEntry.diveMaps.ContainsKey(Game1.player.currentLocation.Name) && ModEntry.diveMaps[Game1.player.currentLocation.Name].DiveLocations.Count > 0) { Point pos = Game1.player.getTileLocationPoint(); Location loc = new Location(pos.X, pos.Y); if (!SwimUtils.IsInWater()) { return; } DiveMap dm = ModEntry.diveMaps[Game1.player.currentLocation.Name]; DiveLocation diveLocation = null; foreach (DiveLocation dl in dm.DiveLocations) { if (dl.GetRectangle().X == -1 || dl.GetRectangle().Contains(loc)) { diveLocation = dl; break; } } if (diveLocation == null) { Monitor.Log($"No dive destination for this point on this map", LogLevel.Debug); return; } if (Game1.getLocationFromName(diveLocation.OtherMapName) == null) { Monitor.Log($"Can't find destination map named {diveLocation.OtherMapName}", LogLevel.Warn); return; } Monitor.Log($"warping to {diveLocation.OtherMapName}", LogLevel.Debug); SwimUtils.DiveTo(diveLocation); return; } if (e.Button == Config.SwimKey && (!Game1.player.swimming || !Config.ReadyToSwim) && !isJumping) { Config.ReadyToSwim = !Config.ReadyToSwim; Helper.WriteConfig <ModConfig>(Config); Monitor.Log($"Ready to swim: {Config.ReadyToSwim}"); return; } if (e.Button == Config.SwimSuitKey) { Config.SwimSuitAlways = !Config.SwimSuitAlways; Helper.WriteConfig <ModConfig>(Config); if (!Game1.player.swimming) { if (!Config.SwimSuitAlways) { Game1.player.changeOutOfSwimSuit(); } else { Game1.player.changeIntoSwimsuit(); } } return; } }
private void Input_ButtonPressed(object sender, StardewModdingAPI.Events.ButtonPressedEventArgs e) { if (!Config.Enabled || !Context.IsWorldReady) { return; } Dictionary <string, string> npcDic; List <string> npcKeys; // check for click on dialogue if (Game1.activeClickableMenu != null && Game1.player?.currentLocation?.lastQuestionKey?.StartsWith("DialogueTrees_") == true) { IClickableMenu menu = Game1.activeClickableMenu; if (menu == null || menu.GetType() != typeof(DialogueBox)) { return; } DialogueBox db = menu as DialogueBox; int resp = db.selectedResponse; List <Response> resps = db.responses; if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null) { return; } string[] parts = resps[resp].responseKey.Split('#'); string npcName = parts[1]; string topicID = parts[2]; string responseID = parts[3]; npcDic = Helper.Content.Load <Dictionary <string, string> >($"Characters/Dialogue/{npcName}", ContentSource.GameContent); npcKeys = npcDic.Keys.ToList(); if (Game1.player.currentLocation.lastQuestionKey == "DialogueTrees_Player_Question") { Monitor.Log($"asking {npcName} about {loadedTopicNames[topicID]}"); var possibleResponses = npcKeys.FindAll(k => k.StartsWith("DialogueTrees_response_" + topicID + "_")); NPC n = Game1.getCharacterFromName(npcName); Game1.drawDialogue(n, npcDic[possibleResponses[myRand.Next(possibleResponses.Count)]]); string nextTopicID = GetNextTopicID(topicID, "any"); if (nextTopicID != null && loadedDialogues.ContainsKey(nextTopicID) && npcKeys.Exists(k => k.StartsWith("DialogueTrees_response_" + nextTopicID + "_"))) { if (responseData != null) { responseData.lastTopic = loadedDialogues[topicID]; responseData.nextTopic = loadedDialogues[nextTopicID]; responseData.npc = n; responseData.topicResponses[topicID] = responseID; } else { responseData = new DialogueTreeResponse(loadedDialogues[topicID], loadedDialogues[nextTopicID], n, responseID); } } } else if (Game1.player.currentLocation.lastQuestionKey == "DialogueTrees_NPC_Question") { Monitor.Log($"{npcName} is asking player about {loadedTopicNames[topicID]}, player response: {loadedResponseStrings[responseID]}"); var possibleReactions = npcKeys.FindAll(k => k.StartsWith("DialogueTrees_reaction_" + topicID + "_" + responseID + "_")); if (!possibleReactions.Any()) { Monitor.Log($"{npcName} has no reaction to {loadedTopicNames[topicID]} response {loadedResponseStrings[responseID]}! Check the [DT] content pack.", LogLevel.Warn); } else { NPC n = Game1.getCharacterFromName(npcName); Game1.drawDialogue(n, npcDic[possibleReactions[myRand.Next(possibleReactions.Count)]]); if (npcDic.ContainsKey("DialogueTrees_friendship_" + topicID + "_" + responseID) && int.TryParse(npcDic["DialogueTrees_friendship_" + topicID + "_" + responseID], out int amount)) { Monitor.Log($"changing friendship with {n.Name} by {amount}"); Game1.player.changeFriendship(amount, n); } string nextTopicID = GetNextTopicID(topicID, responseID); if (nextTopicID != null && loadedDialogues.ContainsKey(nextTopicID)) { Monitor.Log($"Preparing followup dialogue {nextTopicID}"); if (responseData != null) { Monitor.Log($"Adding to existing responseData"); responseData.lastTopic = loadedDialogues[topicID]; responseData.nextTopic = loadedDialogues[nextTopicID]; responseData.npc = n; responseData.topicResponses[topicID] = responseID; } else { responseData = new DialogueTreeResponse(loadedDialogues[topicID], loadedDialogues[nextTopicID], n, responseID); } } else { if (responseData != null) { Monitor.Log("No next topic, erasing response data"); } responseData = null; } } } Game1.player.currentLocation.lastQuestionKey = ""; return; } // check for click on NPC if (Game1.activeClickableMenu != null || !Context.CanPlayerMove || (Config.ModButton != SButton.None && !Helper.Input.IsDown(Config.ModButton)) || (e.Button != Config.AskButton && e.Button != Config.AnswerButton)) { return; } Monitor.Log($"Pressed modkey + {e.Button}"); Rectangle tileRect = new Rectangle((int)Game1.currentCursorTile.X * 64, (int)Game1.currentCursorTile.Y * 64, 64, 64); NPC npc = null; foreach (NPC i in Game1.currentLocation.characters) { if (i != null && !i.IsMonster && (!Game1.player.isRidingHorse() || !(i is Horse)) && i.GetBoundingBox().Intersects(tileRect) && !i.IsInvisible && !i.checkAction(Game1.player, Game1.currentLocation)) { npc = i; break; } } if (npc == null) { return; } try { npcDic = Helper.Content.Load <Dictionary <string, string> >($"Characters/Dialogue/{npc.Name}", ContentSource.GameContent); } catch { Monitor.Log($"No dialogue file for {npc.Name}", LogLevel.Warn); return; } npcKeys = npcDic.Keys.ToList(); if (e.Button == Config.AskButton) { Monitor.Log($"Asking question of {npc.Name}"); var shuffled = loadedDialogues.Values.ToList().FindAll(d => d.isStarter && d.playerCanAsk && npcKeys.Exists(k => k.StartsWith("DialogueTrees_response_" + d.topicID + "_"))); if (!shuffled.Any()) { Monitor.Log($"No questions that {npc.Name} has a response to! Check the [DT] content pack.", LogLevel.Warn); return; } Monitor.Log($"{shuffled.Count} questions that {npc.Name} has a response to."); ShuffleList(shuffled); var questions = shuffled.Take(Config.MaxPlayerQuestions); List <Response> responses = new List <Response>(); foreach (var q in questions) { Monitor.Log(q.topicID); responses.Add(new Response($"DialogueTrees_Response#{npc.Name}#{q.topicID}", string.Format(loadedQuestionStrings[q.questionIDs[myRand.Next(q.questionIDs.Count)]], loadedTopicNames[q.topicID]))); } Game1.player.currentLocation.createQuestionDialogue(string.Format(Helper.Translation.Get("ask-npc"), npc.Name), responses.ToArray(), "DialogueTrees_Player_Question"); } else if (e.Button == Config.AnswerButton) { Monitor.Log($"Answering {npc.Name}'s question"); var possibleQuestions = loadedDialogues.Values.ToList().FindAll(d => d.isStarter && npcKeys.Exists(k => k.StartsWith("DialogueTrees_reaction_" + d.topicID + "_"))); if (!possibleQuestions.Any()) { Monitor.Log($"No questions that {npc.Name} can ask (no reactions)! Check the [DT] content pack.", LogLevel.Warn); return; } DialogueTree p = possibleQuestions[myRand.Next(possibleQuestions.Count)]; Monitor.Log($"Asking about {loadedTopicNames[p.topicID]}"); List <Response> responses = new List <Response>(); foreach (var r in p.responseIDs) { Monitor.Log(r); responses.Add(new Response($"DialogueTrees_Response#{npc.Name}#{p.topicID}#{r}", string.Format(loadedResponseStrings[r], loadedTopicNames[p.topicID]))); } string qid = p.questionIDs[myRand.Next(p.questionIDs.Count)]; List <string> possibleQuestionStrings = npcDic.Keys.ToList().FindAll(k => k.StartsWith("DialogueTrees_question_" + qid + "_")); string questionString = possibleQuestionStrings.Any() ? npcDic[possibleQuestionStrings[myRand.Next(possibleQuestionStrings.Count)]] : loadedQuestionStrings[qid]; Game1.player.currentLocation.createQuestionDialogue(string.Format(questionString, loadedTopicNames[p.topicID]), responses.ToArray(), "DialogueTrees_NPC_Question"); Game1.objectDialoguePortraitPerson = npc; } }
public static object SerializeMenu(IClickableMenu menu, Point mousePosition) { dynamic serialized = Menus.SerializeMenu(menu, mousePosition); if (serialized != null) { return(serialized); } if (menu == null) { return(null); } Rectangle menuRect = new Rectangle(menu.xPositionOnScreen, menu.yPositionOnScreen, menu.width, menu.height); bool containsMouse = menu.isWithinBounds(mousePosition.X, mousePosition.Y); var menuBarObj = new { menu.xPositionOnScreen, menu.yPositionOnScreen, upperRightCloseButton = Utils.SerializeClickableCmp(menu.upperRightCloseButton, mousePosition), containsMouse, menuType = "unknown", classType = menu.GetType().ToString(), }; dynamic menuTypeObj = new { }; if (menu is ShopMenu) { var sm = menu as ShopMenu; var forSale = sm.forSale.Select(x => Utils.SerializeItem((Item)x)); var forSaleButtons = Utils.SerializeComponentList(sm.forSaleButtons, mousePosition); menuTypeObj = new { menuType = "shopMenu", forSale, forSaleButtons, sm.currentItemIndex, inventory = SerializeMenu(sm.inventory), upArrow = SerializeClickableCmp(sm.upArrow, mousePosition), downArrow = SerializeClickableCmp(sm.downArrow, mousePosition), scrollBar = SerializeClickableCmp(sm.scrollBar, mousePosition), }; } else if (menu is ProfileMenu) { var pm = menu as ProfileMenu; var clickableProfileItems = Utils.SerializeComponentList(pm.clickableProfileItems, mousePosition); menuTypeObj = new { menuType = "profileMenu", backButton = Utils.SerializeClickableCmp(pm.backButton, mousePosition), forwardButton = Utils.SerializeClickableCmp(pm.forwardButton, mousePosition), previousCharacterButton = Utils.SerializeClickableCmp(pm.previousCharacterButton, mousePosition), nextCharacterButton = Utils.SerializeClickableCmp(pm.nextCharacterButton, mousePosition), clickableProfileItems, upArrow = SerializeClickableCmp(pm.upArrow, mousePosition), downArrow = SerializeClickableCmp(pm.downArrow, mousePosition), }; } else if (menu is DialogueBox) { var db = menu as DialogueBox; var responseCC = SerializeComponentList(db.responseCC, mousePosition); var responses = db.responses.Select(x => new { x.responseKey, x.responseText, x.hotkey }).ToList(); menuTypeObj = new { menuType = "dialogueBox", responseCC, responses, }; } else if (menu is CoopMenu) { var cb = menu as CoopMenu; var slotButtons = SerializeComponentList(cb.slotButtons, mousePosition); String currentTab = Utils.GetPrivateField(cb, "currentTab").ToString(); menuTypeObj = new { menuType = "coopMenu", downArrow = SerializeClickableCmp(cb.downArrow, mousePosition), hostTab = SerializeClickableCmp(cb.hostTab, mousePosition), joinTab = SerializeClickableCmp(cb.joinTab, mousePosition), refreshButton = SerializeClickableCmp(cb.refreshButton, mousePosition), upArrow = SerializeClickableCmp(cb.upArrow, mousePosition), slotButtons, currentTab, }; if (currentTab == "JOIN_TAB") { } else if (currentTab == "HOST_TAB") { } } else if (menu is TitleTextInputMenu) { var ttim = menu as TitleTextInputMenu; menuTypeObj = new { menuType = "titleTextInputMenu", doneNamingButton = SerializeClickableCmp(ttim.doneNamingButton, mousePosition), pasteButton = SerializeClickableCmp(ttim.pasteButton, mousePosition), textBoxCC = SerializeClickableCmp(ttim.textBoxCC, mousePosition), }; } else if (menu is AnimalQueryMenu) { var aqm = menu as AnimalQueryMenu; bool movingAnimal = (bool)Utils.GetPrivateField(aqm, "movingAnimal"); menuTypeObj = new { menuType = "animalQueryMenu", movingAnimal, }; if (movingAnimal) { var vt = VisibleTiles(Game1.getFarm()); var tileComponents = vt.Select(t => TileToClickableComponent(t[0], t[1], mousePosition)).ToList(); var okButton = SerializeClickableCmp(aqm.okButton, mousePosition); menuTypeObj = Merge(menuTypeObj, new { tileComponents, okButton }); } else { bool confirmingSell = (bool)Utils.GetPrivateField(aqm, "confirmingSell"); if (confirmingSell) { var noButton = SerializeClickableCmp(aqm.noButton, mousePosition); var yesButton = SerializeClickableCmp(aqm.yesButton, mousePosition); menuTypeObj = Merge(menuTypeObj, new { yesButton, noButton }); } else { menuTypeObj = Merge(menuTypeObj, new { allowReproductionButton = SerializeClickableCmp(aqm.allowReproductionButton, mousePosition), sellButton = SerializeClickableCmp(aqm.sellButton, mousePosition), textBoxCC = SerializeClickableCmp(aqm.textBoxCC, mousePosition), moveHomeButton = SerializeClickableCmp(aqm.moveHomeButton, mousePosition), okButton = SerializeClickableCmp(aqm.okButton, mousePosition), }); } } } else if (menu is MineElevatorMenu) { var mem = menu as MineElevatorMenu; var elevators = SerializeComponentList(mem.elevators, mousePosition); menuTypeObj = new { menuType = "mineElevatorMenu", elevators, }; } else if (menu is LetterViewerMenu) { var lvm = menu as LetterViewerMenu; var itemsToGrab = SerializeComponentList(lvm.itemsToGrab, mousePosition); var acceptQuestButton = SerializeClickableCmp(lvm.acceptQuestButton, mousePosition); var backButton = SerializeClickableCmp(lvm.backButton, mousePosition); var forwardButton = SerializeClickableCmp(lvm.forwardButton, mousePosition); menuTypeObj = new { menuType = "letterViewerMenu", acceptQuestButton, backButton, forwardButton, itemsToGrab, }; } else if (menu is InventoryMenu) { var im = menu as InventoryMenu; menuTypeObj = new { menuType = "inventoryMenu", inventory = SerializeComponentList(im.inventory, mousePosition), im.rows, im.capacity, }; } else if (menu is CarpenterMenu) { var cm = menu as CarpenterMenu; bool onFarm = (bool)Utils.GetPrivateField(cm, "onFarm"); menuTypeObj = new { menuType = "carpenterMenu", cancelButton = SerializeClickableCmp(cm.cancelButton, mousePosition), onFarm, }; if (onFarm) { var vt = VisibleTiles(Game1.getFarm()); var tileComponents = vt.Select(t => TileToClickableComponent(t[0], t[1], mousePosition)).ToList(); menuTypeObj = Merge(menuTypeObj, new { tileComponents }); } else { menuTypeObj = Merge(menuTypeObj, new { backButton = SerializeClickableCmp(cm.backButton, mousePosition), demolishButton = SerializeClickableCmp(cm.demolishButton, mousePosition), forwardButton = SerializeClickableCmp(cm.forwardButton, mousePosition), moveButton = SerializeClickableCmp(cm.moveButton, mousePosition), okButton = SerializeClickableCmp(cm.okButton, mousePosition), paintButton = SerializeClickableCmp(cm.paintButton, mousePosition), upgradeIcon = SerializeClickableCmp(cm.upgradeIcon, mousePosition), }); } } else if (menu is TitleMenu) { var tm = menu as TitleMenu; menuTypeObj = new { menuType = "titleMenu", windowedButton = SerializeClickableCmp(tm.windowedButton, mousePosition), }; if (TitleMenu.subMenu != null) { bool addBackButton = tm.backButton != null && !(TitleMenu.subMenu is CharacterCustomization && !TitleMenu.subMenu.readyToClose()); dynamic backButton = addBackButton ? SerializeClickableCmp(tm.backButton, mousePosition) : null; var subMenu = Merge(SerializeMenu(TitleMenu.subMenu), new { backButton }); menuTypeObj = Merge(menuTypeObj, new { subMenu }); } else { dynamic subMenu = null; menuTypeObj = Merge(menuTypeObj, new { subMenu, buttons = SerializeComponentList(tm.buttons, mousePosition), languageButton = SerializeClickableCmp(tm.languageButton, mousePosition), aboutButton = SerializeClickableCmp(tm.aboutButton, mousePosition), muteMusicButton = SerializeClickableCmp(tm.muteMusicButton, mousePosition), }); } } else if (menu is CharacterCustomization) { var ccm = menu as CharacterCustomization; menuTypeObj = new { menuType = "characterCustomizationMenu", }; if (ccm.showingCoopHelp) { menuTypeObj = Merge(menuTypeObj, new { okButton = SerializeClickableCmp(ccm.coopHelpOkButton, mousePosition), coopHelpLeftButton = SerializeClickableCmp(ccm.coopHelpLeftButton, mousePosition), coopHelpRightButton = SerializeClickableCmp(ccm.coopHelpRightButton, mousePosition), }); } else { menuTypeObj = Merge(menuTypeObj, new { advancedOptionsButton = SerializeClickableCmp(ccm.advancedOptionsButton, mousePosition), backButton = SerializeClickableCmp(ccm.backButton, mousePosition), cabinLayoutButtons = SerializeComponentList(ccm.cabinLayoutButtons, mousePosition), coopHelpButton = SerializeClickableCmp(ccm.coopHelpButton, mousePosition), farmTypeButtons = SerializeComponentList(ccm.farmTypeButtons, mousePosition), favThingBoxCC = SerializeClickableCmp(ccm.favThingBoxCC, mousePosition), farmnameBoxCC = SerializeClickableCmp(ccm.farmnameBoxCC, mousePosition), genderButtons = SerializeComponentList(ccm.genderButtons, mousePosition), leftSelectionButtons = SerializeComponentList(ccm.leftSelectionButtons, mousePosition), nameBoxCC = SerializeClickableCmp(ccm.nameBoxCC, mousePosition), okButton = SerializeClickableCmp(ccm.okButton, mousePosition), petButtons = SerializeComponentList(ccm.petButtons, mousePosition), randomButton = SerializeClickableCmp(ccm.randomButton, mousePosition), rightSelectionButtons = SerializeComponentList(ccm.rightSelectionButtons, mousePosition), skipIntroButton = SerializeClickableCmp(ccm.skipIntroButton, mousePosition), }); } } else if (menu is QuestLog) { var qlm = menu as QuestLog; StardewValley.Quests.IQuest shownQuest = GetPrivateField(qlm, "_shownQuest"); int currentPage = GetPrivateField(qlm, "currentPage"); int questPage = GetPrivateField(qlm, "questPage"); float contentHeight = GetPrivateField(qlm, "_contentHeight"); float scissorRectHeight = GetPrivateField(qlm, "_scissorRectHeight"); float scrollAmount = GetPrivateField(qlm, "scrollAmount"); List <List <StardewValley.Quests.IQuest> > pages = GetPrivateField(qlm, "pages"); menuTypeObj = new { menuType = "questLogMenu" }; if (questPage == -1) { if (pages.Count > 0 && pages[currentPage].Count > 0) { menuTypeObj = Merge(menuTypeObj, new { questLogButtons = SerializeComponentList(qlm.questLogButtons, mousePosition) }); } if (currentPage < pages.Count - 1) { menuTypeObj = Merge(menuTypeObj, new { forwardButton = SerializeClickableCmp(qlm.forwardButton, mousePosition) }); } if (currentPage > 0) { menuTypeObj = Merge(menuTypeObj, new { backButton = SerializeClickableCmp(qlm.backButton, mousePosition) }); } } else { var quest = shownQuest as StardewValley.Quests.Quest; bool needsScroll = qlm.NeedsScroll(); if (questPage != -1 && shownQuest.ShouldDisplayAsComplete() && shownQuest.HasMoneyReward()) { menuTypeObj = Merge(menuTypeObj, new { rewardBox = SerializeClickableCmp(qlm.rewardBox, mousePosition) }); } if (questPage != -1 && quest != null && !quest.completed && (bool)quest.canBeCancelled) { menuTypeObj = Merge(menuTypeObj, new { cancelQuestButton = SerializeClickableCmp(qlm.cancelQuestButton, mousePosition) }); } if (needsScroll) { if (scrollAmount < contentHeight - scissorRectHeight) { menuTypeObj = Merge(menuTypeObj, new { downArrow = SerializeClickableCmp(qlm.downArrow, mousePosition) }); } else if (scrollAmount > 0f) { menuTypeObj = Merge(menuTypeObj, new { upArrow = SerializeClickableCmp(qlm.upArrow, mousePosition) }); } } else { menuTypeObj = Merge(menuTypeObj, new { backButton = SerializeClickableCmp(qlm.backButton, mousePosition) }); } } //backButton = SerializeClickableCmp(qlm.backButton, mousePosition), //downArrow = SerializeClickableCmp(qlm.downArrow, mousePosition), //forwardButton = SerializeClickableCmp(qlm.forwardButton, mousePosition), //questLogButtons = SerializeComponentList(qlm.questLogButtons, mousePosition), //upArrow = SerializeClickableCmp(qlm.upArrow, mousePosition), //rewardBox = SerializeClickableCmp(qlm.rewardBox, mousePosition), } else if (menu is LanguageSelectionMenu) { var lsm = menu as LanguageSelectionMenu; menuTypeObj = new { menuType = "languageSelectionMenu", languages = SerializeComponentList(lsm.languages, mousePosition), }; } else if (menu is LevelUpMenu) { var lum = menu as LevelUpMenu; menuTypeObj = new { menuType = "levelUpMenu", }; if (lum.isProfessionChooser) { menuTypeObj = Merge(menuTypeObj, new { leftProfession = SerializeClickableCmp(lum.leftProfession, mousePosition), rightProfession = SerializeClickableCmp(lum.rightProfession, mousePosition), }); } else { menuTypeObj = Merge(menuTypeObj, new { okButton = SerializeClickableCmp(lum.okButton, mousePosition) }); } } else if (menu is LoadGameMenu) { var lgm = menu as LoadGameMenu; int currentItemIndex = (int)GetPrivateField(lgm, "currentItemIndex"); menuTypeObj = new { menuType = "loadGameMenu", currentItemIndex, lgm.deleteConfirmationScreen, }; if (lgm.deleteConfirmationScreen) { menuTypeObj = Utils.Merge(menuTypeObj, new { cancelDeleteButton = SerializeClickableCmp(lgm.cancelDeleteButton, mousePosition), okDeleteButton = SerializeClickableCmp(lgm.okDeleteButton, mousePosition), }); } else { menuTypeObj = Utils.Merge(menuTypeObj, new { deleteButtons = SerializeComponentList(lgm.deleteButtons, mousePosition), slotButtons = SerializeComponentList(lgm.slotButtons, mousePosition), upArrow = SerializeClickableCmp(lgm.upArrow, mousePosition), downArrow = SerializeClickableCmp(lgm.downArrow, mousePosition), }); } } else if (menu is Billboard) { var bb = menu as Billboard; bool dailyQuestBoard = Utils.GetPrivateField(bb, "dailyQuestBoard"); menuTypeObj = new { menuType = "billboard" }; if (dailyQuestBoard) { menuTypeObj = Merge(menuTypeObj, new { acceptQuestButton = SerializeClickableCmp(bb.acceptQuestButton, mousePosition) }); } else { menuTypeObj = Merge(menuTypeObj, new { calendarDays = SerializeComponentList(bb.calendarDays, mousePosition) }); } } else if (menu is LevelUpMenu) { var lum = menu as LevelUpMenu; menuTypeObj = new { menuType = "levelUpMenu", okButton = SerializeClickableCmp(lum.okButton, mousePosition), rightProfession = SerializeClickableCmp(lum.rightProfession, mousePosition), leftProfession = SerializeClickableCmp(lum.leftProfession, mousePosition), lum.isProfessionChooser }; } else if (menu is MuseumMenu) { var mm = menu as MuseumMenu; var location = Game1.currentLocation as StardewValley.Locations.LibraryMuseum; var museumPieceTileComponents = from t in VisibleTiles(location) where location.museumPieces.ContainsKey(new Vector2(t[0], t[1])) || location.isTileSuitableForMuseumPiece(t[0], t[1]) select TileToClickableComponent(t[0], t[1], mousePosition); var inventoryRect = new Rectangle(mm.inventory.xPositionOnScreen, mm.inventory.yPositionOnScreen, mm.inventory.width, mm.inventory.height); var clickableTileComponents = museumPieceTileComponents.Where(x => !x.rect.Intersects(inventoryRect)).ToList(); menuTypeObj = new { menuType = "museumMenu", okButton = SerializeClickableCmp(mm.okButton, mousePosition), clickableTileComponents, inventory = SerializeMenu(mm.inventory), trashCan = SerializeClickableCmp(mm.trashCan, mousePosition), }; } else if (menu is GeodeMenu) { var gm = menu as GeodeMenu; menuTypeObj = new { menuType = "geodeMenu", okButton = SerializeClickableCmp(gm.okButton, mousePosition), geodeSpot = SerializeClickableCmp(gm.geodeSpot, mousePosition), inventory = SerializeMenu(gm.inventory), trashCan = SerializeClickableCmp(gm.trashCan, mousePosition), }; } return(Utils.Merge(menuBarObj, menuTypeObj)); }
private void Input_ButtonPressed(object sender, ButtonPressedEventArgs e) { if ((e.Button != SButton.MouseLeft && e.Button != SButton.MouseRight) || Game1.currentLocation == null || !(Game1.currentLocation is ManorHouse) || !Game1.currentLocation.lastQuestionKey.StartsWith("divorce")) { return; } IClickableMenu menu = Game1.activeClickableMenu; if (menu == null || menu.GetType() != typeof(DialogueBox)) { return; } int resp = (int)typeof(DialogueBox).GetField("selectedResponse", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); List <Response> resps = (List <Response>) typeof(DialogueBox).GetField("responses", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null) { return; } string whichAnswer = resps[resp].responseKey; Game1.currentLocation.lastQuestionKey = ""; PMonitor.Log("answer " + whichAnswer); if (whichAnswer == "Yes") { if (Game1.player.Money >= 50000 || Game1.player.spouse == "Krobus") { if (!Game1.player.isRoommate(Game1.player.spouse)) { Game1.player.Money -= 50000; } Game1.player.divorceTonight.Value = true; string s = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Filed_" + Game1.player.spouse); if (s == null) { s = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Filed"); } Game1.drawObjectDialogue(s); if (!Game1.player.isRoommate(Game1.player.spouse)) { mp.globalChatInfoMessage("Divorce", new string[] { Game1.player.Name }); } } else { Game1.drawObjectDialogue(Game1.content.LoadString("Strings\\UI:NotEnoughMoney1")); } } else if (whichAnswer == "Complex") { heartsLost = 1; ShowNextDialogue("divorce_fault_", Game1.currentLocation); } else if (whichAnswer.StartsWith("divorce_fault_")) { PMonitor.Log("divorce fault"); string r = PHelper.Translation.Get(whichAnswer); if (r != null) { if (int.TryParse(r.Split('#')[r.Split('#').Length - 1], out int lost)) { heartsLost += lost; } } string nextKey = $"divorce_{r.Split('#')[r.Split('#').Length - 2]}reason_"; Translation test = PHelper.Translation.Get(nextKey + "q"); if (!test.HasValue()) { ShowNextDialogue($"divorce_method_", Game1.currentLocation); return; } ShowNextDialogue($"divorce_{r.Split('#')[r.Split('#').Length - 2]}reason_", Game1.currentLocation); } else if (whichAnswer.Contains("reason_")) { PMonitor.Log("divorce reason"); string r = PHelper.Translation.Get(whichAnswer); if (r != null) { if (int.TryParse(r.Split('#')[r.Split('#').Length - 1], out int lost)) { heartsLost += lost; } } ShowNextDialogue($"divorce_method_", Game1.currentLocation); } else if (whichAnswer.StartsWith("divorce_method_")) { PMonitor.Log("divorce method"); string r = PHelper.Translation.Get(whichAnswer); if (r != null) { if (int.TryParse(r.Split('#')[r.Split('#').Length - 1], out int lost)) { heartsLost += lost; } } if (Game1.player.Money >= 50000 || Game1.player.spouse == "Krobus") { if (!Game1.player.isRoommate(Game1.player.spouse)) { int money = 50000; if (int.TryParse(r.Split('#')[r.Split('#').Length - 2], out int mult)) { money = (int)Math.Round(money * mult / 100f); } PMonitor.Log($"money cost {money}"); Game1.player.Money -= money; } Game1.player.divorceTonight.Value = true; string s = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Filed_" + Game1.player.spouse); if (s == null) { s = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Filed"); } Game1.drawObjectDialogue(s); if (!Game1.player.isRoommate(Game1.player.spouse)) { mp.globalChatInfoMessage("Divorce", new string[] { Game1.player.Name }); } PMonitor.Log($"hearts lost {heartsLost}"); } else { Game1.drawObjectDialogue(Game1.content.LoadString("Strings\\UI:NotEnoughMoney1")); } } }
/// <summary>Get whether a skills page is supported for extension.</summary> /// <param name="skillsPage">The skills page to check.</param> private static bool IsSupportedSkillsPage(IClickableMenu skillsPage) { return (skillsPage is SkillsPage || // vanilla menu skillsPage?.GetType().FullName == "SpaceCore.Interface.NewSkillsPage"); // SpaceCore (e.g. Luck Skill) }
private static bool IsCompatibleCraftingPage(IClickableMenu Menu) { return(Menu is CraftingPage || (Menu?.GetType().FullName == "CookingSkill.NewCraftingPage" && IsCookingSkillModCompatible)); // CookingSkill.NewCraftingPage is a menu defined in the "Cooking Skill" mod }
private static void AdjustMenu(IClickableMenu menu, Point delta, bool first = false) { if (first) { adjustedMenus.Clear(); adjustedComponents.Clear(); } if (menu is null || adjustedMenus.Contains(menu)) { return; } menu.xPositionOnScreen += delta.X; menu.yPositionOnScreen += delta.Y; var types = AccessTools.GetDeclaredFields(menu.GetType()); if (menu is ItemGrabMenu) { types.AddRange(AccessTools.GetDeclaredFields(typeof(MenuWithInventory))); } foreach (var f in types) { if (f.FieldType.IsSubclassOf(typeof(ClickableComponent)) || f.FieldType == typeof(ClickableComponent)) { AdjustComponent((ClickableComponent)f.GetValue(menu), delta); } else if (f.FieldType.IsSubclassOf(typeof(IClickableMenu)) || f.FieldType == typeof(IClickableMenu)) { AdjustMenu((IClickableMenu)f.GetValue(menu), delta); } else if (f.FieldType == typeof(InventoryMenu)) { AdjustMenu((IClickableMenu)f.GetValue(menu), delta); } else if (f.Name == "scrollBarRunner") { var c = (Rectangle)f.GetValue(menu); c = new Rectangle(c.X + delta.X, c.Y + delta.Y, c.Width, c.Height); f.SetValue(menu, c); } else if (f.FieldType == typeof(List <ClickableComponent>)) { var ol = (List <ClickableComponent>)f.GetValue(menu); if (ol is null) { continue; } foreach (var o in ol) { AdjustComponent(o, delta); } } else if (f.FieldType == typeof(List <IClickableMenu>)) { var ol = (List <IClickableMenu>)f.GetValue(menu); if (ol is null) { continue; } foreach (var o in ol) { AdjustMenu(o, delta); } } else if (f.FieldType == typeof(Dictionary <int, ClickableTextureComponent>)) { var ol = (Dictionary <int, ClickableTextureComponent>)f.GetValue(menu); if (ol is null) { continue; } foreach (var o in ol.Values) { AdjustComponent(o, delta); } } else if (f.FieldType == typeof(Dictionary <int, ClickableComponent>)) { var ol = (Dictionary <int, ClickableComponent>)f.GetValue(menu); if (ol is null) { continue; } foreach (var o in ol.Values) { AdjustComponent(o, delta); } } else if (f.FieldType == typeof(Dictionary <int, List <List <ClickableTextureComponent> > >)) { var ol = (Dictionary <int, List <List <ClickableTextureComponent> > >)f.GetValue(menu); if (ol is null) { continue; } foreach (var o in ol.Values) { foreach (var o2 in o) { foreach (var o3 in o2) { AdjustComponent(o3, delta); } } } } else if (f.FieldType == typeof(Dictionary <int, List <List <ClickableComponent> > >)) { var ol = (Dictionary <int, List <List <ClickableComponent> > >)f.GetValue(menu); if (ol is null) { continue; } foreach (var o in ol.Values) { foreach (var o2 in o) { foreach (var o3 in o2) { AdjustComponent(o3, delta); } } } } else if (f.FieldType == typeof(List <ClickableTextureComponent>)) { var ol = (List <ClickableTextureComponent>)f.GetValue(menu); if (ol is null) { continue; } foreach (var o in ol) { AdjustComponent(o, delta); } } } if (menu is GameMenu) { for (int i = 0; i < (menu as GameMenu).pages.Count; i++) { if (i != (menu as GameMenu).currentTab) { AdjustMenu((menu as GameMenu).pages[i], delta); } } } AdjustComponent(menu.upperRightCloseButton, delta); adjustedMenus.Add(menu); }
public static void Input_ButtonPressed(object sender, ButtonPressedEventArgs e) { if ((e.Button != SButton.MouseLeft && e.Button != SButton.MouseRight) || Game1.currentLocation == null || !(Game1.currentLocation is ManorHouse) || Game1.currentLocation.lastQuestionKey == null || !Game1.currentLocation.lastQuestionKey.StartsWith("divorce")) { return; } IClickableMenu menu = Game1.activeClickableMenu; if (menu == null || !ReferenceEquals(menu.GetType(), typeof(DialogueBox))) { return; } int resp = (int)typeof(DialogueBox).GetField("selectedResponse", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); List <Response> resps = (List <Response>) typeof(DialogueBox).GetField("responses", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(menu); if (resp < 0 || resps == null || resp >= resps.Count || resps[resp] == null) { return; } Game1.currentLocation.lastQuestionKey = ""; string whichAnswer = resps[resp].responseKey; Monitor.Log("answer " + whichAnswer); if (Misc.GetSpouses(Game1.player, 1).ContainsKey(whichAnswer)) { string s2 = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Question_" + Game1.player.spouse); if (s2 == null) { s2 = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Question"); } List <Response> responses = new List <Response>(); responses.Add(new Response($"Yes_{whichAnswer}", Game1.content.LoadString("Strings\\Lexicon:QuestionDialogue_Yes"))); if (ModEntry.config.ComplexDivorce) { responses.Add(new Response($"divorce_complex_{whichAnswer}", Helper.Translation.Get("divorce_complex"))); } responses.Add(new Response("No", Game1.content.LoadString("Strings\\Lexicon:QuestionDialogue_No"))); Game1.currentLocation.createQuestionDialogue(s2, responses.ToArray(), $"divorce_{whichAnswer}"); } else if (whichAnswer.StartsWith("Yes_")) { string spouse = whichAnswer.Substring(4); ModEntry.spouseToDivorce = spouse; if (Game1.player.Money >= 50000 || spouse == "Krobus") { if (!Game1.player.isRoommate(spouse)) { Game1.player.Money -= 50000; ModEntry.divorceHeartsLost = ModEntry.config.FriendlyDivorce ? 0 : -1; } else { ModEntry.divorceHeartsLost = 0; } Game1.player.divorceTonight.Value = true; string s = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Filed_" + spouse); if (s == null) { s = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Filed"); } Game1.drawObjectDialogue(s); if (!Game1.player.isRoommate(spouse)) { ModEntry.mp.globalChatInfoMessage("Divorce", new string[] { Game1.player.Name }); } } else { Game1.drawObjectDialogue(Game1.content.LoadString("Strings\\UI:NotEnoughMoney1")); } } else if (whichAnswer.StartsWith("divorce_complex_")) { complexDivorceSpouse = whichAnswer.Replace("divorce_complex_", ""); ModEntry.divorceHeartsLost = 1; ShowNextDialogue("divorce_fault_", Game1.currentLocation); } else if (whichAnswer.StartsWith("divorce_fault_")) { Monitor.Log("divorce fault"); string r = Helper.Translation.Get(whichAnswer); if (r != null) { if (int.TryParse(r.Split('#')[r.Split('#').Length - 1], out int lost)) { ModEntry.divorceHeartsLost += lost; } } string nextKey = $"divorce_{r.Split('#')[r.Split('#').Length - 2]}reason_"; Translation test = Helper.Translation.Get(nextKey + "q"); if (!test.HasValue()) { ShowNextDialogue($"divorce_method_", Game1.currentLocation); return; } ShowNextDialogue($"divorce_{r.Split('#')[r.Split('#').Length - 2]}reason_", Game1.currentLocation); } else if (whichAnswer.Contains("reason_")) { Monitor.Log("divorce reason"); string r = Helper.Translation.Get(whichAnswer); if (r != null) { if (int.TryParse(r.Split('#')[r.Split('#').Length - 1], out int lost)) { ModEntry.divorceHeartsLost += lost; } } ShowNextDialogue($"divorce_method_", Game1.currentLocation); } else if (whichAnswer.StartsWith("divorce_method_")) { Monitor.Log("divorce method"); ModEntry.spouseToDivorce = complexDivorceSpouse; string r = Helper.Translation.Get(whichAnswer); if (r != null) { if (int.TryParse(r.Split('#')[r.Split('#').Length - 1], out int lost)) { ModEntry.divorceHeartsLost += lost; } } if (Game1.player.Money >= 50000 || complexDivorceSpouse == "Krobus") { if (!Game1.player.isRoommate(complexDivorceSpouse)) { int money = 50000; if (int.TryParse(r.Split('#')[r.Split('#').Length - 2], out int mult)) { money = (int)Math.Round(money * mult / 100f); } Monitor.Log($"money cost {money}"); Game1.player.Money -= money; } Game1.player.divorceTonight.Value = true; string s = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Filed_" + complexDivorceSpouse); if (s == null) { s = Game1.content.LoadStringReturnNullIfNotFound("Strings\\Locations:ManorHouse_DivorceBook_Filed"); } Game1.drawObjectDialogue(s); if (!Game1.player.isRoommate(complexDivorceSpouse)) { ModEntry.mp.globalChatInfoMessage("Divorce", new string[] { Game1.player.Name }); } Monitor.Log($"hearts lost {ModEntry.divorceHeartsLost}"); } else { Game1.drawObjectDialogue(Game1.content.LoadString("Strings\\UI:NotEnoughMoney1")); } } }