private void OnUpdateTicked(object sender, UpdateTickedEventArgs e) { if (TitleMenu.subMenu is LoadGameMenu) { List <LoadGameMenu.MenuSlot> slots = this.Helper.Reflection.GetField <List <LoadGameMenu.MenuSlot> >(TitleMenu.subMenu, "menuSlots").GetValue(); if (slots.Count < 1) { return; } foreach (LoadGameMenu.MenuSlot slot in slots) { LoadGameMenu.SaveFileSlot saveSlot = slot as LoadGameMenu.SaveFileSlot; Farmer farmer = saveSlot.Farmer; int whichFarm = ReadFarmTypeFromSaveFile(farmer.slotName); string farmType = ""; switch (whichFarm) { case 0: farmType = "Reg. "; break; case 1: farmType = "Riv. "; break; case 2: farmType = "For. "; break; case 3: farmType = "Mtn. "; break; case 4: farmType = "Com. "; break; case 5: farmType = "4Co. "; break; default: break; } string farmName = this.Helper.Reflection.GetField <NetString>(farmer, "farmName").GetValue().Value; this.Helper.Reflection.GetField <NetString>(farmer, "farmName").SetValue(new NetString(farmType + farmName)); } this.Helper.Events.GameLoop.UpdateTicked -= this.OnUpdateTicked; return; } }
/// <summary>Get metadata for a menu element at the specified position.</summary> /// <param name="menu">The active menu.</param> /// <param name="cursorPos">The cursor's viewport-relative coordinates.</param> public ISubject GetSubjectFrom(IClickableMenu menu, Vector2 cursorPos) { IClickableMenu targetMenu = (menu as GameMenu)?.GetCurrentPage() ?? menu; switch (targetMenu) { // calendar case Billboard billboard: { // get target day int selectedDay = -1; for (int i = 0; i < billboard.calendarDays.Count; i++) { if (billboard.calendarDays[i].containsPoint((int)cursorPos.X, (int)cursorPos.Y)) { selectedDay = i + 1; break; } } if (selectedDay == -1) { return(null); } // get villager with a birthday on that date NPC target = this.GameHelper.GetAllCharacters().FirstOrDefault(p => p.Birthday_Season == Game1.currentSeason && p.Birthday_Day == selectedDay); if (target != null) { return(new CharacterSubject(this.GameHelper, target, TargetType.Villager, this.Metadata, this.Translations, this.Reflection, this.Config.ProgressionMode)); } } break; // chest case MenuWithInventory inventoryMenu: { Item item = inventoryMenu.hoveredItem; if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } } break; // inventory case InventoryPage inventory: { Item item = this.Reflection.GetField <Item>(inventory, "hoveredItem").GetValue(); if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } } break; // collections menu // derived from CollectionsPage::performHoverAction case CollectionsPage collectionsTab: { int currentTab = this.Reflection.GetField <int>(collectionsTab, "currentTab").GetValue(); if (currentTab == CollectionsPage.achievementsTab || currentTab == CollectionsPage.secretNotesTab || currentTab == CollectionsPage.lettersTab) { break; } int currentPage = this.Reflection.GetField <int>(collectionsTab, "currentPage").GetValue(); foreach (ClickableTextureComponent component in collectionsTab.collections[currentTab][currentPage]) { if (component.containsPoint((int)cursorPos.X, (int)cursorPos.Y)) { int itemID = Convert.ToInt32(component.name.Split(' ')[0]); SObject obj = new SObject(itemID, 1); return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, obj, ObjectContext.Inventory, knownQuality: false)); } } } break; // cooking or crafting menu case CraftingPage crafting: { // player inventory item Item item = this.Reflection.GetField <Item>(crafting, "hoverItem").GetValue(); if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } // crafting recipe CraftingRecipe recipe = this.Reflection.GetField <CraftingRecipe>(crafting, "hoverRecipe").GetValue(); if (recipe != null) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, recipe.createItem(), ObjectContext.Inventory, knownQuality: true)); } } break; // social tab case SocialPage socialPage: { // get villagers on current page int scrollOffset = this.Reflection.GetField <int>(socialPage, "slotPosition").GetValue(); ClickableTextureComponent[] entries = this.Reflection .GetField <List <ClickableTextureComponent> >(socialPage, "sprites") .GetValue() .Skip(scrollOffset) .ToArray(); // find hovered villager ClickableTextureComponent entry = entries.FirstOrDefault(p => p.containsPoint((int)cursorPos.X, (int)cursorPos.Y)); if (entry != null) { int index = Array.IndexOf(entries, entry) + scrollOffset; object socialID = this.Reflection.GetField <List <object> >(socialPage, "names").GetValue()[index]; if (socialID is long playerID) { Farmer player = Game1.getFarmer(playerID); return(new FarmerSubject(this.GameHelper, player, this.Translations)); } else if (socialID is string villagerName) { NPC npc = this.GameHelper.GetAllCharacters().FirstOrDefault(p => p.isVillager() && p.Name == villagerName); if (npc != null) { return(new CharacterSubject(this.GameHelper, npc, TargetType.Villager, this.Metadata, this.Translations, this.Reflection, this.Config.ProgressionMode)); } } } } break; case ProfileMenu profileMenu: { Item item = profileMenu.hoveredItem; if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } break; } // Community Center bundle menu case JunimoNoteMenu bundleMenu: { // hovered inventory item { Item item = this.Reflection.GetField <Item>(menu, "hoveredItem").GetValue(); if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } } // list of required ingredients for (int i = 0; i < bundleMenu.ingredientList.Count; i++) { if (bundleMenu.ingredientList[i].containsPoint((int)cursorPos.X, (int)cursorPos.Y)) { Bundle bundle = this.Reflection.GetField <Bundle>(bundleMenu, "currentPageBundle").GetValue(); var ingredient = bundle.ingredients[i]; var item = this.GameHelper.GetObjectBySpriteIndex(ingredient.index, ingredient.stack); item.Quality = ingredient.quality; return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } } // list of submitted ingredients foreach (ClickableTextureComponent slot in bundleMenu.ingredientSlots) { if (slot.item != null && slot.containsPoint((int)cursorPos.X, (int)cursorPos.Y)) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, slot.item, ObjectContext.Inventory, knownQuality: true)); } } } break; // load menu case TitleMenu _ when TitleMenu.subMenu is LoadGameMenu loadMenu: { ClickableComponent button = loadMenu.slotButtons.FirstOrDefault(p => p.containsPoint((int)cursorPos.X, (int)cursorPos.Y)); if (button != null) { int index = this.Reflection.GetField <int>(loadMenu, "currentItemIndex").GetValue() + int.Parse(button.name); var slots = this.Reflection.GetProperty <List <LoadGameMenu.MenuSlot> >(loadMenu, "MenuSlots").GetValue(); LoadGameMenu.SaveFileSlot slot = slots[index] as LoadGameMenu.SaveFileSlot; if (slot?.Farmer != null) { return(new FarmerSubject(this.GameHelper, slot.Farmer, this.Translations, isLoadMenu: true)); } } } break; // shop case ShopMenu shopMenu: { ISalable entry = shopMenu.hoveredItem; if (entry is Item item) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } if (entry is MovieConcession snack) { return(new MovieSnackSubject(this.GameHelper, this.Translations, snack)); } } break; // toolbar case Toolbar _: { // find hovered slot List <ClickableComponent> slots = this.Reflection.GetField <List <ClickableComponent> >(menu, "buttons").GetValue(); ClickableComponent hoveredSlot = slots.FirstOrDefault(slot => slot.containsPoint((int)cursorPos.X, (int)cursorPos.Y)); if (hoveredSlot == null) { return(null); } // get inventory index int index = slots.IndexOf(hoveredSlot); if (index < 0 || index > Game1.player.Items.Count - 1) { return(null); } // get hovered item Item item = Game1.player.Items[index]; if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } } break; // by convention (for mod support) default: { Item item = this.Reflection.GetField <Item>(menu, "HoveredItem", required: false)?.GetValue(); // ChestsAnywhere if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, this.Config.ProgressionMode, item, ObjectContext.Inventory, knownQuality: true)); } } break; } return(null); }
/// <inheritdoc /> public override ISubject GetSubject(IClickableMenu menu, int cursorX, int cursorY) { IClickableMenu targetMenu = (menu as GameMenu)?.GetCurrentPage() ?? menu; switch (targetMenu) { /**** ** GameMenu ****/ // skills tab case SkillsPage _: return(this.BuildSubject(Game1.player)); // social tab case SocialPage socialPage: { // get villagers on current page int scrollOffset = this.Reflection.GetField <int>(socialPage, "slotPosition").GetValue(); ClickableTextureComponent[] entries = this.Reflection .GetField <List <ClickableTextureComponent> >(socialPage, "sprites") .GetValue() .Skip(scrollOffset) .ToArray(); // find hovered villager ClickableTextureComponent entry = entries.FirstOrDefault(p => p.containsPoint(cursorX, cursorY)); if (entry != null) { int index = Array.IndexOf(entries, entry) + scrollOffset; object socialID = this.Reflection.GetField <List <object> >(socialPage, "names").GetValue()[index]; if (socialID is long playerID) { Farmer player = Game1.getFarmer(playerID); return(this.BuildSubject(player)); } else if (socialID is string villagerName) { NPC npc = this.GameHelper.GetAllCharacters().FirstOrDefault(p => p.isVillager() && p.Name == villagerName); if (npc != null) { return(this.BuildSubject(npc)); } } } } break; /**** ** Other menus ****/ // calendar case Billboard billboard: { // get target day int selectedDay = -1; for (int i = 0; i < billboard.calendarDays.Count; i++) { if (billboard.calendarDays[i].containsPoint(cursorX, cursorY)) { selectedDay = i + 1; break; } } if (selectedDay == -1) { return(null); } // get villager with a birthday on that date NPC target = this.GameHelper.GetAllCharacters().FirstOrDefault(p => p.Birthday_Season == Game1.currentSeason && p.Birthday_Day == selectedDay); if (target != null) { return(this.BuildSubject(target)); } } break; // load menu case TitleMenu _ when TitleMenu.subMenu is LoadGameMenu loadMenu: { ClickableComponent button = loadMenu.slotButtons.FirstOrDefault(p => p.containsPoint(cursorX, cursorY)); if (button != null) { int index = this.Reflection.GetField <int>(loadMenu, "currentItemIndex").GetValue() + int.Parse(button.name); var slots = this.Reflection.GetProperty <List <LoadGameMenu.MenuSlot> >(loadMenu, "MenuSlots").GetValue(); LoadGameMenu.SaveFileSlot slot = slots[index] as LoadGameMenu.SaveFileSlot; if (slot?.Farmer != null) { return(new FarmerSubject(this.GameHelper, slot.Farmer, isLoadMenu: true)); } } } break; } return(null); }
/// <summary>Get metadata for a menu element at the specified position.</summary> /// <param name="menu">The active menu.</param> /// <param name="cursorPos">The cursor's viewport-relative coordinates.</param> public ISubject GetSubjectFrom(IClickableMenu menu, Vector2 cursorPos) { switch (menu) { // calendar case Billboard billboard: { // get target day int selectedDay = -1; for (int i = 0; i < billboard.calendarDays.Count; i++) { if (billboard.calendarDays[i].containsPoint((int)cursorPos.X, (int)cursorPos.Y)) { selectedDay = i + 1; break; } } if (selectedDay == -1) { return(null); } // get villager with a birthday on that date NPC target = this.GameHelper.GetAllCharacters().FirstOrDefault(p => p.Birthday_Season == Game1.currentSeason && p.Birthday_Day == selectedDay); if (target != null) { return(new CharacterSubject(this.GameHelper, target, TargetType.Villager, this.Metadata, this.Translations, this.Reflection)); } } break; // chest case MenuWithInventory inventoryMenu: { Item item = inventoryMenu.hoveredItem; if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, item, ObjectContext.Inventory, knownQuality: true)); } } break; // inventory case GameMenu gameMenu: { List <IClickableMenu> tabs = this.Reflection.GetField <List <IClickableMenu> >(gameMenu, "pages").GetValue(); IClickableMenu curTab = tabs[gameMenu.currentTab]; switch (curTab) { case InventoryPage _: { Item item = this.Reflection.GetField <Item>(curTab, "hoveredItem").GetValue(); if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, item, ObjectContext.Inventory, knownQuality: true)); } } break; case CraftingPage _: { Item item = this.Reflection.GetField <Item>(curTab, "hoverItem").GetValue(); if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, item, ObjectContext.Inventory, knownQuality: true)); } } break; case SocialPage _: { // get villagers on current page int scrollOffset = this.Reflection.GetField <int>(curTab, "slotPosition").GetValue(); ClickableTextureComponent[] entries = this.Reflection .GetField <List <ClickableTextureComponent> >(curTab, "sprites") .GetValue() .Skip(scrollOffset) .ToArray(); // find hovered villager ClickableTextureComponent entry = entries.FirstOrDefault(p => p.containsPoint((int)cursorPos.X, (int)cursorPos.Y)); if (entry != null) { int index = Array.IndexOf(entries, entry) + scrollOffset; object socialID = this.Reflection.GetField <List <object> >(curTab, "names").GetValue()[index]; if (socialID is long playerID) { Farmer player = Game1.getFarmer(playerID); return(new FarmerSubject(this.GameHelper, player, this.Translations, this.Reflection)); } else if (socialID is string villagerName) { NPC npc = this.GameHelper.GetAllCharacters().FirstOrDefault(p => p.isVillager() && p.Name == villagerName); if (npc != null) { return(new CharacterSubject(this.GameHelper, npc, TargetType.Villager, this.Metadata, this.Translations, this.Reflection)); } } } } break; } } break; // Community Center bundle menu case JunimoNoteMenu bundleMenu: { // hovered inventory item { Item item = this.Reflection.GetField <Item>(menu, "hoveredItem").GetValue(); if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, item.getOne(), ObjectContext.Inventory, knownQuality: true)); } } // list of required ingredients for (int i = 0; i < bundleMenu.ingredientList.Count; i++) { if (bundleMenu.ingredientList[i].containsPoint((int)cursorPos.X, (int)cursorPos.Y)) { Bundle bundle = this.Reflection.GetField <Bundle>(bundleMenu, "currentPageBundle").GetValue(); var ingredient = bundle.ingredients[i]; var item = this.GameHelper.GetObjectBySpriteIndex(ingredient.index, ingredient.stack); item.Quality = ingredient.quality; return(new ItemSubject(this.GameHelper, this.Translations, item, ObjectContext.Inventory, knownQuality: true)); } } // list of submitted ingredients foreach (ClickableTextureComponent slot in bundleMenu.ingredientSlots) { if (slot.item != null && slot.containsPoint((int)cursorPos.X, (int)cursorPos.Y)) { return(new ItemSubject(this.GameHelper, this.Translations, slot.item, ObjectContext.Inventory, knownQuality: true)); } } } break; // kitchen case CraftingPage _: { CraftingRecipe recipe = this.Reflection.GetField <CraftingRecipe>(menu, "hoverRecipe").GetValue(); if (recipe != null) { return(new ItemSubject(this.GameHelper, this.Translations, recipe.createItem(), ObjectContext.Inventory, knownQuality: true)); } } break; // load menu case TitleMenu _ when TitleMenu.subMenu is LoadGameMenu loadMenu: { ClickableComponent button = loadMenu.slotButtons.FirstOrDefault(p => p.containsPoint((int)cursorPos.X, (int)cursorPos.Y)); if (button != null) { int index = this.Reflection.GetField <int>(loadMenu, "currentItemIndex").GetValue() + int.Parse(button.name); var slots = this.Reflection.GetProperty <List <LoadGameMenu.MenuSlot> >(loadMenu, "MenuSlots").GetValue(); LoadGameMenu.SaveFileSlot slot = slots[index] as LoadGameMenu.SaveFileSlot; if (slot?.Farmer != null) { return(new FarmerSubject(this.GameHelper, slot.Farmer, this.Translations, this.Reflection, isLoadMenu: true)); } } } break; // shop case ShopMenu _: { Item item = this.Reflection.GetField <Item>(menu, "hoveredItem").GetValue(); if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, item.getOne(), ObjectContext.Inventory, knownQuality: true)); } } break; // toolbar case Toolbar _: { // find hovered slot List <ClickableComponent> slots = this.Reflection.GetField <List <ClickableComponent> >(menu, "buttons").GetValue(); ClickableComponent hoveredSlot = slots.FirstOrDefault(slot => slot.containsPoint((int)cursorPos.X, (int)cursorPos.Y)); if (hoveredSlot == null) { return(null); } // get inventory index int index = slots.IndexOf(hoveredSlot); if (index < 0 || index > Game1.player.Items.Count - 1) { return(null); } // get hovered item Item item = Game1.player.Items[index]; if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, item.getOne(), ObjectContext.Inventory, knownQuality: true)); } } break; // by convention (for mod support) default: { Item item = this.Reflection.GetField <Item>(menu, "HoveredItem", required: false)?.GetValue(); // ChestsAnywhere if (item != null) { return(new ItemSubject(this.GameHelper, this.Translations, item, ObjectContext.Inventory, knownQuality: true)); } } break; } return(null); }