diff --git a/gradle.properties b/gradle.properties index 6d49f0d..547453b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,4 @@ version_minecraft=1.16.3 version_forge_minecraft=1.16.3-34.1.0 version_fml_mappings=20200723-1.16.1 version_jei=1.16.3:7.3.2.36 -version_engineersdecor=1.1.3-b1 +version_engineersdecor=1.1.3-b2 diff --git a/meta/update.json b/meta/update.json index 9f2c734..97a8438 100644 --- a/meta/update.json +++ b/meta/update.json @@ -1,6 +1,7 @@ { "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "1.16.3": { + "1.1.3-b2": "[A] Crafting table shift/ctrl click item move actions tweaked to new metal slot design.\n[A] Factory Dropper and Block Placer now also support quick-move-all (shift-ctrl-click).\n[F] Fixed Small Lab Furnace speed boost factor (with IE Heater in aux slot).", "1.1.3-b1": "[A] The Factory Block Breaker can insert items into Hoppers underneath it (issue #121, winsrp).\n[F] Help tooltips manually wrapped.\n[F] Fixed Labeled Crate item name persistence (issue #127, ty inqie).\n[F] Help text typo fixed (issue #129, ty Smollet777).", "1.1.2": "[U] Updated to Forge 1.16.3-34.1.0.\n[A] Added Factory Hopper insertion/extraction for entities like Minecarts (issue #125, ty boneskull).", "1.1.2-b8": "[F] Fixed Double-T support thick steel pole connection (thx @CastCrafter).\n[A] Concrete and Clinker walls connect to windows and glass panes.", @@ -14,6 +15,6 @@ }, "promos": { "1.16.3-recommended": "1.1.2", - "1.16.3-latest": "1.1.3-b1" + "1.16.3-latest": "1.1.3-b2" } } \ No newline at end of file diff --git a/readme.md b/readme.md index 1165756..001e278 100644 --- a/readme.md +++ b/readme.md @@ -11,6 +11,10 @@ Mod sources for Minecraft version 1.16.3. ## Version history + - v1.1.3-b2 [A] Crafting table shift/ctrl click item move actions tweaked to new metal slot design. + [A] Factory Dropper and Block Placer now also support quick-move-all (shift-ctrl-click). + [F] Fixed Small Lab Furnace speed boost factor (with IE Heater in aux slot). + - v1.1.3-b1 [A] The Factory Block Breaker can insert items into Hoppers underneath it (issue #121, winsrp). [F] Help tooltips manually wrapped. [F] Fixed Labeled Crate item name persistence (issue #127, ty inqie). diff --git a/src/main/java/wile/engineersdecor/blocks/EdCraftingTable.java b/src/main/java/wile/engineersdecor/blocks/EdCraftingTable.java index d9f3137..f41b561 100644 --- a/src/main/java/wile/engineersdecor/blocks/EdCraftingTable.java +++ b/src/main/java/wile/engineersdecor/blocks/EdCraftingTable.java @@ -50,7 +50,7 @@ import wile.engineersdecor.ModContent; import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.libmc.detail.Auxiliaries; import wile.engineersdecor.libmc.detail.Inventories; -import wile.engineersdecor.libmc.detail.Inventories.SlotRange; +import wile.engineersdecor.libmc.detail.Inventories.InventoryRange; import wile.engineersdecor.libmc.detail.Networking; import wile.engineersdecor.libmc.detail.TooltipDisplay; import wile.engineersdecor.libmc.detail.TooltipDisplay.TipRange; @@ -158,7 +158,10 @@ public class EdCraftingTable public static class CraftingTableTileEntity extends TileEntity implements IInventory, INameable, INamedContainerProvider { - public static final int NUM_OF_SLOTS = 9+18; + public static final int NUM_OF_STORAGE_SLOTS = 18; + public static final int NUM_OF_STORAGE_ROWS = 2; + public static final int NUM_OF_SLOTS = 9+NUM_OF_STORAGE_SLOTS; + protected NonNullList stacks = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); protected CompoundNBT history = new CompoundNBT(); @@ -319,13 +322,15 @@ public class EdCraftingTable protected static final String ACTION_PLACE_CURRENT_HISTORY_SEL = "place-refab"; protected static final String ACTION_PLACE_SHIFTCLICKED_STACK = "place-stack"; protected static final String ACTION_MOVE_ALL_STACKS = "move-stacks"; + protected static final String ACTION_MOVE_STACK = "move-stack"; protected static final String ACTION_INCREASE_CRAFTING_STACKS = "inc-crafting-stacks"; protected static final String ACTION_DECREASE_CRAFTING_STACKS = "dec-crafting-stacks"; public static final int CRAFTING_SLOTS_BEGIN = 0; public static final int NUM_OF_CRAFTING_SLOTS = 9; public static final int STORAGE_SLOTS_BEGIN = NUM_OF_CRAFTING_SLOTS; - public static final int NUM_OF_STORAGE_SLOTS = CraftingTableTileEntity.NUM_OF_SLOTS - NUM_OF_CRAFTING_SLOTS; + public static final int NUM_OF_STORAGE_SLOTS = CraftingTableTileEntity.NUM_OF_STORAGE_SLOTS; + public static final int NUM_OF_STORAGE_ROWS = CraftingTableTileEntity.NUM_OF_STORAGE_ROWS; public final ImmutableList> CRAFTING_SLOT_COORDINATES; private final PlayerEntity player_; @@ -336,6 +341,12 @@ public class EdCraftingTable private final CraftResultInventory result_; private boolean has_recipe_collision_; private boolean crafting_matrix_changed_now_; + private final InventoryRange crafting_grid_range_; + private final InventoryRange crafting_result_range_; + private final InventoryRange block_storage_range_; + private final InventoryRange player_storage_range_; + private final InventoryRange player_hotbar_range_; + private final InventoryRange player_inventory_range_; public CraftingTableContainer(int cid, PlayerInventory pinv) { this(cid, pinv, new Inventory(CraftingTableTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY); } @@ -352,6 +363,12 @@ public class EdCraftingTable result_ = new CraftResultInventory(); matrix_ = new CraftingTableGrid(this, block_inventory); matrix_.openInventory(player_); + crafting_result_range_= new InventoryRange(result_, 0, 1, 1); + crafting_grid_range_ = new InventoryRange(matrix_, 0, 9, 3); + block_storage_range_ = new InventoryRange(inventory_, STORAGE_SLOTS_BEGIN, NUM_OF_STORAGE_SLOTS, NUM_OF_STORAGE_ROWS); + player_storage_range_ = InventoryRange.fromPlayerStorage(player_); + player_hotbar_range_ = InventoryRange.fromPlayerHotbar(player_); + player_inventory_range_= InventoryRange.fromPlayerInventory(player_); // container slotId 0 === crafting output addSlot(new CraftingOutputSlot(this, pinv.player, matrix_, result_, 0, 118, 27)); ArrayList> slotpositions = new ArrayList>(); @@ -378,7 +395,7 @@ public class EdCraftingTable // container slotId 46..53 === TE slots 9..17 (storage) for(int y=0; y<2; ++y) { for(int x=0; x<9; ++x) { - addSlot(new Slot(matrix_, 9+x+y*9, 8+x*18, 65+y*18)); + addSlot(new Slot(inventory_, 9+x+y*9, 8+x*18, 65+y*18)); } } if((!player_.world.isRemote) && (inventory_ instanceof CraftingTableTileEntity)) { @@ -522,39 +539,36 @@ public class EdCraftingTable history_.next(); syncHistory(); // implicitly clear the grid, so that the player can see the refab, and that no recipe is active. - if(clear_grid_to_player(player)) { changed = true; player_inventory_changed = true; } if(clear_grid_to_storage(player)) changed = true; + if(clear_grid_to_player(player)) { changed = true; player_inventory_changed = true; } } break; case BUTTON_PREV: { history_.prev(); syncHistory(); - if(clear_grid_to_player(player)) { changed = true; player_inventory_changed = true; } if(clear_grid_to_storage(player)) changed = true; + if(clear_grid_to_player(player)) { changed = true; player_inventory_changed = true; } } break; case BUTTON_CLEAR_GRID: { history_.reset_selection(); syncHistory(); - if(clear_grid_to_player(player)) { changed = true; player_inventory_changed = true; } if(clear_grid_to_storage(player)) changed = true; + if(clear_grid_to_player(player)) { changed = true; player_inventory_changed = true; } } break; case ACTION_PLACE_CURRENT_HISTORY_SEL: { - if(place_stacks(new SlotRange[]{ - new SlotRange(player.inventory, 0, 9), - new SlotRange(player.inventory, 9, 36), - new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS) - }, refab_crafting_stacks()) != PlacementResult.UNCHANGED) { + if(place_stacks( + new InventoryRange[]{block_storage_range_, player_storage_range_, player_hotbar_range_}, + refab_crafting_stacks()) != PlacementResult.UNCHANGED) { changed = true; } } break; case ACTION_PLACE_SHIFTCLICKED_STACK: { final int container_slot_id = nbt.getInt("containerslot"); - if((container_slot_id < 10) || (container_slot_id > 53)) { + if((container_slot_id < 10) || (container_slot_id > (46+NUM_OF_STORAGE_SLOTS))) { break; // out of range } if(container_slot_id >= 46) { // from storage - final int storage_slot = container_slot_id - 46 + STORAGE_SLOTS_BEGIN; - PlacementResult stat = distribute_stack(inventory_, storage_slot); + PlacementResult stat = distribute_stack(block_storage_range_, container_slot_id-46); if(stat != PlacementResult.UNCHANGED) changed = true; } else { // from player @@ -573,6 +587,20 @@ public class EdCraftingTable } } } break; + case ACTION_MOVE_STACK: { + final int container_slot_id = nbt.getInt("containerslot"); + if((container_slot_id < 1) || (container_slot_id >= (46+NUM_OF_STORAGE_SLOTS))) { + break; // out of range + } else if(container_slot_id < 10) { + int slot = container_slot_id; + ItemStack remaining = Inventories.insert( + new InventoryRange[] {block_storage_range_, player_storage_range_, player_hotbar_range_}, + inventory_.getStackInSlot(slot-1) + ); + changed = player_inventory_changed = (remaining.getCount()!=inventory_.getStackInSlot(slot-1).getCount()); + inventory_.setInventorySlotContents(slot-1, remaining); + } + } break; case ACTION_MOVE_ALL_STACKS: { final int container_slot_id = nbt.getInt("containerslot"); if((container_slot_id < 1) || (container_slot_id >= (46+NUM_OF_STORAGE_SLOTS))) { @@ -580,23 +608,23 @@ public class EdCraftingTable } else if(container_slot_id < 10) { // from crafting grid to player inventory, we clear the grid here as this is most likely // what is wanted in the end. Saves clicking the other grid stacks. - if(clear_grid_to_player(player)) { changed = true; player_inventory_changed = true; } if(clear_grid_to_storage(player)) changed = true; + if(clear_grid_to_player(player)) { changed = true; player_inventory_changed = true; } break; } IInventory from_inventory; - SlotRange[] to_ranges; + InventoryRange[] to_ranges; int from_slot; if(container_slot_id >= 46) { // from storage to player inventory from_inventory = inventory_; from_slot = container_slot_id - 46 + STORAGE_SLOTS_BEGIN; - to_ranges = new SlotRange[] {new SlotRange(player.inventory, 9, 36), new SlotRange(player.inventory, 0, 9)}; + to_ranges = new InventoryRange[] {player_storage_range_, player_hotbar_range_}; } else { // from player to storage (otherwise ACTION_PLACE_SHIFTCLICKED_STACK would have been used) from_inventory = player.inventory; from_slot = (container_slot_id >= 37) ? (container_slot_id-37) : (container_slot_id-10+9); - to_ranges = new SlotRange[] {new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS)}; + to_ranges = new InventoryRange[]{block_storage_range_}; } final ItemStack reference_stack = from_inventory.getStackInSlot(from_slot).copy(); if(!reference_stack.isEmpty()) { @@ -604,16 +632,8 @@ public class EdCraftingTable for(int i=0; (i < from_inventory.getSizeInventory()) && (!abort); ++i) { final ItemStack stack = from_inventory.getStackInSlot(i); if(Inventories.areItemStacksDifferent(reference_stack, stack)) continue; - ItemStack remaining = from_inventory.getStackInSlot(i); - for(SlotRange range:to_ranges) { - remaining = range.insert(remaining, false, 0, false, true); - if(!remaining.isEmpty()) { - abort = true; // no space left - break; - } else { - changed = player_inventory_changed = true; - } - } + ItemStack remaining = Inventories.insert(to_ranges, from_inventory.getStackInSlot(i)); + changed = player_inventory_changed = (remaining.getCount()!=from_inventory.getStackInSlot(i).getCount()); from_inventory.setInventorySlotContents(i, remaining); } } @@ -622,18 +642,14 @@ public class EdCraftingTable select_next_collision_recipe(inventory_); } break; case ACTION_DECREASE_CRAFTING_STACKS: { - changed = player_inventory_changed = decrease_grid_stacks(new SlotRange[]{ - new SlotRange(player.inventory, 9, 36), - new SlotRange(player.inventory, 0, 9), - new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS) - }, MathHelper.clamp(nbt.getInt("limit"), 1, 8)); + changed = player_inventory_changed = decrease_grid_stacks( + new InventoryRange[]{block_storage_range_, player_storage_range_, player_hotbar_range_}, + MathHelper.clamp(nbt.getInt("limit"), 1, 8)); } break; case ACTION_INCREASE_CRAFTING_STACKS: { - changed = player_inventory_changed = increase_grid_stacks(new SlotRange[]{ - new SlotRange(player.inventory, 9, 36), - new SlotRange(player.inventory, 0, 9), - new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS) - }, MathHelper.clamp(nbt.getInt("limit"), 1, 8)); + changed = player_inventory_changed = increase_grid_stacks( + new InventoryRange[]{block_storage_range_, player_storage_range_, player_hotbar_range_}, + MathHelper.clamp(nbt.getInt("limit"), 1, 8)); } break; } } @@ -717,26 +733,22 @@ public class EdCraftingTable .findFirst().orElse(null); } - private ItemStack search_inventory(ItemStack match_stack, ItemStack not_found_value) { - SlotRange search_ranges[] = new SlotRange[]{ - new SlotRange(player_.inventory, 0, 36), - new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS) - }; - for(SlotRange range: search_ranges) { - for(int i=0; i search_inventory(ItemStack match_stack) { + InventoryRange search_ranges[] = new InventoryRange[]{block_storage_range_, player_storage_range_, player_hotbar_range_}; + for(InventoryRange range: search_ranges) { + for(int i=0; i search_inventory(ItemStack[] match_stacks) { for(ItemStack match_stack: match_stacks) { - ItemStack stack = search_inventory(match_stack, ItemStack.EMPTY); - if(!stack.isEmpty()) return stack; + Optional stack = search_inventory(match_stack); + if(stack.isPresent()) return stack; } - return not_found_value; + return Optional.empty(); } private ArrayList placement_stacks(ICraftingRecipe recipe) @@ -756,7 +768,7 @@ public class EdCraftingTable if((w >= endw) || (ingredient_index >= recipe.getIngredients().size())) { grid.add(ItemStack.EMPTY); continue; } ItemStack[] match_stacks = recipe.getIngredients().get(ingredient_index++).getMatchingStacks(); if(match_stacks.length == 0) { grid.add(ItemStack.EMPTY); continue; } - ItemStack preferred = search_inventory(match_stacks, match_stacks[0]); + ItemStack preferred = search_inventory(match_stacks).orElse(match_stacks[0]); if(preferred.isEmpty()) { grid.add(ItemStack.EMPTY); continue; } grid.add(preferred); } @@ -765,7 +777,7 @@ public class EdCraftingTable for(int ingredient_index=0; ingredient_indexInventories.areItemStacksIdentical(s, to_replace))) { - replacement = search_inventory(match_stacks, to_replace); + replacement = search_inventory(match_stacks).orElse(to_replace); changed = true; break; } @@ -889,7 +901,7 @@ public class EdCraftingTable { final ArrayList stacks = new ArrayList(); for(int i=0; i<9; ++i) { - final ItemStack palced = inventory_.getStackInSlot(i+CRAFTING_SLOTS_BEGIN).copy(); + final ItemStack palced = crafting_grid_range_.getStackInSlot(i).copy(); if(!palced.isEmpty()) palced.setCount(count); stacks.add(palced); } @@ -897,45 +909,22 @@ public class EdCraftingTable } private boolean clear_grid_to_storage(PlayerEntity player) - { - boolean changed = false; - for(int grid_i = CRAFTING_SLOTS_BEGIN; grid_i < (CRAFTING_SLOTS_BEGIN+NUM_OF_CRAFTING_SLOTS); ++grid_i) { - ItemStack stack = inventory_.getStackInSlot(grid_i); - if(stack.isEmpty()) continue; - ItemStack remaining = (new SlotRange(inventory_, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS)).insert(stack, false, 0); - inventory_.setInventorySlotContents(grid_i, remaining); - changed = true; - } - return changed; - } + { return crafting_grid_range_.move(block_storage_range_); } private boolean clear_grid_to_player(PlayerEntity player) - { - boolean changed = false; - for(int grid_i = CRAFTING_SLOTS_BEGIN; grid_i < (CRAFTING_SLOTS_BEGIN+NUM_OF_CRAFTING_SLOTS); ++grid_i) { - ItemStack remaining = inventory_.getStackInSlot(grid_i); - if(remaining.isEmpty()) continue; - remaining = (new SlotRange(player.inventory,9, 36)).insert(remaining,true, 0); // prefer filling up inventory stacks - remaining = (new SlotRange(player.inventory,0, 9)).insert(remaining, true, 0); // then fill up the hotbar stacks - remaining = (new SlotRange(player.inventory,9, 36)).insert(remaining, false, 0); // then allow empty stacks in inventory - remaining = (new SlotRange(player.inventory,0, 9)).insert(remaining, false, 0); // then new stacks in the hotbar - inventory_.setInventorySlotContents(grid_i, remaining); - changed = true; - } - return changed; - } + { return crafting_grid_range_.move(player_inventory_range_); } - private PlacementResult place_stacks(final SlotRange[] ranges, final List to_fill) + private PlacementResult place_stacks(final InventoryRange[] ranges, final List to_fill) { if(history_.current_recipe() != null) result_.setRecipeUsed(history_.current_recipe()); boolean slots_changed = false; if(!to_fill.isEmpty()) { - for(SlotRange slot_range: ranges) { + for(InventoryRange slot_range: ranges) { for(int it_guard=63; it_guard>=0; --it_guard) { boolean slots_updated = false; for(int i = 0; i < 9; ++i) { if(to_fill.get(i).isEmpty()) continue; - ItemStack grid_stack = inventory_.getStackInSlot(i + CRAFTING_SLOTS_BEGIN).copy(); + ItemStack grid_stack = crafting_grid_range_.getStackInSlot(i).copy(); if(grid_stack.getCount() >= grid_stack.getMaxStackSize()) continue; final ItemStack req_stack = to_fill.get(i).copy(); req_stack.setCount(1); @@ -947,7 +936,7 @@ public class EdCraftingTable } else { grid_stack.grow(mv_stack.getCount()); } - inventory_.setInventorySlotContents(i + CRAFTING_SLOTS_BEGIN, grid_stack); + crafting_grid_range_.setInventorySlotContents(i, grid_stack); slots_changed = true; slots_updated = true; } @@ -971,18 +960,18 @@ public class EdCraftingTable } } - private PlacementResult distribute_stack(IInventory inventory, final int slotno) + private PlacementResult distribute_stack(IInventory inventory, final int slot_index) { List to_refab = refab_crafting_stacks(); if(history_.current_recipe() != null) result_.setRecipeUsed(history_.current_recipe()); - ItemStack to_distribute = inventory.getStackInSlot(slotno).copy(); + ItemStack to_distribute = inventory.getStackInSlot(slot_index).copy(); if(to_distribute.isEmpty()) return PlacementResult.UNCHANGED; int matching_grid_stack_sizes[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1}; int max_matching_stack_size = -1; int min_matching_stack_size = 65; int total_num_missing_stacks = 0; for(int i=0; i<9; ++i) { - final ItemStack grid_stack = inventory_.getStackInSlot(i+CRAFTING_SLOTS_BEGIN); + final ItemStack grid_stack = crafting_grid_range_.getStackInSlot(i); final ItemStack refab_stack = to_refab.isEmpty() ? ItemStack.EMPTY : to_refab.get(i).copy(); if((!grid_stack.isEmpty()) && Inventories.areItemStacksIdentical(grid_stack, to_distribute)) { matching_grid_stack_sizes[i] = grid_stack.getCount(); @@ -1004,7 +993,7 @@ public class EdCraftingTable } } if(min_matching_stack_size < 0) return PlacementResult.UNCHANGED; - final int stack_limit_size = Math.min(to_distribute.getMaxStackSize(), inventory_.getInventoryStackLimit()); + final int stack_limit_size = Math.min(to_distribute.getMaxStackSize(), crafting_grid_range_.getInventoryStackLimit()); if(min_matching_stack_size >= stack_limit_size) return PlacementResult.UNCHANGED; int n_to_distribute = to_distribute.getCount(); for(int it_guard=63; it_guard>=0; --it_guard) { @@ -1026,40 +1015,40 @@ public class EdCraftingTable } if(n_to_distribute == to_distribute.getCount()) return PlacementResult.UNCHANGED; // was already full if(n_to_distribute <= 0) { - inventory.setInventorySlotContents(slotno, ItemStack.EMPTY); + inventory.setInventorySlotContents(slot_index, ItemStack.EMPTY); } else { to_distribute.setCount(n_to_distribute); - inventory.setInventorySlotContents(slotno, to_distribute); + inventory.setInventorySlotContents(slot_index, to_distribute); } for(int i=0; i<9; ++i) { if(matching_grid_stack_sizes[i] < 0) continue; - ItemStack grid_stack = inventory_.getStackInSlot(i + CRAFTING_SLOTS_BEGIN).copy(); + ItemStack grid_stack = crafting_grid_range_.getStackInSlot(i).copy(); if(grid_stack.isEmpty()) grid_stack = to_distribute.copy(); grid_stack.setCount(matching_grid_stack_sizes[i]); - inventory_.setInventorySlotContents(i + CRAFTING_SLOTS_BEGIN, grid_stack); + crafting_grid_range_.setInventorySlotContents(i, grid_stack); } return PlacementResult.PLACED; } - private boolean decrease_grid_stacks(SlotRange[] ranges, int limit) + private boolean decrease_grid_stacks(InventoryRange[] ranges, int limit) { boolean changed = false; for(int i=0; i<9; ++i) { - ItemStack stack = inventory_.getStackInSlot(i+CRAFTING_SLOTS_BEGIN).copy(); + ItemStack stack = crafting_grid_range_.getStackInSlot(i).copy(); if(stack.isEmpty()) continue; - for(SlotRange range:ranges) { - ItemStack remaining = range.insert(stack, false, limit); + for(InventoryRange range:ranges) { + ItemStack remaining = range.insert(stack, false, limit, false, false); if(remaining.getCount() < stack.getCount()) changed = true; boolean stop = (remaining.getCount() <= Math.max(0, (stack.getCount()-limit))); stack = remaining; if(stop) break; } - inventory_.setInventorySlotContents(i+CRAFTING_SLOTS_BEGIN, stack.isEmpty() ? ItemStack.EMPTY : stack); + crafting_grid_range_.setInventorySlotContents(i, stack.isEmpty() ? ItemStack.EMPTY : stack); } return changed; } - private boolean increase_grid_stacks(SlotRange[] ranges, int limit) + private boolean increase_grid_stacks(InventoryRange[] ranges, int limit) { return place_stacks(ranges, incr_crafting_grid_stacks(limit)) != PlacementResult.UNCHANGED; } } @@ -1259,6 +1248,12 @@ public class EdCraftingTable nbt.putInt("containerslot", slotId); action(CraftingTableContainer.ACTION_MOVE_ALL_STACKS, nbt); return; + } else if((slotId > 0) && (slotId <= 9)) { + // Move from grid to storage or player inventory + CompoundNBT nbt = new CompoundNBT(); + nbt.putInt("containerslot", slotId); + action(CraftingTableContainer.ACTION_MOVE_STACK, nbt); + return; } else { // Let the normal slot click handle that. } @@ -1539,7 +1534,7 @@ public class EdCraftingTable final IRecipe recipe = ((CraftResultInventory)this.inventory).getRecipeUsed(); final ArrayList grid = new ArrayList(); grid.add(stack); - for(int i = 0; i < 9; ++i) grid.add(container.inventory_.getStackInSlot(i)); + for(int i = 0; i<9; ++i) grid.add(container.inventory_.getStackInSlot(i)); if(recipe instanceof ICraftingRecipe) { container.history().add(grid, (ICraftingRecipe)recipe); container.history().reset_current(); diff --git a/src/main/java/wile/engineersdecor/blocks/EdDropper.java b/src/main/java/wile/engineersdecor/blocks/EdDropper.java index 3a54da8..f72daae 100644 --- a/src/main/java/wile/engineersdecor/blocks/EdDropper.java +++ b/src/main/java/wile/engineersdecor/blocks/EdDropper.java @@ -8,15 +8,8 @@ */ package wile.engineersdecor.blocks; -import com.mojang.blaze3d.matrix.MatrixStack; +import net.minecraft.inventory.container.ClickType; import net.minecraft.util.math.vector.Vector3d; -import wile.engineersdecor.ModContent; -import wile.engineersdecor.ModEngineersDecor; -import wile.engineersdecor.libmc.detail.Inventories; -import wile.engineersdecor.libmc.detail.Inventories.SlotRange; -import wile.engineersdecor.libmc.detail.Networking; -import wile.engineersdecor.libmc.detail.TooltipDisplay; -import wile.engineersdecor.libmc.detail.TooltipDisplay.TipRange; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; import net.minecraft.state.BooleanProperty; @@ -57,6 +50,15 @@ import net.minecraftforge.items.wrapper.SidedInvWrapper; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.matrix.MatrixStack; +import wile.engineersdecor.ModContent; +import wile.engineersdecor.ModEngineersDecor; +import wile.engineersdecor.libmc.detail.Auxiliaries; +import wile.engineersdecor.libmc.detail.Inventories; +import wile.engineersdecor.libmc.detail.Inventories.InventoryRange; +import wile.engineersdecor.libmc.detail.Networking; +import wile.engineersdecor.libmc.detail.TooltipDisplay; +import wile.engineersdecor.libmc.detail.TooltipDisplay.TipRange; import javax.annotation.Nullable; import java.util.ArrayList; @@ -240,7 +242,7 @@ public class EdDropper private int drop_slot_index_ = 0; private int tick_timer_ = 0; protected NonNullList stacks_; - protected final SlotRange slot_range_ = new SlotRange(this, INPUT_SLOTS_FIRST, INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE); + protected final InventoryRange storage_slot_range_; public static void on_config(int cooldown_ticks) { @@ -254,6 +256,7 @@ public class EdDropper { super(te_type); stacks_ = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); + storage_slot_range_ = new InventoryRange(this, INPUT_SLOTS_FIRST, INPUT_SLOTS_SIZE); reset_rtstate(); } @@ -711,7 +714,7 @@ public class EdDropper final boolean dropped = res.getA(); final List remaining = res.getB(); for(ItemStack st:remaining) { - if(!slot_range_.insert(st).isEmpty()) ModEngineersDecor.logger().debug("NOT ALL NON-DROPPED ITEMS PUT BACK:" + st); + if(!storage_slot_range_.insert(st).isEmpty()) ModEngineersDecor.logger().debug("NOT ALL NON-DROPPED ITEMS PUT BACK:" + st); } if(dropped || (!remaining.isEmpty())) dirty = true; // cooldown @@ -737,11 +740,14 @@ public class EdDropper public static class DropperContainer extends Container implements Networking.INetworkSynchronisableContainer { + protected static final String QUICK_MOVE_ALL = "quick-move-all"; private static final int PLAYER_INV_START_SLOTNO = DropperTileEntity.NUM_OF_SLOTS; private final PlayerEntity player_; private final IInventory inventory_; private final IWorldPosCallable wpc_; private final IIntArray fields_; + private final InventoryRange player_inventory_range_; + private final InventoryRange block_storage_range_; public final int field(int index) { return fields_.get(index); } @@ -755,6 +761,8 @@ public class EdDropper wpc_ = wpc; player_ = player_inventory.player; inventory_ = block_inventory; + block_storage_range_ = new InventoryRange(inventory_, 0, DropperTileEntity.NUM_OF_SLOTS); + player_inventory_range_ = InventoryRange.fromPlayerInventory(player_); int i=-1; // input slots (stacks 0 to 11) for(int y=0; y<2; ++y) { @@ -824,6 +832,13 @@ public class EdDropper Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); } + @OnlyIn(Dist.CLIENT) + public void onGuiAction(String message, CompoundNBT nbt) + { + nbt.putString("action", message); + Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); + } + @Override public void onServerPacketReceived(int windowId, CompoundNBT nbt) {} @@ -832,16 +847,35 @@ public class EdDropper public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt) { if(!(inventory_ instanceof DropperTileEntity)) return; - DropperTileEntity te = (DropperTileEntity)inventory_; - if(nbt.contains("drop_speed")) te.drop_speed_ = MathHelper.clamp(nbt.getInt("drop_speed"), 0, 100); - if(nbt.contains("drop_xdev")) te.drop_xdev_ = MathHelper.clamp(nbt.getInt("drop_xdev"), -100, 100); - if(nbt.contains("drop_ydev")) te.drop_ydev_ = MathHelper.clamp(nbt.getInt("drop_ydev"), -100, 100); - if(nbt.contains("drop_count")) te.drop_count_ = MathHelper.clamp(nbt.getInt("drop_count"), 1, DropperTileEntity.MAX_DROP_COUNT); - if(nbt.contains("drop_period")) te.drop_period_ = MathHelper.clamp(nbt.getInt("drop_period"), 0, 100); - if(nbt.contains("drop_logic")) te.drop_logic_ = nbt.getInt("drop_logic"); - if(nbt.contains("manual_rstrigger") && (nbt.getInt("manual_rstrigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; } - if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.tick_timer_ = 1; te.triggered_ = true; } - te.markDirty(); + if(nbt.contains("action")) { + boolean changed = false; + final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1; + switch(nbt.getString("action")) { + case QUICK_MOVE_ALL: { + if((slotId >= 0) && (slotId < PLAYER_INV_START_SLOTNO) && (getSlot(slotId).getHasStack())) { + changed = block_storage_range_.move(getSlot(slotId).getSlotIndex(), player_inventory_range_, true, false, true, true); + } else if((slotId >= PLAYER_INV_START_SLOTNO) && (slotId < PLAYER_INV_START_SLOTNO+36) && (getSlot(slotId).getHasStack())) { + changed = player_inventory_range_.move(getSlot(slotId).getSlotIndex(), block_storage_range_, true, false, false, true); + } + } break; + } + if(changed) { + inventory_.markDirty(); + player.inventory.markDirty(); + detectAndSendChanges(); + } + } else { + DropperTileEntity te = (DropperTileEntity)inventory_; + if(nbt.contains("drop_speed")) te.drop_speed_ = MathHelper.clamp(nbt.getInt("drop_speed"), 0, 100); + if(nbt.contains("drop_xdev")) te.drop_xdev_ = MathHelper.clamp(nbt.getInt("drop_xdev"), -100, 100); + if(nbt.contains("drop_ydev")) te.drop_ydev_ = MathHelper.clamp(nbt.getInt("drop_ydev"), -100, 100); + if(nbt.contains("drop_count")) te.drop_count_ = MathHelper.clamp(nbt.getInt("drop_count"), 1, DropperTileEntity.MAX_DROP_COUNT); + if(nbt.contains("drop_period")) te.drop_period_ = MathHelper.clamp(nbt.getInt("drop_period"), 0, 100); + if(nbt.contains("drop_logic")) te.drop_logic_ = nbt.getInt("drop_logic"); + if(nbt.contains("manual_rstrigger") && (nbt.getInt("manual_rstrigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; } + if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.tick_timer_ = 1; te.triggered_ = true; } + te.markDirty(); + } } } @@ -944,6 +978,19 @@ public class EdDropper return true; } + @Override + protected void handleMouseClick(Slot slot, int slotId, int button, ClickType type) + { + tooltip_.resetTimer(); + if((type == ClickType.QUICK_MOVE) && (slot!=null) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) { + CompoundNBT nbt = new CompoundNBT(); + nbt.putInt("slot", slotId); + container.onGuiAction(DropperContainer.QUICK_MOVE_ALL, nbt); + } else { + super.handleMouseClick(slot, slotId, button, type); + } + } + @Override @SuppressWarnings("deprecation") protected void drawGuiContainerBackgroundLayer(MatrixStack mx, float partialTicks, int mouseX, int mouseY) diff --git a/src/main/java/wile/engineersdecor/blocks/EdElectricalFurnace.java b/src/main/java/wile/engineersdecor/blocks/EdElectricalFurnace.java index 374fa9d..a2eb525 100644 --- a/src/main/java/wile/engineersdecor/blocks/EdElectricalFurnace.java +++ b/src/main/java/wile/engineersdecor/blocks/EdElectricalFurnace.java @@ -110,7 +110,6 @@ public class EdElectricalFurnace @OnlyIn(Dist.CLIENT) public void animateTick(BlockState state, World world, BlockPos pos, Random rnd) {} - } //-------------------------------------------------------------------------------------------------------------------- @@ -136,7 +135,7 @@ public class EdElectricalFurnace public static final int FIFO_INPUT_1_SLOT_NO = 4; public static final int FIFO_OUTPUT_0_SLOT_NO = 5; public static final int FIFO_OUTPUT_1_SLOT_NO = 6; - public static final int DEFAULT_SPEED_PERCENT = 200; + public static final int DEFAULT_SPEED_PERCENT = 250; public static final int DEFAULT_ENERGY_CONSUMPTION = 16; public static final int DEFAULT_SCALED_ENERGY_CONSUMPTION = DEFAULT_ENERGY_CONSUMPTION * HEAT_INCREMENT * DEFAULT_SPEED_PERCENT / 100; diff --git a/src/main/java/wile/engineersdecor/blocks/EdFurnace.java b/src/main/java/wile/engineersdecor/blocks/EdFurnace.java index e8efc83..72a149d 100644 --- a/src/main/java/wile/engineersdecor/blocks/EdFurnace.java +++ b/src/main/java/wile/engineersdecor/blocks/EdFurnace.java @@ -586,7 +586,10 @@ public class EdFurnace } if(burning() && canSmeltCurrentItem()) { proc_time_elapsed_ += TICK_INTERVAL * proc_speed_; - if(heater_inserted_ && (boost_energy_ >= boost_energy_consumption)) { boost_energy_ = 0; proc_time_elapsed_ += TICK_INTERVAL; } + if(heater_inserted_ && (boost_energy_ >= boost_energy_consumption)) { + boost_energy_ = 0; + proc_time_elapsed_ += (TICK_INTERVAL * proc_speed_)*2; + } if(proc_time_elapsed_ >= proc_time_needed_) { proc_time_elapsed_ = 0; proc_time_needed_ = getSmeltingTimeNeeded(world, stacks_.get(SMELTING_INPUT_SLOT_NO)); diff --git a/src/main/java/wile/engineersdecor/blocks/EdHopper.java b/src/main/java/wile/engineersdecor/blocks/EdHopper.java index afdcf97..cca1d74 100644 --- a/src/main/java/wile/engineersdecor/blocks/EdHopper.java +++ b/src/main/java/wile/engineersdecor/blocks/EdHopper.java @@ -52,7 +52,7 @@ import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.libmc.detail.Auxiliaries; import wile.engineersdecor.libmc.detail.Inventories; import wile.engineersdecor.libmc.detail.Networking; -import wile.engineersdecor.libmc.detail.Inventories.SlotRange; +import wile.engineersdecor.libmc.detail.Inventories.InventoryRange; import wile.engineersdecor.libmc.detail.TooltipDisplay; import wile.engineersdecor.libmc.detail.TooltipDisplay.TipRange; @@ -703,8 +703,8 @@ public class EdHopper protected static final int STORAGE_SLOT_END = HopperTileEntity.NUM_OF_SLOTS; protected static final int PLAYER_SLOT_BEGIN = HopperTileEntity.NUM_OF_SLOTS; protected static final int PLAYER_SLOT_END = HopperTileEntity.NUM_OF_SLOTS+36; - private final SlotRange player_inventory_slot_range; - private final SlotRange hopper_slot_range; + private final InventoryRange player_inventory_range_; + private final InventoryRange block_storage_range_; private final PlayerEntity player_; private final IInventory inventory_; private final IWorldPosCallable wpc_; @@ -722,8 +722,8 @@ public class EdHopper wpc_ = wpc; player_ = player_inventory.player; inventory_ = block_inventory; - hopper_slot_range = new SlotRange(inventory_, 0, HopperTileEntity.NUM_OF_SLOTS); - player_inventory_slot_range = new SlotRange(player_inventory, 0, 36); + block_storage_range_ = new InventoryRange(inventory_, 0, HopperTileEntity.NUM_OF_SLOTS); + player_inventory_range_ = InventoryRange.fromPlayerInventory(player_); int i=-1; // input slots (stacks 0 to 17) for(int y=0; y<3; ++y) { @@ -816,35 +816,10 @@ public class EdHopper switch(nbt.getString("action")) { case QUICK_MOVE_ALL: { if((slotId >= STORAGE_SLOT_BEGIN) && (slotId < STORAGE_SLOT_END) && (getSlot(slotId).getHasStack())) { - final Slot slot = getSlot(slotId); - ItemStack remaining = slot.getStack(); - slot.putStack(ItemStack.EMPTY); - final ItemStack ref_stack = remaining.copy(); - ref_stack.setCount(ref_stack.getMaxStackSize()); - for(int i=hopper_slot_range.end_slot-hopper_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) { - remaining = player_inventory_slot_range.insert(remaining, false, 0, true, true); - if(!remaining.isEmpty()) break; - remaining = hopper_slot_range.extract(ref_stack); - } - if(!remaining.isEmpty()) { - slot.putStack(remaining); // put back - } + changed = block_storage_range_.move(getSlot(slotId).getSlotIndex(), player_inventory_range_, true, false, true, true); } else if((slotId >= PLAYER_SLOT_BEGIN) && (slotId < PLAYER_SLOT_END) && (getSlot(slotId).getHasStack())) { - final Slot slot = getSlot(slotId); - ItemStack remaining = slot.getStack(); - slot.putStack(ItemStack.EMPTY); - final ItemStack ref_stack = remaining.copy(); - ref_stack.setCount(ref_stack.getMaxStackSize()); - for(int i=player_inventory_slot_range.end_slot-player_inventory_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) { - remaining = hopper_slot_range.insert(remaining, false, 0, false, true); - if(!remaining.isEmpty()) break; - remaining = player_inventory_slot_range.extract(ref_stack); - } - if(!remaining.isEmpty()) { - slot.putStack(remaining); // put back - } + changed = player_inventory_range_.move(getSlot(slotId).getSlotIndex(), block_storage_range_, true, false, false, true); } - changed = true; } break; } if(changed) { @@ -855,7 +830,6 @@ public class EdHopper } te.markDirty(); } - } //-------------------------------------------------------------------------------------------------------------------- diff --git a/src/main/java/wile/engineersdecor/blocks/EdLabeledCrate.java b/src/main/java/wile/engineersdecor/blocks/EdLabeledCrate.java index bba1084..dd2025a 100644 --- a/src/main/java/wile/engineersdecor/blocks/EdLabeledCrate.java +++ b/src/main/java/wile/engineersdecor/blocks/EdLabeledCrate.java @@ -13,7 +13,6 @@ import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.libmc.blocks.StandardBlocks; import wile.engineersdecor.libmc.detail.Auxiliaries; import wile.engineersdecor.libmc.detail.Inventories.InventoryRange; -import wile.engineersdecor.libmc.detail.Inventories.SlotRange; import wile.engineersdecor.libmc.detail.Networking; import net.minecraft.world.IBlockReader; import net.minecraft.world.server.ServerWorld; @@ -571,8 +570,9 @@ public class EdLabeledCrate protected final IInventory inventory_; protected final IWorldPosCallable wpc_; private final IIntArray fields_; - private final SlotRange player_inventory_slot_range; - private final SlotRange crate_slot_range; + private final InventoryRange player_inventory_range_; + private final InventoryRange block_storage_range_; + private final InventoryRange frame_slot_range_; //------------------------------------------------------------------------------------------------------------------ public int field(int index) { return fields_.get(index); } public PlayerEntity player() { return player_ ; } @@ -590,8 +590,9 @@ public class EdLabeledCrate inventory_ = block_inventory; wpc_ = wpc; fields_ = fields; - crate_slot_range = new SlotRange(inventory_, 0, LabeledCrateTileEntity.ITEMFRAME_SLOTNO); - player_inventory_slot_range = new SlotRange(player_inventory, 0, 36); + block_storage_range_ = new InventoryRange(inventory_, 0, LabeledCrateTileEntity.ITEMFRAME_SLOTNO); + player_inventory_range_ = new InventoryRange(player_inventory, 0, 36); + frame_slot_range_ = new InventoryRange(inventory_, 54, 1); int i=-1; // storage slots (stacks 0 to 53) for(int y=0; y<6; ++y) { @@ -601,9 +602,7 @@ public class EdLabeledCrate } } // picture frame slot (54) - addSlot(new Slot(new InventoryRange(inventory_, 54, 1), 0, 191, 100) { - @Override public int getSlotStackLimit(){return 1;} - }); + addSlot(new Slot(frame_slot_range_, 0, 191, 100) { @Override public int getSlotStackLimit(){return 1;} }); // player slots for(int x=0; x<9; ++x) { addSlot(new Slot(player_inventory, x, 28+x*18, 183)); // player slots: 0..8 @@ -676,35 +675,10 @@ public class EdLabeledCrate switch(nbt.getString("action")) { case QUICK_MOVE_ALL: { if((slotId >= STORAGE_SLOT_BEGIN) && (slotId < STORAGE_SLOT_END) && (getSlot(slotId).getHasStack())) { - final Slot slot = getSlot(slotId); - ItemStack remaining = slot.getStack(); - slot.putStack(ItemStack.EMPTY); - final ItemStack ref_stack = remaining.copy(); - ref_stack.setCount(ref_stack.getMaxStackSize()); - for(int i=crate_slot_range.end_slot-crate_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) { - remaining = player_inventory_slot_range.insert(remaining, false, 0, true, true); - if(!remaining.isEmpty()) break; - remaining = crate_slot_range.extract(ref_stack); - } - if(!remaining.isEmpty()) { - slot.putStack(remaining); // put back - } + changed = block_storage_range_.move(getSlot(slotId).getSlotIndex(), player_inventory_range_, true, false, true, true); } else if((slotId >= PLAYER_SLOT_BEGIN) && (slotId < PLAYER_SLOT_END) && (getSlot(slotId).getHasStack())) { - final Slot slot = getSlot(slotId); - ItemStack remaining = slot.getStack(); - slot.putStack(ItemStack.EMPTY); - final ItemStack ref_stack = remaining.copy(); - ref_stack.setCount(ref_stack.getMaxStackSize()); - for(int i=player_inventory_slot_range.end_slot-player_inventory_slot_range.start_slot; (i>0) && (!remaining.isEmpty()); --i) { - remaining = crate_slot_range.insert(remaining, false, 0, false, true); - if(!remaining.isEmpty()) break; - remaining = player_inventory_slot_range.extract(ref_stack); - } - if(!remaining.isEmpty()) { - slot.putStack(remaining); // put back - } + changed = player_inventory_range_.move(getSlot(slotId).getSlotIndex(), block_storage_range_, true, false, false, true); } - changed = true; } break; case INCREASE_STACK: { } break; diff --git a/src/main/java/wile/engineersdecor/blocks/EdPlacer.java b/src/main/java/wile/engineersdecor/blocks/EdPlacer.java index 05fbed7..a06a25a 100644 --- a/src/main/java/wile/engineersdecor/blocks/EdPlacer.java +++ b/src/main/java/wile/engineersdecor/blocks/EdPlacer.java @@ -9,9 +9,12 @@ package wile.engineersdecor.blocks; import com.mojang.blaze3d.matrix.MatrixStack; +import net.minecraft.inventory.container.ClickType; import net.minecraft.util.math.vector.Vector3d; import wile.engineersdecor.ModContent; import wile.engineersdecor.ModEngineersDecor; +import wile.engineersdecor.libmc.detail.Auxiliaries; +import wile.engineersdecor.libmc.detail.Inventories.InventoryRange; import wile.engineersdecor.libmc.detail.Networking; import net.minecraft.block.*; import net.minecraft.world.IBlockReader; @@ -600,11 +603,14 @@ public class EdPlacer public static class PlacerContainer extends Container implements Networking.INetworkSynchronisableContainer { + protected static final String QUICK_MOVE_ALL = "quick-move-all"; private static final int PLAYER_INV_START_SLOTNO = PlacerTileEntity.NUM_OF_SLOTS; private final PlayerEntity player_; private final IInventory inventory_; private final IWorldPosCallable wpc_; private final IIntArray fields_; + private final InventoryRange player_inventory_range_; + private final InventoryRange block_storage_range_; public final int field(int index) { return fields_.get(index); } @@ -618,6 +624,8 @@ public class EdPlacer wpc_ = wpc; player_ = player_inventory.player; inventory_ = block_inventory; + block_storage_range_ = new InventoryRange(inventory_, 0, PlacerTileEntity.NUM_OF_SLOTS); + player_inventory_range_ = InventoryRange.fromPlayerInventory(player_); int i=-1; // device slots (stacks 0 to 17) for(int y=0; y<3; ++y) { @@ -683,6 +691,13 @@ public class EdPlacer Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); } + @OnlyIn(Dist.CLIENT) + public void onGuiAction(String message, CompoundNBT nbt) + { + nbt.putString("action", message); + Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); + } + @Override public void onServerPacketReceived(int windowId, CompoundNBT nbt) {} @@ -691,10 +706,30 @@ public class EdPlacer public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt) { if(!(inventory_ instanceof PlacerTileEntity)) return; - PlacerTileEntity te = (PlacerTileEntity)inventory_; - if(nbt.contains("logic")) te.logic_ = nbt.getInt("logic"); - if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; } - te.markDirty(); + if(nbt.contains("action")) { + boolean changed = false; + final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1; + switch(nbt.getString("action")) { + case QUICK_MOVE_ALL: { + if((slotId >= 0) && (slotId < PLAYER_INV_START_SLOTNO) && (getSlot(slotId).getHasStack())) { + changed = block_storage_range_.move(getSlot(slotId).getSlotIndex(), player_inventory_range_, true, false, true, true); + } else if((slotId >= PLAYER_INV_START_SLOTNO) && (slotId < PLAYER_INV_START_SLOTNO+36) && (getSlot(slotId).getHasStack())) { + changed = player_inventory_range_.move(getSlot(slotId).getSlotIndex(), block_storage_range_, true, false, false, true); + } + } break; + } + if(changed) { + inventory_.markDirty(); + player.inventory.markDirty(); + detectAndSendChanges(); + } + } else { + PlacerTileEntity te = (PlacerTileEntity)inventory_; + if(nbt.contains("logic")) te.logic_ = nbt.getInt("logic"); + if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; } + te.markDirty(); + } + } } @@ -756,6 +791,19 @@ public class EdPlacer return true; } + @Override + protected void handleMouseClick(Slot slot, int slotId, int button, ClickType type) + { + tooltip_.resetTimer(); + if((type == ClickType.QUICK_MOVE) && (slot!=null) && slot.getHasStack() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) { + CompoundNBT nbt = new CompoundNBT(); + nbt.putInt("slot", slotId); + container.onGuiAction(PlacerContainer.QUICK_MOVE_ALL, nbt); + } else { + super.handleMouseClick(slot, slotId, button, type); + } + } + @Override @SuppressWarnings("deprecation") protected void drawGuiContainerBackgroundLayer/*drawGuiContainerBackgroundLayer*/(MatrixStack mx, float partialTicks, int mouseX, int mouseY) diff --git a/src/main/java/wile/engineersdecor/detail/ExternalObjects.java b/src/main/java/wile/engineersdecor/detail/ExternalObjects.java index 66d49ec..cd4bb61 100644 --- a/src/main/java/wile/engineersdecor/detail/ExternalObjects.java +++ b/src/main/java/wile/engineersdecor/detail/ExternalObjects.java @@ -14,7 +14,7 @@ import net.minecraftforge.registries.ObjectHolder; public class ExternalObjects { - @ObjectHolder("immersiveengineering:external_heater") + @ObjectHolder("immersiveengineering:furnace_heater") public static final Item IE_EXTERNAL_HEATER = null; @ObjectHolder("bottledmilk:milk_bottle_drinkable") diff --git a/src/main/java/wile/engineersdecor/libmc/detail/Inventories.java b/src/main/java/wile/engineersdecor/libmc/detail/Inventories.java index 16140e9..373f2ee 100644 --- a/src/main/java/wile/engineersdecor/libmc/detail/Inventories.java +++ b/src/main/java/wile/engineersdecor/libmc/detail/Inventories.java @@ -18,6 +18,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.NonNullList; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.world.World; import net.minecraft.inventory.IInventory; import net.minecraft.inventory.ISidedInventory; @@ -33,7 +34,6 @@ import java.util.List; public class Inventories { - public static boolean areItemStacksIdentical(ItemStack a, ItemStack b) { return (a.getItem()==b.getItem()) && ItemStack.areItemStackTagsEqual(a, b); } @@ -98,190 +98,46 @@ public class Inventories } private static ItemStack checked(ItemStack stack) - { return stack.isEmpty() ? ItemStack.EMPTY : stack; } // explicit EMPTY return + { return stack.isEmpty() ? ItemStack.EMPTY : stack; } //-------------------------------------------------------------------------------------------------------------------- - public static class SlotRange + public static ItemStack insert(InventoryRange to_ranges[], ItemStack stack) { - public final IInventory inventory; - public final int start_slot, end_slot; - - public SlotRange(IInventory inv, int start, int end) - { inventory=inv; start_slot=start; end_slot=end; } - - /** - * Returns the number of stacks that match the given stack with NBT. - */ - public int stackMatchCount(final ItemStack ref_stack) - { - int n = 0; // ... std::accumulate() the old school way. - for(int i = start_slot; i < end_slot; ++i) { - if(areItemStacksIdentical(ref_stack, inventory.getStackInSlot(i))) ++n; - } - return n; - } - - public int totalMatchingItemCount(final ItemStack ref_stack) - { - int n = 0; - for(int i = start_slot; i < end_slot; ++i) { - ItemStack stack = inventory.getStackInSlot(i); - if(areItemStacksIdentical(ref_stack, stack)) n += stack.getCount(); - } - return n; - } - - /** - * Moves as much items from the stack to the slots in range [start_slot, end_slot] of the inventory, - * filling up existing stacks first, then (player inventory only) checks appropriate empty slots next - * to stacks that have that item already, and last uses any empty slot that can be found. - * Returns the stack that is still remaining in the referenced `stack`. - */ - public ItemStack insert(final ItemStack stack_to_move, boolean only_fillup, int limit, boolean reverse, boolean force_group_stacks) - { - final ItemStack mvstack = stack_to_move.copy(); - if((mvstack.isEmpty()) || (start_slot < 0) || (end_slot > inventory.getSizeInventory())) return checked(mvstack); - int limit_left = (limit>0) ? (Math.min(limit, mvstack.getMaxStackSize())) : (mvstack.getMaxStackSize()); - boolean matches[] = new boolean[end_slot]; - boolean empties[] = new boolean[end_slot]; - int num_matches = 0; - for(int i = start_slot; i < end_slot; ++i) { - final int sno = reverse ? (end_slot-1-i) : (i); - final ItemStack stack = inventory.getStackInSlot(sno); - if(stack.isEmpty()) { - empties[sno] = true; - } else if(areItemStacksIdentical(stack, mvstack)) { - matches[sno] = true; - ++num_matches; - } - } - // first iteration: fillup existing stacks - for(int i = start_slot; i < end_slot; ++i) { - final int sno = reverse ? (end_slot-1-i) : (i); - if((empties[sno]) || (!matches[sno])) continue; - final ItemStack stack = inventory.getStackInSlot(sno); - int nmax = Math.min(limit_left, stack.getMaxStackSize() - stack.getCount()); - if(mvstack.getCount() <= nmax) { - stack.setCount(stack.getCount()+mvstack.getCount()); - inventory.setInventorySlotContents(sno, stack); - return ItemStack.EMPTY; - } else { - stack.grow(nmax); - mvstack.shrink(nmax); - inventory.setInventorySlotContents(sno, stack); - limit_left -= nmax; - } - } - if(only_fillup) return checked(mvstack); - if((num_matches>0) && ((force_group_stacks) || (inventory instanceof PlayerInventory))) { - // second iteration: use appropriate empty slots, - // a) between - { - int insert_start = -1; - int insert_end = -1; - int i = start_slot+1; - for(;i < end_slot-1; ++i) { - final int sno = reverse ? (end_slot-1-i) : (i); - if(insert_start < 0) { - if(matches[sno]) insert_start = sno; - } else if(matches[sno]) { - insert_end = sno; - } - } - for(i=insert_start;i < insert_end; ++i) { - final int sno = reverse ? (end_slot-1-i) : (i); - if((!empties[sno]) || (!inventory.isItemValidForSlot(sno, mvstack))) continue; - int nmax = Math.min(limit_left, mvstack.getCount()); - ItemStack moved = mvstack.copy(); - moved.setCount(nmax); - mvstack.shrink(nmax); - inventory.setInventorySlotContents(sno, moved); - return checked(mvstack); - } - } - // b) before/after - { - for(int i = start_slot+1; i < end_slot-1; ++i) { - final int sno = reverse ? (end_slot-1-i) : (i); - if(!matches[sno]) continue; - int ii = (empties[sno-1]) ? (sno-1) : (empties[sno+1] ? (sno+1) : -1); - if((ii >= 0) && (inventory.isItemValidForSlot(ii, mvstack))) { - int nmax = Math.min(limit_left, mvstack.getCount()); - ItemStack moved = mvstack.copy(); - moved.setCount(nmax); - mvstack.shrink(nmax); - inventory.setInventorySlotContents(ii, moved); - return checked(mvstack); - } - } - } - } - // third iteration: use any empty slots - for(int i = start_slot; i < end_slot; ++i) { - final int sno = reverse ? (end_slot-1-i) : (i); - if((!empties[sno]) || (!inventory.isItemValidForSlot(sno, mvstack))) continue; - int nmax = Math.min(limit_left, mvstack.getCount()); - ItemStack placed = mvstack.copy(); - placed.setCount(nmax); - mvstack.shrink(nmax); - inventory.setInventorySlotContents(sno, placed); - return checked(mvstack); - } - return checked(mvstack); - } - - public ItemStack insert(final ItemStack stack_to_move, boolean only_fillup, int limit) - { return insert(stack_to_move, only_fillup, limit, false, false); } - - public ItemStack insert(final ItemStack stack_to_move, boolean only_fillup) - { return insert(stack_to_move, only_fillup, 0, false, false); } - - public ItemStack insert(final ItemStack stack_to_move) - { return insert(stack_to_move, false, 0, false, false); } - - /** - * Moves as much items from the slots in range [start_slot, end_slot] of the inventory into a new stack. - * Implicitly shrinks the inventory stacks and the `request_stack`. - */ - public ItemStack extract(final ItemStack request_stack) - { - if(request_stack.isEmpty()) return ItemStack.EMPTY; - final IInventory inventory = this.inventory; - List matches = new ArrayList<>(); - for(int i = start_slot; i < end_slot; ++i) { - final ItemStack stack = inventory.getStackInSlot(i); - if((!stack.isEmpty()) && (areItemStacksIdentical(stack, request_stack))) { - if(stack.hasTag()) { - final CompoundNBT nbt = stack.getTag(); - int n = nbt.size(); - if((n > 0) && (nbt.contains("Damage"))) --n; - if(n > 0) continue; - } - matches.add(stack); - } - } - matches.sort((a,b) -> Integer.compare(a.getCount(), b.getCount())); - if(matches.isEmpty()) return ItemStack.EMPTY; - int n_left = request_stack.getCount(); - ItemStack fetched_stack = matches.get(0).split(n_left); - n_left -= fetched_stack.getCount(); - for(int i=1; (i0); ++i) { - ItemStack stack = matches.get(i).split(n_left); - n_left -= stack.getCount(); - fetched_stack.grow(stack.getCount()); - } - return checked(fetched_stack); + ItemStack remaining = stack.copy(); + for(InventoryRange range:to_ranges) { + remaining = range.insert(remaining, false, 0, false, true); + if(remaining.isEmpty()) return remaining; } + return remaining; } public static class InventoryRange implements IInventory { public final IInventory inventory; - public final int offset, size; + public final int offset, size, num_rows; + + public InventoryRange(IInventory inventory, int offset, int size, int num_rows) + { + this.inventory = inventory; + this.offset = MathHelper.clamp(offset, 0, inventory.getSizeInventory()-1); + this.size = MathHelper.clamp(size, 0, inventory.getSizeInventory()-this.offset); + this.num_rows = num_rows; + } public InventoryRange(IInventory inventory, int offset, int size) - { this.inventory = inventory; this.offset = offset; this.size = size; } + { this(inventory, offset, size, 1); } + + public static InventoryRange fromPlayerHotbar(PlayerEntity player) + { return new InventoryRange(player.inventory, 0, 9, 1); } + + public static InventoryRange fromPlayerStorage(PlayerEntity player) + { return new InventoryRange(player.inventory, 9, 27, 3); } + + public static InventoryRange fromPlayerInventory(PlayerEntity player) + { return new InventoryRange(player.inventory, 0, 36, 4); } + + // IInventory ------------------------------------------------------------------------------------------------------ public void clear() { inventory.clear(); } @@ -321,6 +177,213 @@ public class Inventories public boolean isItemValidForSlot(int index, ItemStack stack) { return inventory.isItemValidForSlot(offset+index, stack); } + + //------------------------------------------------------------------------------------------------------------------ + + /** + * Returns the number of stacks that match the given stack with NBT. + */ + public int stackMatchCount(final ItemStack ref_stack) + { + int n = 0; // ... std::accumulate() the old school way. + for(int i=0; i0) ? (Math.min(limit, mvstack.getMaxStackSize())) : (mvstack.getMaxStackSize()); + boolean matches[] = new boolean[size]; + boolean empties[] = new boolean[size]; + int num_matches = 0; + for(int i=0; i < size; ++i) { + final int sno = reverse ? (size-1-i) : (i); + final ItemStack stack = getStackInSlot(sno); + if(stack.isEmpty()) { + empties[sno] = true; + } else if(areItemStacksIdentical(stack, mvstack)) { + matches[sno] = true; + ++num_matches; + } + } + // first iteration: fillup existing stacks + for(int i=0; i0) && ((force_group_stacks) || (inventory instanceof PlayerInventory))) { + // second iteration: use appropriate empty slots, + // a) between + { + int insert_start = -1; + int insert_end = -1; + int i = 1; + for(;i= 0) && (isItemValidForSlot(ii, mvstack))) { + int nmax = Math.min(limit_left, mvstack.getCount()); + ItemStack moved = mvstack.copy(); + moved.setCount(nmax); + mvstack.shrink(nmax); + setInventorySlotContents(ii, moved); + return checked(mvstack); + } + } + } + } + // third iteration: use any empty slots + for(int i=0; i matches = new ArrayList<>(); + for(int i=0; i 0) && (nbt.contains("Damage"))) --n; + if(n > 0) continue; + } + matches.add(stack); + } + } + matches.sort((a,b) -> Integer.compare(a.getCount(), b.getCount())); + if(matches.isEmpty()) return ItemStack.EMPTY; + int n_left = request_stack.getCount(); + ItemStack fetched_stack = matches.get(0).split(n_left); + n_left -= fetched_stack.getCount(); + for(int i=1; (i0); ++i) { + ItemStack stack = matches.get(i).split(n_left); + n_left -= stack.getCount(); + fetched_stack.grow(stack.getCount()); + } + return checked(fetched_stack); + } + + /** + * Moves items from this inventory range to another. Returns true if something was moved + * (if the inventories should be marked dirty). + */ + public boolean move(int index, final InventoryRange target_range, boolean all_identical_stacks, boolean only_fillup, boolean reverse, boolean force_group_stacks) + { + final ItemStack source_stack = getStackInSlot(index); + if(source_stack.isEmpty()) return false; + if(!all_identical_stacks) { + ItemStack remaining = target_range.insert(source_stack, only_fillup, 0, reverse, force_group_stacks); + setInventorySlotContents(index, remaining); + return (remaining.getCount() != source_stack.getCount()); + } else { + ItemStack remaining = source_stack.copy(); + setInventorySlotContents(index, ItemStack.EMPTY); + final ItemStack ref_stack = remaining.copy(); + ref_stack.setCount(ref_stack.getMaxStackSize()); + for(int i=size; (i>0) && (!remaining.isEmpty()); --i) { + remaining = target_range.insert(remaining, only_fillup, 0, reverse, force_group_stacks); + if(!remaining.isEmpty()) break; + remaining = this.extract(ref_stack); + } + if(!remaining.isEmpty()) { + setInventorySlotContents(index, remaining); // put back + } + return (remaining.getCount() != source_stack.getCount()); + } + } + + public boolean move(int index, final InventoryRange target_range) + { return move(index, target_range, false, false, false, true); } + + /** + * Moves/clears the complete range to another range if possible. Returns true if something was moved + * (if the inventories should be marked dirty). + */ + public boolean move(final InventoryRange target_range, boolean only_fillup, boolean reverse, boolean force_group_stacks) + { + boolean changed = false; + for(int i=0; i