Crafting Table grid shift/ctrl-click interactions go first to storage, then to player inventory. Fixed Lab Furnace speed boost using IE External Heater.
This commit is contained in:
parent
a730143176
commit
ed54eea0bd
12 changed files with 481 additions and 373 deletions
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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).
|
||||
|
|
|
@ -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<ItemStack> stacks = NonNullList.<ItemStack>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<Tuple<Integer,Integer>> 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<Tuple<Integer,Integer>> slotpositions = new ArrayList<Tuple<Integer,Integer>>();
|
||||
|
@ -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<range.inventory.getSizeInventory(); ++i) {
|
||||
ItemStack stack = range.inventory.getStackInSlot(i);
|
||||
if(Inventories.areItemStacksIdentical(stack, match_stack)) return match_stack;
|
||||
private Optional<ItemStack> 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<range.getSizeInventory(); ++i) {
|
||||
if(Inventories.areItemStacksIdentical(range.getStackInSlot(i), match_stack)) return Optional.of(match_stack);
|
||||
}
|
||||
}
|
||||
return not_found_value;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private ItemStack search_inventory(ItemStack[] match_stacks, ItemStack not_found_value) {
|
||||
private Optional<ItemStack> 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<ItemStack> stack = search_inventory(match_stack);
|
||||
if(stack.isPresent()) return stack;
|
||||
}
|
||||
return not_found_value;
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private ArrayList<ItemStack> 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_index<recipe.getIngredients().size(); ++ingredient_index) {
|
||||
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);
|
||||
}
|
||||
|
@ -781,11 +793,11 @@ public class EdCraftingTable
|
|||
for(int stack_index=0; stack_index < grid_stacks.size(); ++stack_index) {
|
||||
ItemStack to_replace = grid_stacks.get(stack_index);
|
||||
ItemStack replacement = to_replace;
|
||||
if(to_replace.isEmpty() || (!search_inventory(to_replace, ItemStack.EMPTY).isEmpty())) continue; // no replacement needed
|
||||
if(to_replace.isEmpty() || (search_inventory(to_replace).isPresent())) continue; // no replacement needed
|
||||
for(int ingredient_index=0; ingredient_index<recipe.getIngredients().size(); ++ingredient_index) {
|
||||
ItemStack[] match_stacks = recipe.getIngredients().get(ingredient_index).getMatchingStacks();
|
||||
if(Arrays.stream(match_stacks).anyMatch(s->Inventories.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<ItemStack> stacks = new ArrayList<ItemStack>();
|
||||
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<ItemStack> to_fill)
|
||||
private PlacementResult place_stacks(final InventoryRange[] ranges, final List<ItemStack> 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<ItemStack> 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<ItemStack> grid = new ArrayList<ItemStack>();
|
||||
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();
|
||||
|
|
|
@ -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<ItemStack> 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.<ItemStack>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<ItemStack> 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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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<ItemStack> 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; (i<matches.size()) && (n_left>0); ++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; i<size; ++i) {
|
||||
if(areItemStacksIdentical(ref_stack, getStackInSlot(i))) ++n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
public int totalMatchingItemCount(final ItemStack ref_stack)
|
||||
{
|
||||
int n = 0;
|
||||
for(int i=0; i<size; ++i) {
|
||||
ItemStack stack = getStackInSlot(i);
|
||||
if(areItemStacksIdentical(ref_stack, stack)) n += stack.getCount();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves as much items from the stack to the slots in range [offset, 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 input_stack, boolean only_fillup, int limit, boolean reverse, boolean force_group_stacks)
|
||||
{
|
||||
final ItemStack mvstack = input_stack.copy();
|
||||
//final int end_slot = offset + size;
|
||||
if(mvstack.isEmpty()) return checked(mvstack);
|
||||
int limit_left = (limit>0) ? (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; i<size; ++i) {
|
||||
final int sno = reverse ? (size-1-i) : (i);
|
||||
if((empties[sno]) || (!matches[sno])) continue;
|
||||
final ItemStack stack = getStackInSlot(sno);
|
||||
int nmax = Math.min(limit_left, stack.getMaxStackSize() - stack.getCount());
|
||||
if(mvstack.getCount() <= nmax) {
|
||||
stack.setCount(stack.getCount()+mvstack.getCount());
|
||||
setInventorySlotContents(sno, stack);
|
||||
return ItemStack.EMPTY;
|
||||
} else {
|
||||
stack.grow(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
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 = 1;
|
||||
for(;i<size-1; ++i) {
|
||||
final int sno = reverse ? (size-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 ? (size-1-i) : (i);
|
||||
if((!empties[sno]) || (!isItemValidForSlot(sno, mvstack))) continue;
|
||||
int nmax = Math.min(limit_left, mvstack.getCount());
|
||||
ItemStack moved = mvstack.copy();
|
||||
moved.setCount(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
setInventorySlotContents(sno, moved);
|
||||
return checked(mvstack);
|
||||
}
|
||||
}
|
||||
// b) before/after
|
||||
{
|
||||
for(int i=1; i<size-1; ++i) {
|
||||
final int sno = reverse ? (size-1-i) : (i);
|
||||
if(!matches[sno]) continue;
|
||||
int ii = (empties[sno-1]) ? (sno-1) : (empties[sno+1] ? (sno+1) : -1);
|
||||
if((ii >= 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<size; ++i) {
|
||||
final int sno = reverse ? (size-1-i) : (i);
|
||||
if((!empties[sno]) || (!isItemValidForSlot(sno, mvstack))) continue;
|
||||
int nmax = Math.min(limit_left, mvstack.getCount());
|
||||
ItemStack placed = mvstack.copy();
|
||||
placed.setCount(nmax);
|
||||
mvstack.shrink(nmax);
|
||||
setInventorySlotContents(sno, placed);
|
||||
return checked(mvstack);
|
||||
}
|
||||
return checked(mvstack);
|
||||
}
|
||||
|
||||
public ItemStack insert(final ItemStack stack_to_move)
|
||||
{ return insert(stack_to_move, false, 0, false, true); }
|
||||
|
||||
/**
|
||||
* Moves as much items from the slots in range [offset, 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;
|
||||
List<ItemStack> matches = new ArrayList<>();
|
||||
for(int i=0; i<size; ++i) {
|
||||
final ItemStack stack = 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; (i<matches.size()) && (n_left>0); ++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<size; ++i) changed |= move(i, target_range, false, only_fillup, reverse, force_group_stacks);
|
||||
return changed;
|
||||
}
|
||||
|
||||
public boolean move(final InventoryRange target_range)
|
||||
{ return move(target_range, false, false, true); }
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue