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:
stfwi 2020-10-17 09:01:24 +02:00
parent a730143176
commit ed54eea0bd
12 changed files with 481 additions and 373 deletions

View file

@ -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

View file

@ -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"
}
}

View file

@ -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).

View file

@ -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();

View file

@ -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)

View file

@ -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;

View file

@ -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));

View file

@ -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();
}
}
//--------------------------------------------------------------------------------------------------------------------

View file

@ -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;

View file

@ -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)

View file

@ -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")

View file

@ -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); }
}
//--------------------------------------------------------------------------------------------------------------------