/// <summary>Updates the number of items being held by the player based on what was input to the split menu.</summary> /// <param name="item">The selected item.</param> /// <param name="who">The player that selected the items.</param> /// <param name="inventory">Either the player inventory or the shop inventory.</param> /// <param name="callback">The native callback to invoke to continue with the regular behavior after we've modified the stack.</param> private void MoveItems(Item item, SFarmer who, InventoryMenu inventory, ItemGrabMenu.behaviorOnItemSelect callback) { Debug.Assert(this.StackAmount > 0); // Get the held item now that it's been set by the native receiveRightClick call var heldItem = this.HeldItem; if (heldItem != null) { // update held item stack and item stack int numCurrentlyHeld = heldItem.Stack; // How many we're actually holding. int numInPile = this.HoverItem.Stack + item.Stack; int wantToHold = Math.Min(this.TotalItems, Math.Max(this.StackAmount, 0)); this.HoverItem.Stack = this.TotalItems - wantToHold; heldItem.Stack = wantToHold; item.Stack = wantToHold; // Remove the empty item from the inventory if (this.HoverItem.Stack <= 0) { int index = inventory.actualInventory.IndexOf(this.HoverItem); if (index > -1) { inventory.actualInventory[index] = null; } } } RestoreNativeCallbacks(); // Update stack to the amount set from OnStackAmountReceived callback?.Invoke(item, who); }
/// <summary>Replaces the native shop callbacks with our own so we can intercept the operation to modify the amount.</summary> /// <returns>If it was hooked successfully.</returns> private bool HookCallbacks() { if (this.CallbacksHooked) { return(true); } try { // Replace the delegates with our own var itemSelectCallbackField = this.Helper.Reflection.GetField <ItemGrabMenu.behaviorOnItemSelect>(this.NativeMenu, "behaviorFunction"); var itemGrabCallbackField = typeof(ItemGrabMenu).GetField("behaviorOnItemGrab"); this.OriginalItemGrabCallback = itemGrabCallbackField.GetValue(this.NativeMenu) as ItemGrabMenu.behaviorOnItemSelect; this.OriginalItemSelectCallback = itemSelectCallbackField.GetValue(); itemGrabCallbackField.SetValue(this.NativeMenu, new ItemGrabMenu.behaviorOnItemSelect(this.OnItemGrab)); itemSelectCallbackField.SetValue(this.OnItemSelect); this.CallbacksHooked = true; } catch (Exception e) { this.Monitor.Log($"Failed to hook ItemGrabMenu callbacks: {e}", LogLevel.Error); return(false); } return(true); }
/// <summary>Replaces the native shop callbacks with our own so we can intercept the operation to modify the amount.</summary> /// <returns>If it was hooked successfully.</returns> private bool HookCallbacks() { if (this.CallbacksHooked) { return(true); } try { // Replace the delegates with our own var itemSelectCallbackField = Mod.Reflection.GetField <ItemGrabMenu.behaviorOnItemSelect>(this.NativeMenu, "behaviorFunction"); //var itemGrabCallbackField = typeof(ItemGrabMenu).GetField("behaviorOnItemGrab"); this.OriginalItemGrabCallback = this.NativeMenu.behaviorOnItemGrab; this.OriginalItemSelectCallback = itemSelectCallbackField.GetValue(); this.NativeMenu.behaviorOnItemGrab = new ItemGrabMenu.behaviorOnItemSelect(OnItemGrab); itemSelectCallbackField.SetValue(OnItemSelect); this.CallbacksHooked = true; } catch (Exception e) { Log.Error($"[{nameof(ItemGrabMenuHandler)}.{nameof(HookCallbacks)}] Failed to hook ItemGrabMenu callbacks:\n{e}"); return(false); } return(true); }
public static void AddItemsToInventoryByMenuIfNecessary(List<Item> items, ItemGrabMenu.behaviorOnItemSelect itemSelectedCallback = null) { List<Item> listItensToAdd = items.Where(i => !(i is Object)).ToList(); List<Object> listObjects = items .Where(i => i is Object) .GroupBy(i => new {id = i.ParentSheetIndex, (i as Object).Quality }) .Select(g => new Object(Vector2.Zero, g.Key.id, g.Count()) {Quality = g.Key.Quality }) .ToList(); listItensToAdd.AddRange(listObjects); Game1.player.addItemsByMenuIfNecessary( listItensToAdd, itemSelectedCallback ); }
public static void AddItemsToInventoryByMenuIfNecessary(List <Item> items, ItemGrabMenu.behaviorOnItemSelect itemSelectedCallback = null) { Game1.player.addItemsByMenuIfNecessary( new List <Item>( items .GroupBy(i => new { id = i.ParentSheetIndex, (i as Object).Quality }) .Select(g => new Object(Vector2.Zero, g.Key.id, g.Count()) { Quality = g.Key.Quality }) .ToList() ), itemSelectedCallback ); }
private ItemGrabMenu ShippingBin() { MethodInfo method = typeof(Farm).GetMethod("shipItem", BindingFlags.Instance | BindingFlags.NonPublic); ItemGrabMenu.behaviorOnItemSelect behaviorOnItemSelectFunction = (ItemGrabMenu.behaviorOnItemSelect)Delegate.CreateDelegate(typeof(ItemGrabMenu.behaviorOnItemSelect), Game1.getFarm(), method); ItemGrabMenu itemGrabMenu = new ItemGrabMenu(null, true, false, new InventoryMenu.highlightThisItem(Utility.highlightShippableObjects), behaviorOnItemSelectFunction, "", null, true, true, false, true, false, 0, null, -1, null); itemGrabMenu.initializeUpperRightCloseButton(); int num = 0; itemGrabMenu.setBackgroundTransparency(num != 0); int num2 = 1; itemGrabMenu.setDestroyItemOnClick(num2 != 0); itemGrabMenu.initializeShippingBin(); return(itemGrabMenu); }
/********* ** Private methods *********/ private Item AddItemToInventory(Item item, int position, IList <Item> items, ItemGrabMenu.behaviorOnItemSelect onAddFunction = null) { if (object.ReferenceEquals(items, Game1.player.Items) && item is SObject obj && obj.specialItem) { if (obj.bigCraftable.Value) { Game1.player.specialBigCraftables.Add(obj.IsRecipe ? -obj.ParentSheetIndex : obj.ParentSheetIndex); } else { Game1.player.specialItems.Add(obj.IsRecipe ? -obj.ParentSheetIndex : obj.ParentSheetIndex); } } if (position < 0 || position >= items.Count) { return(item); } if (items[position] == null) { items[position] = item; onAddFunction?.Invoke(item, null); return(null); } if (items[position].maximumStackSize() == -1 || items[position].Name != item.Name || (item is SObject itemObj && items[position] is SObject slotObj && (itemObj.Quality != slotObj.Quality || itemObj.ParentSheetIndex != slotObj.ParentSheetIndex)) || !item.canStackWith(items[position])) { Item item2 = items[position]; if (position == Game1.player.CurrentToolIndex && object.ReferenceEquals(items, Game1.player.Items) && item2 != null) { item2.actionWhenStopBeingHeld(Game1.player); item.actionWhenBeingHeld(Game1.player); } items[position] = item; onAddFunction?.Invoke(item, null); return(item2); } int num = items[position].addToStack(item.getStack()); if (num <= 0) { return(null); } item.Stack = num; onAddFunction?.Invoke(item, null); return(item); }
public static bool receiveRightClick_Prefix(int x, int y, bool playSound, // Original arguments ref Item ___sourceItem, ref TemporaryAnimatedSprite ___poof, ItemGrabMenu.behaviorOnItemSelect ___behaviorFunction, bool ___essential, // Private fields ItemGrabMenu __instance) // Special { try { Monitor.Log($"Invoked ItemGrabMenu.receiveRightClick_Prefix", LogLevel.Debug); // Reimplemented game code return true; } catch (Exception ex) { Monitor.Log($"Failed in {nameof(receiveRightClick_Prefix)}:\n{ex}", LogLevel.Error); return true; // Run original code } }
public ItemGrabMenu(List <Item> inventory, int rows, bool reverseGrab, bool showReceivingMenu, InventoryMenu.highlightThisItem highlightFunction, ItemGrabMenu.behaviorOnItemSelect behaviorOnItemSelectFunction, string message, ItemGrabMenu.behaviorOnItemSelect behaviorOnItemGrab = null, bool snapToBottom = false, bool canBeExitedWithKey = false, bool playRightClickSound = true, bool allowRightClick = true, bool showOrganizeButton = false, int source = 0, Item sourceItem = null) : base(highlightFunction, true, true, 0, 0) { this.source = source; this.message = message; this.reverseGrab = reverseGrab; this.showReceivingMenu = showReceivingMenu; this.playRightClickSound = playRightClickSound; this.allowRightClick = allowRightClick; this.inventory.showGrayedOutSlots = true; this.sourceItem = sourceItem; this.Rows = rows; if (source == 1 && sourceItem != null && sourceItem is Chest) { this.chestColorPicker = new DiscreteColorPicker(this.xPositionOnScreen, this.yPositionOnScreen - Game1.tileSize - IClickableMenu.borderWidth * 2, 0, new Chest(true)); this.chestColorPicker.colorSelection = this.chestColorPicker.getSelectionFromColor((sourceItem as Chest).playerChoiceColor); (this.chestColorPicker.itemToDrawColored as Chest).playerChoiceColor = this.chestColorPicker.getColorFromSelection(this.chestColorPicker.colorSelection); this.colorPickerToggleButton = new ClickableTextureComponent(new Rectangle(this.xPositionOnScreen + this.width, this.yPositionOnScreen + Game1.tileSize + Game1.pixelZoom * 5, 16 * Game1.pixelZoom, 16 * Game1.pixelZoom), Game1.mouseCursors, new Rectangle(119, 469, 16, 16), (float)Game1.pixelZoom, false) { hoverText = Game1.content.LoadString("Strings\\UI:Toggle_ColorPicker", new object[0]) }; } if (snapToBottom) { base.movePosition(0, Game1.viewport.Height - (this.yPositionOnScreen + this.height - IClickableMenu.spaceToClearTopBorder)); this.snappedtoBottom = true; } this.ItemsToGrabMenu = new InventoryMenu(this.xPositionOnScreen + Game1.tileSize / 2, this.yPositionOnScreen, false, inventory, highlightFunction, inventory.Capacity, Rows, 0, 0, true); this.behaviorFunction = behaviorOnItemSelectFunction; this.behaviorOnItemGrab = behaviorOnItemGrab; this.canExitOnKey = canBeExitedWithKey; if (showOrganizeButton) { this.organizeButton = new ClickableTextureComponent("", new Rectangle(this.xPositionOnScreen + this.width, this.yPositionOnScreen + this.height / 3 - Game1.tileSize, Game1.tileSize, Game1.tileSize), "", Game1.content.LoadString("Strings\\UI:ItemGrab_Organize", new object[0]), Game1.mouseCursors, new Rectangle(162, 440, 16, 16), (float)Game1.pixelZoom, false); } if ((Game1.isAnyGamePadButtonBeingPressed() || !Game1.lastCursorMotionWasMouse) && this.ItemsToGrabMenu.actualInventory.Count > 0 && Game1.activeClickableMenu == null) { Game1.setMousePosition(this.inventory.inventory[0].bounds.Center); } }
public static Item addItemToInventory(Item item, int position, List <Item> items, ItemGrabMenu.behaviorOnItemSelect onAddFunction = null) { if (items.Equals(Game1.player.items) && item is StardewValley.Object && (item as StardewValley.Object).specialItem) { if ((item as StardewValley.Object).bigCraftable) { Game1.player.specialBigCraftables.Add((item as StardewValley.Object).isRecipe ? (-(item as StardewValley.Object).parentSheetIndex) : (item as StardewValley.Object).parentSheetIndex); } else { Game1.player.specialItems.Add((item as StardewValley.Object).isRecipe ? (-(item as StardewValley.Object).parentSheetIndex) : (item as StardewValley.Object).parentSheetIndex); } } if (position < 0 || position >= items.Count <Item>()) { return(item); } if (items[position] == null) { items[position] = item; if (onAddFunction != null) { onAddFunction(item, null); } return(null); } if (items[position].maximumStackSize() == -1 || !items[position].Name.Equals(item.Name) || (item is StardewValley.Object && items[position] is StardewValley.Object && ((item as StardewValley.Object).quality != (items[position] as StardewValley.Object).quality || (item as StardewValley.Object).parentSheetIndex != (items[position] as StardewValley.Object).parentSheetIndex)) || !item.canStackWith(items[position])) { Item item2 = items[position]; if (position == Game1.player.CurrentToolIndex && items.Equals(Game1.player.items) && item2 != null) { item2.actionWhenStopBeingHeld(Game1.player); item.actionWhenBeingHeld(Game1.player); } items[position] = item; if (onAddFunction != null) { onAddFunction(item, null); } return(item2); } int num = items[position].addToStack(item.getStack()); if (num <= 0) { return(null); } item.Stack = num; if (onAddFunction != null) { onAddFunction(item, null); } return(item); }
public ItemGrabMenu(List <Item> inventory, bool reverseGrab, bool showReceivingMenu, InventoryMenu.highlightThisItem highlightFunction, ItemGrabMenu.behaviorOnItemSelect behaviorOnItemSelectFunction, string message, ItemGrabMenu.behaviorOnItemSelect behaviorOnItemGrab = null, bool snapToBottom = false, bool canBeExitedWithKey = false, bool playRightClickSound = true, bool allowRightClick = true, bool showOrganizeButton = false, int source = 0, Item sourceItem = null, int whichSpecialButton = -1, object specialObject = null) : base(highlightFunction, true, true, 0, 0) { this.source = source; this.message = message; this.reverseGrab = reverseGrab; this.showReceivingMenu = showReceivingMenu; this.playRightClickSound = playRightClickSound; this.allowRightClick = allowRightClick; this.inventory.showGrayedOutSlots = true; this.sourceItem = sourceItem; if (source == 1 && sourceItem != null && sourceItem is Chest) { this.chestColorPicker = new DiscreteColorPicker(this.xPositionOnScreen, this.yPositionOnScreen - Game1.tileSize - IClickableMenu.borderWidth * 2, 0, new Chest(true)); this.chestColorPicker.colorSelection = this.chestColorPicker.getSelectionFromColor((sourceItem as Chest).playerChoiceColor); (this.chestColorPicker.itemToDrawColored as Chest).playerChoiceColor = this.chestColorPicker.getColorFromSelection(this.chestColorPicker.colorSelection); this.colorPickerToggleButton = new ClickableTextureComponent(new Rectangle(this.xPositionOnScreen + this.width, this.yPositionOnScreen + Game1.tileSize + Game1.pixelZoom * 5, 16 * Game1.pixelZoom, 16 * Game1.pixelZoom), Game1.mouseCursors, new Rectangle(119, 469, 16, 16), (float)Game1.pixelZoom, false) { hoverText = Game1.content.LoadString("Strings\\UI:Toggle_ColorPicker", new object[0]), myID = 27346, downNeighborID = (showOrganizeButton ? 106 : 5948), leftNeighborID = 11 }; } this.whichSpecialButton = whichSpecialButton; this.specialObject = specialObject; if (whichSpecialButton == 1) { this.specialButton = new ClickableTextureComponent(new Rectangle(this.xPositionOnScreen + this.width, this.yPositionOnScreen + Game1.tileSize + Game1.pixelZoom * 5, 16 * Game1.pixelZoom, 16 * Game1.pixelZoom), Game1.mouseCursors, new Rectangle(108, 491, 16, 16), (float)Game1.pixelZoom, false) { myID = 12485, downNeighborID = (showOrganizeButton ? 106 : 5948) }; if (specialObject != null && specialObject is JunimoHut) { this.specialButton.sourceRect.X = ((specialObject as JunimoHut).noHarvest ? 124 : 108); } } if (snapToBottom) { base.movePosition(0, Game1.viewport.Height - (this.yPositionOnScreen + this.height - IClickableMenu.spaceToClearTopBorder)); this.snappedtoBottom = true; } this.ItemsToGrabMenu = new InventoryMenu(this.xPositionOnScreen + Game1.tileSize / 2, this.yPositionOnScreen, false, inventory, highlightFunction, -1, 3, 0, 0, true); if (Game1.options.SnappyMenus) { this.ItemsToGrabMenu.populateClickableComponentList(); for (int i = 0; i < this.ItemsToGrabMenu.inventory.Count; i++) { if (this.ItemsToGrabMenu.inventory[i] != null) { this.ItemsToGrabMenu.inventory[i].myID += 53910; this.ItemsToGrabMenu.inventory[i].upNeighborID += 53910; this.ItemsToGrabMenu.inventory[i].rightNeighborID += 53910; this.ItemsToGrabMenu.inventory[i].downNeighborID = -7777; this.ItemsToGrabMenu.inventory[i].leftNeighborID += 53910; this.ItemsToGrabMenu.inventory[i].fullyImmutable = true; } } } this.behaviorFunction = behaviorOnItemSelectFunction; this.behaviorOnItemGrab = behaviorOnItemGrab; this.canExitOnKey = canBeExitedWithKey; if (showOrganizeButton) { this.organizeButton = new ClickableTextureComponent("", new Rectangle(this.xPositionOnScreen + this.width, this.yPositionOnScreen + this.height / 3 - Game1.tileSize, Game1.tileSize, Game1.tileSize), "", Game1.content.LoadString("Strings\\UI:ItemGrab_Organize", new object[0]), Game1.mouseCursors, new Rectangle(162, 440, 16, 16), (float)Game1.pixelZoom, false) { myID = 106, upNeighborID = ((this.colorPickerToggleButton != null) ? 27346 : ((this.specialButton != null) ? 12485 : -500)), downNeighborID = 5948 }; } if ((Game1.isAnyGamePadButtonBeingPressed() || !Game1.lastCursorMotionWasMouse) && this.ItemsToGrabMenu.actualInventory.Count > 0 && Game1.activeClickableMenu == null) { Game1.setMousePosition(this.inventory.inventory[0].bounds.Center); } if (Game1.options.snappyMenus && Game1.options.gamepadControls) { if (this.chestColorPicker != null) { this.discreteColorPickerCC = new List <ClickableComponent>(); for (int j = 0; j < this.chestColorPicker.totalColors; j++) { this.discreteColorPickerCC.Add(new ClickableComponent(new Rectangle(this.chestColorPicker.xPositionOnScreen + IClickableMenu.borderWidth / 2 + j * 9 * Game1.pixelZoom, this.chestColorPicker.yPositionOnScreen + IClickableMenu.borderWidth / 2, 9 * Game1.pixelZoom, 7 * Game1.pixelZoom), "") { myID = j + 4343, rightNeighborID = ((j < this.chestColorPicker.totalColors - 1) ? (j + 4343 + 1) : -1), leftNeighborID = ((j > 0) ? (j + 4343 - 1) : -1), downNeighborID = ((this.ItemsToGrabMenu != null && this.ItemsToGrabMenu.inventory.Count > 0) ? 53910 : 0) }); } } for (int k = 0; k < 12; k++) { if (this.inventory != null && this.inventory.inventory != null && this.inventory.inventory.Count >= 12) { this.inventory.inventory[k].upNeighborID = (this.shippingBin ? 12598 : ((this.discreteColorPickerCC != null && this.ItemsToGrabMenu != null && this.ItemsToGrabMenu.inventory.Count <= k) ? 4343 : ((this.ItemsToGrabMenu.inventory.Count > k) ? (53910 + k) : 53910))); } if (this.discreteColorPickerCC != null && this.ItemsToGrabMenu != null && this.ItemsToGrabMenu.inventory.Count > k) { this.ItemsToGrabMenu.inventory[k].upNeighborID = 4343; } } if (!this.shippingBin) { for (int l = 0; l < 36; l++) { if (this.inventory != null && this.inventory.inventory != null && this.inventory.inventory.Count > l) { this.inventory.inventory[l].upNeighborID = -7777; this.inventory.inventory[l].upNeighborImmutable = true; } } } if (this.trashCan != null) { this.trashCan.leftNeighborID = 11; } if (this.okButton != null) { this.okButton.leftNeighborID = 11; } base.populateClickableComponentList(); this.snapToDefaultClickableComponent(); } }
public ItemGrabMenuMethods(IList <Item> inventory, bool reverseGrab, bool showReceivingMenu, InventoryMenu.highlightThisItem highlightFunction, ItemGrabMenu.behaviorOnItemSelect behaviorOnItemSelectFunction, string message, ItemGrabMenu.behaviorOnItemSelect behaviorOnItemGrab = null, bool snapToBottom = false, bool canBeExitedWithKey = false, bool playRightClickSound = true, bool allowRightClick = true, bool showOrganizeButton = false, int source = 0, Item sourceItem = null, int whichSpecialButton = -1, object context = null) : base(inventory, reverseGrab, showReceivingMenu, highlightFunction, behaviorOnItemSelectFunction, message, behaviorOnItemGrab, snapToBottom, canBeExitedWithKey, playRightClickSound, allowRightClick, showOrganizeButton, source, sourceItem, whichSpecialButton, context, -1, 3, null, true, null, false, null) { }
// Constructors: // TODO: Add custom menu background colour support public MainMenu(IList <StardewValley.Item> inventory, Boolean reverseGrab, Boolean showReceivingMenu, InventoryMenu.highlightThisItem highlightFunction, ItemGrabMenu.behaviorOnItemSelect behaviorOnItemSelectFunction, String message, ItemGrabMenu.behaviorOnItemSelect behaviorOnItemGrab = null, Boolean snapToBottom = false, Boolean canBeExitedWithKey = false, Boolean playRightClickSound = true, Boolean allowRightClick = true, Boolean showOrganizeButton = false, Int32 source = 0, StardewValley.Item sourceItem = null, Int32 whichSpecialButton = -1, Object context = null) : base(inventory, reverseGrab, showReceivingMenu, highlightFunction, behaviorOnItemSelectFunction, message, behaviorOnItemGrab, snapToBottom, canBeExitedWithKey, playRightClickSound, allowRightClick, showOrganizeButton, source, sourceItem, whichSpecialButton, context) { // recreate menu { var game_viewport = GlobalVars.GameViewport; this.inventory = new InventoryMenu( game_viewport.Width - this.inventory.width - Convert.ToInt32(game_viewport.Width / (12.0f * StardewValley.Game1.options.zoomLevel)), game_viewport.Height - this.inventory.height - (game_viewport.Height / Convert.ToInt32(8.0f * StardewValley.Game1.options.zoomLevel)), false, null, this.inventory.highlightMethod, this.inventory.capacity, this.inventory.rows, this.inventory.horizontalGap, this.inventory.verticalGap, this.inventory.drawSlots); this.ItemsToGrabMenu = new InventoryMenu( game_viewport.Width - this.ItemsToGrabMenu.width - Convert.ToInt32(game_viewport.Width / (12.0f * StardewValley.Game1.options.zoomLevel)), game_viewport.Height / Convert.ToInt32(8.0f * StardewValley.Game1.options.zoomLevel), false, this.ItemsToGrabMenu.actualInventory, this.ItemsToGrabMenu.highlightMethod, this.ItemsToGrabMenu.capacity, this.ItemsToGrabMenu.rows, this.ItemsToGrabMenu.horizontalGap, this.ItemsToGrabMenu.verticalGap, this.ItemsToGrabMenu.drawSlots); this.ItemsToGrabMenu.populateClickableComponentList(); for (Int32 i = 0; i < this.ItemsToGrabMenu.inventory.Count; i++) { if (this.ItemsToGrabMenu.inventory[i] != null) { this.ItemsToGrabMenu.inventory[i].myID += ItemGrabMenu.region_itemsToGrabMenuModifier; this.ItemsToGrabMenu.inventory[i].upNeighborID += ItemGrabMenu.region_itemsToGrabMenuModifier; this.ItemsToGrabMenu.inventory[i].rightNeighborID += ItemGrabMenu.region_itemsToGrabMenuModifier; this.ItemsToGrabMenu.inventory[i].downNeighborID = ClickableComponent.CUSTOM_SNAP_BEHAVIOR; this.ItemsToGrabMenu.inventory[i].leftNeighborID += ItemGrabMenu.region_itemsToGrabMenuModifier; this.ItemsToGrabMenu.inventory[i].fullyImmutable = true; } } this.PlayerInventoryOptions.Bounds = this.inventory.GetRectangleForDialogueBox(); this.SourceInventoryOptions.Bounds = this.ItemsToGrabMenu.GetRectangleForDialogueBox(); this.SetBounds( this.SourceInventoryOptions.Bounds.X, this.SourceInventoryOptions.Bounds.Y, this.SourceInventoryOptions.Bounds.Width, this.SourceInventoryOptions.Bounds.Height + (this.PlayerInventoryOptions.Bounds.Y - (this.SourceInventoryOptions.Bounds.Y + this.SourceInventoryOptions.Bounds.Height)) + this.PlayerInventoryOptions.Bounds.Height); // handle organization buttons { this.createOrganizationButtons(false, false, false); this.okButton = this.trashCan = null; if (!(this.dropItemInvisibleButton is null)) { this.dropItemInvisibleButton.bounds = new Rectangle( this.PlayerInventoryOptions.Bounds.X + (this.PlayerInventoryOptions.Bounds.Width / 2), this.PlayerInventoryOptions.Bounds.Y - ((this.PlayerInventoryOptions.Bounds.Y - (this.SourceInventoryOptions.Bounds.Y + this.SourceInventoryOptions.Bounds.Height)) / 2), 64, 64); } } this.populateClickableComponentList(); if (StardewValley.Game1.options.SnappyMenus) { this.snapToDefaultClickableComponent(); } this.SetupBorderNeighbors(); } this.MenuItems.Add(new ConfigPanel(this)); this.MenuItems.Add(new ChestColouringPanel(this)); }
// No longer used after switching to transpiler public static bool addItemToInventory_Prefix( Item item, int position, IList <Item> items, ItemGrabMenu.behaviorOnItemSelect onAddFunction, ref Item __result) { try { Monitor.Log($"Invoked Utility.addItemToInventory with onAddFunction: {onAddFunction}", LogLevel.Debug); // Reimplemented game code if (items.Equals((object)Game1.player.items) && item is Object && (item as Object).specialItem) { if ((bool)(NetFieldBase <bool, NetBool>)(item as Object).bigCraftable) { if (!Game1.player.specialBigCraftables.Contains((bool)(NetFieldBase <bool, NetBool>)(item as Object).isRecipe ? -(int)(NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex : (int)(NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex)) { Game1.player.specialBigCraftables.Add((bool)(NetFieldBase <bool, NetBool>)(item as Object).isRecipe ? -(int)(NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex : (int)(NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex); } } else if (!Game1.player.specialItems.Contains((bool)(NetFieldBase <bool, NetBool>)(item as Object).isRecipe ? -(int)(NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex : (int)(NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex)) { Game1.player.specialItems.Add((bool)(NetFieldBase <bool, NetBool>)(item as Object).isRecipe ? -(int)(NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex : (int)(NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex); } } if (position < 0 || position >= items.Count) { __result = item; return(false); } if (items[position] == null) { items[position] = item; Utility.checkItemFirstInventoryAdd(item); if (onAddFunction != null) { onAddFunction(item, Game1.player); } __result = (Item)null; return(false); } if (items[position].maximumStackSize() != -1 && items[position].Name.Equals(item.Name) && (!(item is Object) || !(items[position] is Object) || (NetFieldBase <int, NetInt>)(item as Object).quality == (items[position] as Object).quality && (NetFieldBase <int, NetInt>)(item as Object).parentSheetIndex == (items[position] as Object).parentSheetIndex) && item.canStackWith((ISalable)items[position])) { Utility.checkItemFirstInventoryAdd(item); int stack = items[position].addToStack(item); if (stack <= 0) { __result = (Item)null; return(false); } item.Stack = stack; if (onAddFunction != null) { onAddFunction(item, Game1.player); } __result = item; return(false); } Item obj = items[position]; if (position == Game1.player.CurrentToolIndex && items.Equals((object)Game1.player.items) && obj != null) { obj.actionWhenStopBeingHeld(Game1.player); item.actionWhenBeingHeld(Game1.player); } Utility.checkItemFirstInventoryAdd(item); items[position] = item; if (onAddFunction != null) { onAddFunction(item, Game1.player); } __result = obj; return(false); } catch (Exception ex) { Monitor.Log($"Failed in {nameof(addItemToInventory_Prefix)}:\n{ex}", LogLevel.Error); return(true); // Run original code } }
public static Item AddItemToInventory(Item item, int position, List <Item> items, ItemGrabMenu.behaviorOnItemSelect onAddFunction = null) { if (items == Game1.player.items && item is SObject obj && obj.specialItem) { if (obj.bigCraftable) { Game1.player.specialBigCraftables.Add(obj.isRecipe ? (-obj.parentSheetIndex) : obj.parentSheetIndex); } else { Game1.player.specialItems.Add(obj.isRecipe ? (-obj.parentSheetIndex) : obj.parentSheetIndex); } } if (position < 0 || position >= items.Count) { return(item); } if (items[position] == null) { items[position] = item; onAddFunction?.Invoke(item, null); return(null); } if (items[position].maximumStackSize() == -1 || items[position].Name != item.Name || (item is SObject addItem && items[position] is SObject slotItem && (addItem.quality != slotItem.quality || addItem.parentSheetIndex != slotItem.parentSheetIndex)) || !item.canStackWith(items[position])) { Item foundItem = items[position]; if (position == Game1.player.CurrentToolIndex && items == Game1.player.items && foundItem != null) { foundItem.actionWhenStopBeingHeld(Game1.player); item.actionWhenBeingHeld(Game1.player); } items[position] = item; onAddFunction?.Invoke(item, null); return(foundItem); } int newStack = items[position].addToStack(item.getStack()); if (newStack <= 0) { return(null); } item.Stack = newStack; onAddFunction?.Invoke(item, null); return(item); }
public static bool receiveLeftClick_Prefix(int x, int y, bool playSound, // Original arguments ref Item ___sourceItem, ref TemporaryAnimatedSprite ___poof, ItemGrabMenu.behaviorOnItemSelect ___behaviorFunction, bool ___essential, // Private fields ItemGrabMenu __instance) // Special { try { Monitor.Log($"Invoked ItemGrabMenu.receiveLeftClick_Prefix.", LogLevel.Debug); // Reimplemented game code /** //base.receiveLeftClick(x, y, !__instance.destroyItemOnClick); // Reimplemented below var baseMethod = typeof(MenuWithInventory).GetMethod("receiveLeftClick"); var ftn = baseMethod.MethodHandle.GetFunctionPointer(); var baseReceiveLeftClick = (Action<int, int, bool>)Activator.CreateInstance( typeof(Action<int, int, bool>), __instance, ftn); baseReceiveLeftClick(x, y, !__instance.destroyItemOnClick); // Shipping bin menu if (__instance.shippingBin && __instance.lastShippedHolder.containsPoint(x, y)) { if (Game1.getFarm().lastItemShipped == null) return false; // Don't run original code Game1.getFarm().getShippingBin(Game1.player).Remove(Game1.getFarm().lastItemShipped); if (Game1.player.addItemToInventoryBool(Game1.getFarm().lastItemShipped, false)) { Game1.playSound("coin"); Game1.getFarm().lastItemShipped = (Item)null; if (Game1.player.ActiveObject == null) return false; // Don't run original code Game1.player.showCarrying(); Game1.player.Halt(); } else Game1.getFarm().getShippingBin(Game1.player).Add(Game1.getFarm().lastItemShipped); } else { // Select color for chests if (__instance.chestColorPicker != null) { __instance.chestColorPicker.receiveLeftClick(x, y, true); if (___sourceItem != null && ___sourceItem is Chest) (___sourceItem as Chest).playerChoiceColor.Value = __instance.chestColorPicker.getColorFromSelection(__instance.chestColorPicker.colorSelection); } if (__instance.colorPickerToggleButton != null && __instance.colorPickerToggleButton.containsPoint(x, y)) { Game1.player.showChestColorPicker = !Game1.player.showChestColorPicker; __instance.chestColorPicker.visible = Game1.player.showChestColorPicker; try { Game1.playSound("drumkit6"); } catch (Exception ex) { } __instance.SetupBorderNeighbors(); } // Junimo harvest toggle if (__instance.whichSpecialButton != -1 && __instance.specialButton != null && __instance.specialButton.containsPoint(x, y)) { Game1.playSound("drumkit6"); if (__instance.whichSpecialButton == 1 && __instance.context != null && __instance.context is JunimoHut) { (__instance.context as JunimoHut).noHarvest.Value = !(bool)(NetFieldBase<bool, NetBool>)(__instance.context as JunimoHut).noHarvest; __instance.specialButton.sourceRect.X = (bool)(NetFieldBase<bool, NetBool>)(__instance.context as JunimoHut).noHarvest ? 124 : 108; } } // Click with empty hand if (__instance.heldItem == null && __instance.showReceivingMenu) { __instance.heldItem = __instance.ItemsToGrabMenu.leftClick(x, y, __instance.heldItem, false); // behaviorOnItemGrab Action if (__instance.heldItem != null && __instance.behaviorOnItemGrab != null) { __instance.behaviorOnItemGrab(__instance.heldItem, Game1.player); // ??? if (Game1.activeClickableMenu != null && Game1.activeClickableMenu is ItemGrabMenu) { (Game1.activeClickableMenu as ItemGrabMenu).setSourceItem(___sourceItem); if (Game1.options.SnappyMenus) { (Game1.activeClickableMenu as ItemGrabMenu).currentlySnappedComponent = __instance.currentlySnappedComponent; (Game1.activeClickableMenu as ItemGrabMenu).snapCursorToCurrentSnappedComponent(); } } } // Dwarvish translation guide if (__instance.heldItem is StardewValley.Object && (int)(NetFieldBase<int, NetInt>)(__instance.heldItem as StardewValley.Object).parentSheetIndex == 326) { __instance.heldItem = (Item)null; Game1.player.canUnderstandDwarves = true; ___poof = new TemporaryAnimatedSprite("TileSheets\\animations", new Rectangle(0, 320, 64, 64), 50f, 8, 0, new Vector2((float)(x - x % 64 + 16), (float)(y - y % 64 + 16)), false, false); Game1.playSound("fireball"); } // Lost book else if (__instance.heldItem is StardewValley.Object && (int)(NetFieldBase<int, NetInt>)(__instance.heldItem as StardewValley.Object).parentSheetIndex == 102) { __instance.heldItem = (Item)null; Game1.player.foundArtifact(102, 1); ___poof = new TemporaryAnimatedSprite("TileSheets\\animations", new Rectangle(0, 320, 64, 64), 50f, 8, 0, new Vector2((float)(x - x % 64 + 16), (float)(y - y % 64 + 16)), false, false); Game1.playSound("fireball"); } // Stardrop if (__instance.heldItem is StardewValley.Object && Utility.IsNormalObjectAtParentSheetIndex(__instance.heldItem, 434)) { StardewValley.Object heldItem = __instance.heldItem as StardewValley.Object; __instance.heldItem = (Item)null; __instance.exitThisMenu(false); Game1.player.eatObject(heldItem, true); } // New Recipe else if (__instance.heldItem is StardewValley.Object && (bool)(NetFieldBase<bool, NetBool>)(__instance.heldItem as StardewValley.Object).isRecipe) { string key = __instance.heldItem.Name.Substring(0, __instance.heldItem.Name.IndexOf("Recipe") - 1); try { if ((__instance.heldItem as StardewValley.Object).Category == -7) Game1.player.cookingRecipes.Add(key, 0); else Game1.player.craftingRecipes.Add(key, 0); ___poof = new TemporaryAnimatedSprite("TileSheets\\animations", new Rectangle(0, 320, 64, 64), 50f, 8, 0, new Vector2((float)(x - x % 64 + 16), (float)(y - y % 64 + 16)), false, false); Game1.playSound("newRecipe"); } catch (Exception ex) { } __instance.heldItem = (Item)null; } // Try to add to inventory - this is where it's going wrong for grandpa callbacks else if (Game1.player.addItemToInventoryBool(__instance.heldItem, false)) // Can I pass in a delegate? No. { if (__instance.inventory.onAddItem != null) // MY ADDITIONS! __instance.inventory.onAddItem(__instance.heldItem, Game1.player); // MY ADDITIONS! __instance.heldItem = (Item)null; Game1.playSound("coin"); } } // Hands are full. Check if reverse grab is allowed else if ((__instance.reverseGrab || ___behaviorFunction != null) && __instance.isWithinBounds(x, y)) { ___behaviorFunction(__instance.heldItem, Game1.player); // Action is executed? (Works for callbacks?) if (Game1.activeClickableMenu != null && Game1.activeClickableMenu is ItemGrabMenu) { (Game1.activeClickableMenu as ItemGrabMenu).setSourceItem(___sourceItem); if (Game1.options.SnappyMenus) { (Game1.activeClickableMenu as ItemGrabMenu).currentlySnappedComponent = __instance.currentlySnappedComponent; (Game1.activeClickableMenu as ItemGrabMenu).snapCursorToCurrentSnappedComponent(); } } if (__instance.destroyItemOnClick) { __instance.heldItem = (Item)null; return false; // Don't run original code } } if (__instance.organizeButton != null && __instance.organizeButton.containsPoint(x, y)) { ClickableComponent snappedComponent = __instance.currentlySnappedComponent; ItemGrabMenu.organizeItemsInList(__instance.ItemsToGrabMenu.actualInventory); Game1.activeClickableMenu = (IClickableMenu)new ItemGrabMenu(__instance.ItemsToGrabMenu.actualInventory, false, true, new InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems), ___behaviorFunction, (string)null, __instance.behaviorOnItemGrab, false, true, true, true, true, __instance.source, ___sourceItem, __instance.whichSpecialButton, __instance.context).setEssential(___essential); if (snappedComponent != null) { Game1.activeClickableMenu.setCurrentlySnappedComponentTo(snappedComponent.myID); if (Game1.options.SnappyMenus) __instance.snapCursorToCurrentSnappedComponent(); } (Game1.activeClickableMenu as ItemGrabMenu).heldItem = __instance.heldItem; Game1.playSound("Ship"); } if (__instance.fillStacksButton != null && __instance.fillStacksButton.containsPoint(x, y)) { __instance.FillOutStacks(); Game1.playSound("Ship"); } // This one seems to trigger statue callback behaviour. It calls inventory.onAddItem. Try with fishing artifact? // I think the difference is for delegate onAddItem functions, versus in-built "new Artifact?" checking functions. else { if (__instance.heldItem == null || __instance.isWithinBounds(x, y) || !__instance.heldItem.canBeTrashed()) return false; // Don't run original code __instance.DropHeldItem(); } } return false;**/ return true; } catch (Exception ex) { Monitor.Log($"Failed in {nameof(receiveLeftClick_Prefix)}:\n{ex}", LogLevel.Error); return true; // Run original code } }
public void addItemByMenuIfNecessary(IItemWrapper item, ItemGrabMenu.behaviorOnItemSelect itemSelectedCallback = null) { }
public void addItemsByMenuIfNecessary(IEnumerable <IItemWrapper> itemsToAdd, ItemGrabMenu.behaviorOnItemSelect itemSelectedCallback = null) { }