diff --git a/1.12/gradle.properties b/1.12/gradle.properties index 44450e2..a1820e4 100644 --- a/1.12/gradle.properties +++ b/1.12/gradle.properties @@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx8G version_minecraft=1.12.2 version_forge=14.23.5.2768 version_jei=4.10.0.198 -version_engineersdecor=1.0.3 +version_engineersdecor=1.0.4-b1 diff --git a/1.12/meta/update.json b/1.12/meta/update.json index f4ccff1..7748218 100644 --- a/1.12/meta/update.json +++ b/1.12/meta/update.json @@ -1,6 +1,7 @@ { "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "1.12.2": { + "1.0.4-b1": "[A] Crafting table: JEI integration for recipe placement added.\n[A] Crafting table: History re-fab added, allowing to quickly select and re-craft recent recipes. Selection with arrow buttons, ingredient placement by clicking the result slot. Automatic item distribution on shift-click. Quick-move buttons.\n[F] Crafting table textures modified to prevent optifine glitches on the edges of the legs.", "1.0.3": "[R] Release based on v1.0.3-b5. Release-to-release changes: * Small laboratory furnace added. * Extensive config options for mod packing and tuning added. * Rendering issues fixes (window bleeding, optifine). * Steel framed window added. * Treated wood pole \"end pieces\" added (two support variants). * Sitting on treated wood stool added including mobs (but not villagers, as these are obviously very upright people). * Lang ru_ru added (github contribution from Yaroslavik). * Creative tab logo changed to mod logo. * Table/crafting table bounding boxes refined. * Standalone \"escape\" recipes added if IE is not installed.", "1.0.3-b5": "[F] Fixed typo in en-en lang file.\n[F] Fixed IE concrete texture missing bailout in log if IE is not installed.\n[F] Using forge multi-layer models for windows to circumvent glitches.\n[M] Changed creative tab logo to the mod logo.\n[A] Added alternative recipes for crafting table and furnace if main IE ingredients are missing (for \"stand-alone\" mod usage).", "1.0.3-b4": "[A] Lab furnace supports electrical speedup when a IE external is placed in one of the two auxiliary slots.\n[F] Fixed window rendering issue (issue #15, thanks to ILLOMIURGE).\n[M] Updated ru_ru lang file (Yaroslavik).", @@ -24,6 +25,6 @@ }, "promos": { "1.12.2-recommended": "1.0.3", - "1.12.2-latest": "1.0.3" + "1.12.2-latest": "1.0.4-b1" } } \ No newline at end of file diff --git a/1.12/readme.md b/1.12/readme.md index d307c08..c3d1e3e 100644 --- a/1.12/readme.md +++ b/1.12/readme.md @@ -10,6 +10,14 @@ Mod sources for Minecraft version 1.12.2. ---- ## Revision history + - v1.0.4-b1 [A] Crafting table: JEI integration for recipe placement added. + [A] Crafting table: History re-fab added, allowing to quickly select + and re-craft recent recipes. Selection with arrow buttons, + ingredient placement by clicking the result slot. Automatic + item distribution on shift-click. Quick-move buttons. + [F] Crafting table textures modified to prevent optifine glitches + on the edges of the legs. + ------------------------------------------------------------------- - v1.0.3 [R] Release based on v1.0.3-b5. Release-to-release changes: * Small laboratory furnace added. diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java index d9a7d74..c7e4f87 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java @@ -9,7 +9,6 @@ */ package wile.engineersdecor.blocks; -import net.minecraft.client.gui.GuiButtonImage; import wile.engineersdecor.ModEngineersDecor; import net.minecraft.block.Block; import net.minecraft.block.SoundType; @@ -25,6 +24,8 @@ import net.minecraft.inventory.*; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.init.Items; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.Ingredient; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.*; @@ -37,8 +38,11 @@ import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.gui.GuiButton; +import net.minecraft.client.gui.GuiButtonImage; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; +import net.minecraftforge.fml.common.registry.GameRegistry; +import net.minecraftforge.registries.IForgeRegistry; import com.google.common.collect.ImmutableList; import wile.engineersdecor.detail.Networking; import javax.annotation.Nonnull; @@ -51,10 +55,14 @@ import java.util.List; public class BlockDecorCraftingTable extends BlockDecorDirected { public static boolean with_assist = true; + public static boolean with_assist_direct_history_refab = false; + public static boolean with_assist_quickmove_buttons = false; - public static final void on_config(boolean without_crafting_assist) + public static final void on_config(boolean without_crafting_assist, boolean with_assist_immediate_history_refab, boolean with_quickmove_buttons) { with_assist = !without_crafting_assist; + with_assist_direct_history_refab = with_assist_immediate_history_refab; + with_assist_quickmove_buttons = with_quickmove_buttons; CraftingHistory.max_history_size(32); } @@ -157,11 +165,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected private static class CraftingHistory { + public static final int RESULT_STACK_INDEX = 0; + public static final int INPUT_STACKS_BEGIN = 1; public static final List NOTHING = new ArrayList(); + private static int max_history_size_ = 5; private List history_ = new ArrayList(); private int current_ = -1; - private static int max_history_size_ = 5; + private List current_stacks_ = new ArrayList(); + private IRecipe current_recipe_ = null; public CraftingHistory() {} @@ -186,6 +198,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected } } current_ = (!subsect.hasKey("current")) ? (-1) : MathHelper.clamp(subsect.getInteger("current"), -1, history_.size()-1); + update_current(); } catch(Throwable ex) { ModEngineersDecor.logger.error("Exception reading crafting table history NBT, resetting, exception is:" + ex.getMessage()); clear(); @@ -201,27 +214,39 @@ public class BlockDecorCraftingTable extends BlockDecorDirected } public void clear() - { current_ = -1; history_.clear(); } + { reset_current(); history_.clear(); } - public void reset_curent() - { current_ = -1; } + public void reset_current() + { current_ = -1; current_stacks_ = NOTHING; current_recipe_ = null; } - public void add(final List grid_stacks) + void update_current() { - if(!with_assist) { clear(); return; } - String s = stacks2str(grid_stacks); - if(s.isEmpty()) return; - history_.removeIf(e->e.equals(s)); - history_.add(s); - while(history_.size() > max_history_size()) history_.remove(0); - if(current_ >= history_.size()) current_ = -1; + if((current_ < 0) || (current_ >= history_.size())) { reset_current(); return; } + Tuple> data = str2stacks(history_.get(current_)); + if(data == null) { reset_current(); return; } + current_recipe_ = data.getFirst(); + current_stacks_ = data.getSecond(); } - public String stacks2str(final List grid_stacks) + public void add(final List grid_stacks, IRecipe recipe) { - if((grid_stacks==null) || (grid_stacks.size() != 10)) return ""; + if(!with_assist) { clear(); return; } + String s = stacks2str(grid_stacks, recipe); + String recipe_filter = recipe.getRegistryName().toString() + ";"; + if(s.isEmpty()) return; + history_.removeIf(e->e.equals(s)); + history_.removeIf(e->e.startsWith(recipe_filter)); + history_.add(s); + while(history_.size() > max_history_size()) history_.remove(0); + if(current_ >= history_.size()) reset_current(); + } + + public String stacks2str(final List grid_stacks, IRecipe recipe) + { + if((grid_stacks==null) || (grid_stacks.size() != 10) || (recipe==null)) return ""; if(grid_stacks.get(0).isEmpty()) return ""; final ArrayList items = new ArrayList(); + items.add(recipe.getRegistryName().toString().trim()); for(ItemStack st:grid_stacks) { int meta = st.getMetadata(); items.add( (st.isEmpty()) ? ("") : ((st.getItem().getRegistryName().toString().trim()) + ((meta==0)?(""):("/"+meta)) )); @@ -229,13 +254,21 @@ public class BlockDecorCraftingTable extends BlockDecorDirected return String.join(";", items); } - public List str2stacks(final String entry) + public @Nullable Tuple> str2stacks(final String entry) { try { - if((entry == null) || (entry.isEmpty())) return NOTHING; + if((entry == null) || (entry.isEmpty())) return null; ArrayList item_regnames = new ArrayList(Arrays.asList(entry.split("[;]"))); - if((item_regnames == null) || (item_regnames.size() > 10)) return NOTHING; - while(item_regnames.size() < 10) item_regnames.add(""); + if((item_regnames == null) || (item_regnames.size() < 2) || (item_regnames.size() > 11)) return null; + while(item_regnames.size() < 11) item_regnames.add(""); + IRecipe recipe = null; + try { + final IForgeRegistry recipe_registry = GameRegistry.findRegistry(IRecipe.class); + recipe = recipe_registry.getValue(new ResourceLocation(item_regnames.remove(0))); + } catch(Throwable e) { + ModEngineersDecor.logger.error("Recipe lookup failed: " + e.getMessage()); + } + if(recipe==null) return null; List stacks = new ArrayList(); for(String regname : item_regnames) { ItemStack stack = ItemStack.EMPTY; @@ -244,42 +277,54 @@ public class BlockDecorCraftingTable extends BlockDecorDirected if(regname.indexOf('/') >= 0) { String[] itemdetails = regname.split("[/]"); if(itemdetails.length>0) regname = itemdetails[0]; - try { if(itemdetails.length>1) meta = Integer.parseInt(itemdetails[1]); } catch(Throwable e){meta=0;} // ignore exception here + if(itemdetails.length>1) try { meta=Integer.parseInt(itemdetails[1]); } catch(Throwable e){ meta=0; } // ignore exception here } final Item item = Item.REGISTRY.getObject(new ResourceLocation(regname)); stack = ((item == null) || (item == Items.AIR)) ? ItemStack.EMPTY : (new ItemStack(item, 1, meta)); } stacks.add(stack); } - if((stacks.size() != 10) || (stacks.get(0).isEmpty())) return NOTHING; // invalid size or no result - return stacks; + if((stacks.size() != 10) || (stacks.get(0).isEmpty())) return null; // invalid size or no result + return new Tuple>(recipe, stacks); } catch(Throwable ex) { ModEngineersDecor.logger.error("History stack building failed: " + ex.getMessage()); - return NOTHING; + return null; } } public List current() - { - if((current_ < 0) || (current_ >= history_.size())) { current_ = -1; return NOTHING; } - return str2stacks(history_.get(current_)); - } + { return current_stacks_; } + + public IRecipe current_recipe() + { return current_recipe_; } public void next() { - if(history_.isEmpty()) { current_ = -1; return; } - current_ = ((++current_) >= history_.size()) ? (-1) : (current_); + if(history_.isEmpty()) { + current_ = -1; + } else { + current_ = ((++current_) >= history_.size()) ? (-1) : (current_); + } + update_current(); } public void prev() { - if(history_.isEmpty()) { current_ = -1; return; } - current_ = ((--current_) < -1) ? (history_.size()-1) : (current_); + if(history_.isEmpty()) { + current_ = -1; + } else { + current_ = ((--current_) < -1) ? (history_.size()-1) : (current_); + } + update_current(); } + public void reset_selection() + { current_ = -1; update_current(); } + public String toString() { - StringBuilder s = new StringBuilder("{ current:" + current_ + ", elements:[ "); + String rec = (current_recipe_==null) ? "none" : (current_recipe_.getRegistryName().toString()); + StringBuilder s = new StringBuilder("{ current:" + current_ + ", recipe:'" + rec + "', elements:[ "); for(int i=0; i buttons = new ArrayList(); + protected final boolean history_slot_tooltip[] = {false,false,false,false,false,false,false,false,false,false}; public BGui(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te) - { super(new BContainer(playerInventory, world, pos, te)); this.te = te; } + { super(new BContainer(playerInventory, world, pos, te)); this.te = te; this.player=playerInventory.player; } @Override @SuppressWarnings("unused") @@ -315,12 +366,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected final int x0=((width - xSize)/2), y0=((height - ySize)/2); buttons.clear(); if(with_assist) { - buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT, x0+156,y0+44, 12,12, 194,44, 12, BACKGROUND))); - buttons.add(addButton(new GuiButtonImage(BUTTON_PREV, x0+156,y0+30, 12,12, 180,30, 12, BACKGROUND))); - // buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_STORAGE, x0+49,y0+34, 9,17, 219,34, 17, BACKGROUND))); - // buttons.add(addButton(new GuiButtonImage(BUTTON_TO_STORAGE, x0+49,y0+52, 9,17, 208,16, 17, BACKGROUND))); - // buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_PLAYER, x0+77,y0+71, 17,9, 198,71, 9, BACKGROUND))); - // buttons.add(addButton(new GuiButtonImage(BUTTON_TO_PLAYER, x0+59,y0+71, 17,9, 180,71, 9, BACKGROUND))); + buttons.add(addButton(new GuiButtonImage(BUTTON_NEXT, x0+158,y0+44, 12,12, 194,44, 12, BACKGROUND))); + buttons.add(addButton(new GuiButtonImage(BUTTON_PREV, x0+158,y0+30, 12,12, 180,30, 12, BACKGROUND))); + buttons.add(addButton(new GuiButtonImage(BUTTON_CLEAR_GRID, x0+158,y0+58, 12,12, 194,8, 12, BACKGROUND))); + if(with_assist_quickmove_buttons) { + buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_STORAGE, x0+49, y0+34, 9,17, 219,34, 17, BACKGROUND))); + buttons.add(addButton(new GuiButtonImage(BUTTON_TO_STORAGE, x0+49, y0+52, 9,17, 208,16, 17, BACKGROUND))); + buttons.add(addButton(new GuiButtonImage(BUTTON_FROM_PLAYER, x0+77, y0+71, 17,9, 198,71, 9, BACKGROUND))); + buttons.add(addButton(new GuiButtonImage(BUTTON_TO_PLAYER, x0+59, y0+71, 17,9, 180,71, 9, BACKGROUND))); + } } } @@ -332,6 +386,26 @@ public class BlockDecorCraftingTable extends BlockDecorDirected renderHoveredToolTip(mouseX, mouseY); } + @Override + protected void renderHoveredToolTip(int mouseX, int mouseY) + { + if((!player.inventory.getItemStack().isEmpty()) || (getSlotUnderMouse() == null)) return; + final Slot slot = getSlotUnderMouse(); + if(!slot.getStack().isEmpty()) { renderToolTip(slot.getStack(), mouseX, mouseY); return; } + if(with_assist) { + int hist_index = -1; + if(slot instanceof BSlotCrafting) { + hist_index = 0; + } else if(slot.inventory instanceof BInventoryCrafting) { + hist_index = slot.getSlotIndex() + 1; + } + if((hist_index < 0) || (hist_index >= history_slot_tooltip.length)) return; + if(!history_slot_tooltip[hist_index]) return; + ItemStack hist_stack = te.history.current().get(hist_index); + if(!hist_stack.isEmpty()) renderToolTip(hist_stack, mouseX, mouseY); + } + } + @Override protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) { @@ -340,14 +414,15 @@ public class BlockDecorCraftingTable extends BlockDecorDirected final int x0=((width - xSize)/2), y0=((height - ySize)/2); drawTexturedModalRect(x0, y0, 0, 0, xSize, ySize); if(with_assist) { + for(int i=0; i crafting_template = te.history.current(); if((crafting_template == null) || (crafting_template.isEmpty())) return; - if(inventorySlots.getSlot(0).getHasStack()) return; { int i = 0; for(Tuple e : ((BContainer) inventorySlots).CRAFTING_SLOT_POSITIONS) { + if(i==0) continue; // explicitly here, that is the result slot. if((inventorySlots.getSlot(i).getHasStack())) { - if(!inventorySlots.getSlot(i).getStack().getItem().equals(crafting_template.get(i).getItem())) { + if(!inventorySlots.getSlot(i).getStack().isItemEqual(crafting_template.get(i))) { return; // user has placed another recipe } } @@ -358,7 +433,14 @@ public class BlockDecorCraftingTable extends BlockDecorDirected int i = 0; for(Tuple e : ((BContainer) inventorySlots).CRAFTING_SLOT_POSITIONS) { final ItemStack stack = crafting_template.get(i); - if(!stack.isEmpty()) drawTemplateItemAt(stack, x0, y0, e.getFirst(), e.getSecond()); + if(!stack.isEmpty()) { + if(!inventorySlots.getSlot(i).getHasStack()) history_slot_tooltip[i] = true; + if((i==0) && inventorySlots.getSlot(i).getStack().isItemEqual(crafting_template.get(i))) { + continue; // don't shade the output slot if the result can be crafted. + } else { + drawTemplateItemAt(stack, x0, y0, e.getFirst(), e.getSecond()); + } + } ++i; } } @@ -367,9 +449,10 @@ public class BlockDecorCraftingTable extends BlockDecorDirected protected void drawTemplateItemAt(ItemStack stack, int x0, int y0, int x, int y) { + final float main_zl = zLevel; RenderHelper.disableStandardItemLighting(); RenderHelper.enableGUIStandardItemLighting(); - float zl = itemRender.zLevel; + final float zl = itemRender.zLevel; itemRender.zLevel = -50; itemRender.renderItemIntoGUI(stack, x0+x, y0+y); itemRender.zLevel = zl; @@ -377,7 +460,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected GlStateManager.color(0.7f, 0.7f, 0.7f, 0.8f); mc.getTextureManager().bindTexture(BACKGROUND); drawTexturedModalRect(x0+x, y0+y, x, y, 16, 16); + RenderHelper.enableGUIStandardItemLighting(); RenderHelper.enableStandardItemLighting(); + zLevel = main_zl; } @Override @@ -386,17 +471,58 @@ public class BlockDecorCraftingTable extends BlockDecorDirected switch(button.id) { case BUTTON_NEXT: case BUTTON_PREV: + case BUTTON_CLEAR_GRID: case BUTTON_FROM_STORAGE: case BUTTON_TO_STORAGE: case BUTTON_FROM_PLAYER: - case BUTTON_TO_PLAYER: { + case BUTTON_TO_PLAYER: + case ACTION_PLACE_CURRENT_HISTORY_SEL: { NBTTagCompound nbt = new NBTTagCompound(); - nbt.setInteger("button", button.id); + nbt.setInteger("action", button.id); Networking.PacketTileNotify.sendToServer(te, nbt); break; } } } + + @Override + protected void handleMouseClick(Slot slot, int slotId, int mouseButton, ClickType type) + { + if(type == ClickType.PICKUP) { + boolean place_refab = (slot instanceof BSlotCrafting) && (!slot.getHasStack()); + if(place_refab && with_assist_direct_history_refab) onHistoryItemPlacement(); // place before crafting -> direct item pick + super.handleMouseClick(slot, slotId, mouseButton, type); + if(place_refab && (!with_assist_direct_history_refab)) onHistoryItemPlacement(); // place after crafting -> confirmation first + return; + } + if((type == ClickType.QUICK_MOVE) && (slotId > 9) && (slot.getHasStack())) { // container slots 0..9 are crafting output and grid + List history = te.history.current(); + boolean palce_in_crafting_grid = (!history.isEmpty()); + if(!palce_in_crafting_grid) { + for(int i=0; i<9; ++i) { + if(!(te.getStackInSlot(i).isEmpty())) { palce_in_crafting_grid = true; break; } + } + } + if(palce_in_crafting_grid) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("action", ACTION_PLACE_SHIFTCLICKED_STACK); + nbt.setInteger("containerslot", slotId); + Networking.PacketTileNotify.sendToServer(te, nbt); + return; + } + } + super.handleMouseClick(slot, slotId, mouseButton, type); + } + + private void onHistoryItemPlacement() + { + if(te.history.current().isEmpty()) return; + final Slot resultSlot = this.getSlotUnderMouse(); // double check + if(!(resultSlot instanceof BSlotCrafting)) return; + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("action", ACTION_PLACE_CURRENT_HISTORY_SEL); + Networking.PacketTileNotify.sendToServer(te, nbt); + } } //-------------------------------------------------------------------------------------------------------------------- @@ -415,11 +541,12 @@ public class BlockDecorCraftingTable extends BlockDecorDirected protected void onCrafting(ItemStack stack) { if((with_assist) && ((player.world!=null) && (!(player.world.isRemote))) && (!stack.isEmpty())) { + final IRecipe recipe = ((InventoryCraftResult)this.inventory).getRecipeUsed(); final ArrayList grid = new ArrayList(); grid.add(stack); for(int i = 0; i < 9; ++i) grid.add(te.stacks.get(i)); - te.history.add(grid); - te.history.reset_curent(); + te.history.add(grid, recipe); + te.history.reset_current(); te.syncHistory(player); } super.onCrafting(stack); @@ -430,7 +557,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected // Crafting container //-------------------------------------------------------------------------------------------------------------------- - private static class BContainer extends Container + public static class BContainer extends Container { private final World world; private final BlockPos pos; @@ -449,28 +576,33 @@ public class BlockDecorCraftingTable extends BlockDecorDirected this.te = te; craftMatrix = new BInventoryCrafting(this, te); craftMatrix.openInventory(player); + // container slotId 0 === crafting output addSlotToContainer(new BSlotCrafting(te, playerInventory.player, craftMatrix, craftResult, 0, 134, 35)); slotpositions.add(new Tuple<>(134, 35)); + // container slotId 1..9 === TE slots 0..8 for(int y=0; y<3; ++y) { for(int x=0; x<3; ++x) { int xpos = 60+x*18; int ypos = 17+y*18; - addSlotToContainer(new Slot(craftMatrix, x+y*3, xpos, ypos)); // block slots 0..8 + addSlotToContainer(new Slot(craftMatrix, x+y*3, xpos, ypos)); slotpositions.add(new Tuple<>(xpos, ypos)); } } CRAFTING_SLOT_POSITIONS = ImmutableList.copyOf(slotpositions); + // container slotId 10..36 === player slots: 9..35 for(int y=0; y<3; ++y) { - for (int x=0; x<9; ++x) { - addSlotToContainer(new Slot(playerInventory, x+y*9+9, 8+x*18, 86+y*18)); // player slots: 9..35 + for(int x=0; x<9; ++x) { + addSlotToContainer(new Slot(playerInventory, x+y*9+9, 8+x*18, 86+y*18)); } } + // container slotId 37..45 === player slots: 0..8 for(int x=0; x<9; ++x) { - addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144)); // player slots: 0..8 + addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144)); } + // container slotId 46..53 === TE slots 9..17 (storage) for(int y=0; y<4; ++y) { - for (int x=0; x<2; ++x) { - addSlotToContainer(new Slot(craftMatrix, x+y*2+9, 8+x*18, 9+y*18)); // block slots 9..17 + for(int x=0; x<2; ++x) { + addSlotToContainer(new Slot(craftMatrix, x+y*2+9, 8+x*18, 9+y*18)); } } onCraftMatrixChanged(craftMatrix); @@ -541,6 +673,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected } return stack; } + + public void setCraftingMatrixSlot(int slot_index, ItemStack stack) + { craftMatrix.setInventorySlotContents(slot_index, stack.copy()); } } //-------------------------------------------------------------------------------------------------------------------- @@ -599,7 +734,9 @@ public class BlockDecorCraftingTable extends BlockDecorDirected //-------------------------------------------------------------------------------------------------------------------- public static class BTileEntity extends TileEntity implements IInventory, Networking.IPacketReceiver { + 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 = 8; public static final int NUM_OF_SLOTS = NUM_OF_CRAFTING_SLOTS+NUM_OF_STORAGE_SLOTS; protected NonNullList stacks; @@ -625,35 +762,384 @@ public class BlockDecorCraftingTable extends BlockDecorDirected history.write(compound); } + // private aux methods --------------------------------------------------------------------- + + private boolean itemstack_recipe_match(ItemStack grid_stack, ItemStack history_stack) + { + if(history.current_recipe()!=null) { + boolean grid_match, dist_match; + for(final Ingredient ingredient:history.current_recipe().getIngredients()) { + grid_match = false; dist_match = false; + for(final ItemStack match:ingredient.getMatchingStacks()) { + if(match.isItemEqualIgnoreDurability(grid_stack)) dist_match = true; + if(match.isItemEqualIgnoreDurability(history_stack)) grid_match = true; + if(dist_match && grid_match) return true; + } + } + } + return false; + } + + private List crafting_slot_stacks_to_add() + { + final ArrayList slots = new ArrayList(); + final List tocraft = history.current(); + final int stack_sizes[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1}; + if(tocraft.isEmpty()) return slots; + for(int i=0; i<9; ++i) { + if((i+CraftingHistory.INPUT_STACKS_BEGIN) >= tocraft.size()) break; + final ItemStack needed = tocraft.get(i+CraftingHistory.INPUT_STACKS_BEGIN); + final ItemStack palced = getStackInSlot(i+CRAFTING_SLOTS_BEGIN); + if(needed.isEmpty() && (!palced.isEmpty())) return slots; // history vs grid mismatch. + if((!palced.isEmpty()) && (!itemstack_recipe_match(needed, palced))) return slots; // also mismatch + if(!needed.isEmpty()) stack_sizes[i] = palced.getCount(); + } + int min_placed = 64, max_placed=0; + for(int i=0; i<9; ++i) { // todo: check if java has something like std::accumulate<>() + if(stack_sizes[i] < 0) continue; + min_placed = Math.min(min_placed, stack_sizes[i]); + max_placed = Math.max(max_placed, stack_sizes[i]); + } + int fillup_size = (max_placed <= min_placed) ? (min_placed + 1) : max_placed; + for(int i=0; i<9; ++i) { + if(stack_sizes[i] < 0) continue; + if(fillup_size > getStackInSlot(i+CRAFTING_SLOTS_BEGIN).getMaxStackSize()) return slots; // can't fillup all + } + for(int i=0; i<9; ++i) { + if(stack_sizes[i] < 0) { + slots.add(ItemStack.EMPTY); + } else { + ItemStack st = getStackInSlot(i+CRAFTING_SLOTS_BEGIN).copy(); + if(st.isEmpty()) { + st = tocraft.get(i+CraftingHistory.INPUT_STACKS_BEGIN).copy(); + st.setCount(Math.min(st.getMaxStackSize(), fillup_size)); + } else { + st.setCount(MathHelper.clamp(fillup_size-st.getCount(), 0, st.getMaxStackSize())); + } + slots.add(st); + } + } + return slots; + } + + /** + * Moves as much items from the stack to the slots in range [first_slot, last_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`. + */ + private ItemStack move_stack_to_inventory(final ItemStack stack_to_move, IInventory inventory, final int slot_begin, final int slot_end, boolean only_fillup) + { + final ItemStack mvstack = stack_to_move.copy(); + if((mvstack.isEmpty()) || (slot_begin < 0) || (slot_end > inventory.getSizeInventory())) return mvstack; + // first iteration: fillup existing stacks + for(int i = slot_begin; i < slot_end; ++i) { + final ItemStack stack = inventory.getStackInSlot(i); + if((stack.isEmpty()) || (!stack.isItemEqual(mvstack))) continue; + int nmax = stack.getMaxStackSize() - stack.getCount(); + if(mvstack.getCount() <= nmax) { + stack.setCount(stack.getCount()+mvstack.getCount()); + mvstack.setCount(0); + inventory.setInventorySlotContents(i, stack); + return mvstack; + } else { + stack.setCount(stack.getMaxStackSize()); + mvstack.shrink(nmax); + inventory.setInventorySlotContents(i, stack); + } + } + if(only_fillup) return mvstack; + if(inventory instanceof InventoryPlayer) { + // second iteration: use appropriate empty slots + for(int i = slot_begin+1; i < slot_end-1; ++i) { + final ItemStack stack = inventory.getStackInSlot(i); + if(!stack.isEmpty()) continue; + if((!inventory.getStackInSlot(i+1).isItemEqual(mvstack)) && (!inventory.getStackInSlot(i-1).isItemEqual(mvstack))) continue; + inventory.setInventorySlotContents(i, mvstack.copy()); + mvstack.setCount(0); + return mvstack; + } + } + // third iteration: use any empty slots + for(int i = slot_begin; i < slot_end; ++i) { + final ItemStack stack = inventory.getStackInSlot(i); + if(!stack.isEmpty()) continue; + inventory.setInventorySlotContents(i, mvstack.copy()); + mvstack.setCount(0); + return mvstack; + } + return mvstack; + } + + /** + * Moves as much items from the slots in range [first_slot, last_slot] of the inventory into a new stack. + * Implicitly shrinks the inventory stacks and the `request_stack`. + */ + private ItemStack move_stack_from_inventory(IInventory inventory, final ItemStack request_stack, final int slot_begin, final int slot_end) + { + ItemStack fetched_stack = request_stack.copy(); + fetched_stack.setCount(0); + int n_left = request_stack.getCount(); + while(n_left > 0) { + int smallest_stack_size = 0; + int smallest_stack_index = -1; + for(int i = slot_begin; i < slot_end; ++i) { + final ItemStack stack = inventory.getStackInSlot(i); + if((!stack.isEmpty()) && (stack.isItemEqual(request_stack))) { + // Never automatically place stuff with nbt (except a few allowed like "Damage"), + // as this could be a full crate, a valuable tool item, etc. For these recipes + // the user has to place this item manually. + if(stack.hasTagCompound()) { + final NBTTagCompound nbt = stack.getTagCompound(); + int n = stack.getTagCompound().getSize(); + if((n > 0) && (stack.getTagCompound().hasKey("Damage"))) --n; + if(n > 0) continue; + } + fetched_stack = stack.copy(); // copy exact stack with nbt and tool damage, otherwise we have an automagical repair of items. + fetched_stack.setCount(0); + int n = stack.getCount(); + if((n < smallest_stack_size) || (smallest_stack_size <= 0)) { + smallest_stack_size = n; + smallest_stack_index = i; + } + } + } + if(smallest_stack_index < 0) { + break; // no more items available + } else { + int n = Math.min(n_left, smallest_stack_size); + n_left -= n; + fetched_stack.grow(n); + ItemStack st = inventory.getStackInSlot(smallest_stack_index); + st.shrink(n); + inventory.setInventorySlotContents(smallest_stack_index, st); + } + } + return fetched_stack; + } + + private boolean clear_grid_to_storage(EntityPlayer player) + { + boolean changed = false; + for(int grid_i = CRAFTING_SLOTS_BEGIN; grid_i < (CRAFTING_SLOTS_BEGIN + NUM_OF_CRAFTING_SLOTS); ++grid_i) { + ItemStack stack = getStackInSlot(grid_i); + if(stack.isEmpty()) continue; + ItemStack remaining = move_stack_to_inventory(stack, this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN+NUM_OF_STORAGE_SLOTS, false); + setInventorySlotContents(grid_i, remaining); + changed = true; + } + return changed; + } + + private boolean clear_grid_to_player(EntityPlayer player) + { + boolean changed = false; + for(int grid_i = CRAFTING_SLOTS_BEGIN; grid_i < (CRAFTING_SLOTS_BEGIN + NUM_OF_CRAFTING_SLOTS); ++grid_i) { + ItemStack remaining = getStackInSlot(grid_i); + if(remaining.isEmpty()) continue; + remaining = move_stack_to_inventory(remaining, player.inventory,9, 36, true); // prefer filling up inventory stacks + remaining = move_stack_to_inventory(remaining, player.inventory,0, 9, true); // then fill up the hotbar stacks + remaining = move_stack_to_inventory(remaining, player.inventory,9, 36, false); // then allow empty stacks in inventory + remaining = move_stack_to_inventory(remaining, player.inventory,0, 9, false); // then new stacks in the hotbar + this.setInventorySlotContents(grid_i, remaining); + changed = true; + } + return changed; + } + + enum EnumRefabPlacement { UNCHANGED, INCOMPLETE, PLACED } + private EnumRefabPlacement place_refab_stacks(IInventory inventory, final int slot_begin, final int slot_end) + { + List to_fill = crafting_slot_stacks_to_add(); + boolean slots_changed = false; + boolean missing_item = false; + int num_slots_placed = 0; + if(!to_fill.isEmpty()) { + for(int it_guard=63; it_guard>=0; --it_guard) { + boolean slots_updated = false; + for(int i = 0; i < 9; ++i) { + final ItemStack req_stack = to_fill.get(i).copy(); + if(req_stack.isEmpty()) continue; + req_stack.setCount(1); + to_fill.get(i).shrink(1); + final ItemStack mv_stack = move_stack_from_inventory(inventory, req_stack, slot_begin, slot_end); + if(mv_stack.isEmpty()) { missing_item=true; continue; } + // sizes already checked + ItemStack grid_stack = getStackInSlot(i + CRAFTING_SLOTS_BEGIN).copy(); + if(grid_stack.isEmpty()) { + grid_stack = mv_stack.copy(); + } else { + grid_stack.grow(mv_stack.getCount()); + } + setInventorySlotContents(i + CRAFTING_SLOTS_BEGIN, grid_stack); + slots_changed = true; + slots_updated = true; + } + if(!slots_updated) break; + } + } + if(!slots_changed) { + return EnumRefabPlacement.UNCHANGED; + } else if(missing_item) { + return EnumRefabPlacement.INCOMPLETE; + } else { + return EnumRefabPlacement.PLACED; + } + } + + private EnumRefabPlacement distribute_stack(IInventory inventory, final int slotno) + { + List to_refab = crafting_slot_stacks_to_add(); + ItemStack to_distribute = inventory.getStackInSlot(slotno).copy(); + if(to_distribute.isEmpty()) return EnumRefabPlacement.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 = getStackInSlot(i + CRAFTING_SLOTS_BEGIN); + final ItemStack refab_stack = to_refab.isEmpty() ? ItemStack.EMPTY : to_refab.get(i).copy(); + if((!grid_stack.isEmpty()) && (grid_stack.isItemEqual(to_distribute))) { + matching_grid_stack_sizes[i] = grid_stack.getCount(); + total_num_missing_stacks += grid_stack.getMaxStackSize()-grid_stack.getCount(); + if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i]; + if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i]; + } else if((!refab_stack.isEmpty()) && (refab_stack.isItemEqual(to_distribute))) { + matching_grid_stack_sizes[i] = 0; + total_num_missing_stacks += grid_stack.getMaxStackSize(); + if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i]; + if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i]; + } else if(grid_stack.isEmpty() && (!refab_stack.isEmpty())) { + if(itemstack_recipe_match(to_distribute, refab_stack)) { + matching_grid_stack_sizes[i] = 0; + total_num_missing_stacks += grid_stack.getMaxStackSize(); + if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i]; + if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i]; + } + } + } + if(min_matching_stack_size < 0) return EnumRefabPlacement.UNCHANGED; + final int stack_limit_size = Math.min(to_distribute.getMaxStackSize(), getInventoryStackLimit()); + if(min_matching_stack_size >= stack_limit_size) return EnumRefabPlacement.UNCHANGED; + int n_to_distribute = to_distribute.getCount(); + for(int it_guard=63; it_guard>=0; --it_guard) { + if(n_to_distribute <= 0) break; + for(int i=0; i<9; ++i) { + if(n_to_distribute <= 0) break; + if(matching_grid_stack_sizes[i] == min_matching_stack_size) { + ++matching_grid_stack_sizes[i]; + --n_to_distribute; + } + } + if(min_matching_stack_size < max_matching_stack_size) { + ++min_matching_stack_size; // distribute short stacks + } else { + ++min_matching_stack_size; // stacks even, increase all + max_matching_stack_size = min_matching_stack_size; + } + if(min_matching_stack_size >= stack_limit_size) break; // all full + } + if(n_to_distribute == to_distribute.getCount()) return EnumRefabPlacement.UNCHANGED; // was already full + if(n_to_distribute <= 0) { + inventory.setInventorySlotContents(slotno, ItemStack.EMPTY); + } else { + to_distribute.setCount(n_to_distribute); + inventory.setInventorySlotContents(slotno, to_distribute); + } + for(int i=0; i<9; ++i) { + if(matching_grid_stack_sizes[i] < 0) continue; + ItemStack grid_stack = getStackInSlot(i + CRAFTING_SLOTS_BEGIN).copy(); + if(grid_stack.isEmpty()) grid_stack = to_distribute.copy(); + grid_stack.setCount(matching_grid_stack_sizes[i]); + setInventorySlotContents(i + CRAFTING_SLOTS_BEGIN, grid_stack); + } + return EnumRefabPlacement.PLACED; + } + // Networking.IPacketReceiver -------------------------------------------------------------- @Override public void onClientPacketReceived(EntityPlayer player, NBTTagCompound nbt) { - if(with_assist && nbt.hasKey("button")) { - switch(nbt.getInteger("button")) { - case BGui.BUTTON_NEXT: + if((world.isRemote) || (!(player.openContainer instanceof BContainer))) return; + final BContainer container = (BContainer)player.openContainer; + if(container.te != this) return; + boolean te_changed = false; + boolean player_inventory_changed = false; + if(with_assist && nbt.hasKey("action")) { + switch(nbt.getInteger("action")) { + case BGui.BUTTON_NEXT: { history.next(); syncHistory(player); - break; - case BGui.BUTTON_PREV: + // implicitly clear the grid, so that the player can see the refab, and that no recipe is active. + if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; } + if(clear_grid_to_storage(player)) te_changed = true; + } break; + case BGui.BUTTON_PREV: { history.prev(); syncHistory(player); - break; - case BGui.BUTTON_FROM_STORAGE: - //System.out.println("BUTTON_FROM_STORAGE"); - break; - case BGui.BUTTON_TO_STORAGE: - //System.out.println("BUTTON_TO_STORAGE"); - break; - case BGui.BUTTON_FROM_PLAYER: - //System.out.println("BUTTON_FROM_PLAYER"); - break; - case BGui.BUTTON_TO_PLAYER: - //System.out.println("BUTTON_TO_PLAYER"); - break; + if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; } + if(clear_grid_to_storage(player)) te_changed = true; + } break; + case BGui.BUTTON_CLEAR_GRID: { + history.reset_selection(); + syncHistory(player); + if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; } + if(clear_grid_to_storage(player)) te_changed = true; + } break; + case BGui.BUTTON_TO_STORAGE: { + if(clear_grid_to_storage(player)) te_changed = true; + } break; + case BGui.BUTTON_TO_PLAYER: { + if(clear_grid_to_player(player)) { te_changed = true; player_inventory_changed = true; } + } break; + case BGui.BUTTON_FROM_STORAGE: { + EnumRefabPlacement from_storage = place_refab_stacks(this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN + NUM_OF_STORAGE_SLOTS); + if(from_storage != EnumRefabPlacement.UNCHANGED) te_changed = true; + } break; + case BGui.BUTTON_FROM_PLAYER: { + EnumRefabPlacement from_player_inv = place_refab_stacks(player.inventory, 9, 36); + if(from_player_inv != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; } + if(from_player_inv != EnumRefabPlacement.PLACED) { + EnumRefabPlacement from_hotbar = place_refab_stacks(player.inventory, 0, 9); + if(from_hotbar != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; } + } + } break; + case BGui.ACTION_PLACE_CURRENT_HISTORY_SEL: { + EnumRefabPlacement from_storage = place_refab_stacks(this, STORAGE_SLOTS_BEGIN, STORAGE_SLOTS_BEGIN + NUM_OF_STORAGE_SLOTS); + if(from_storage != EnumRefabPlacement.UNCHANGED) te_changed = true; + if(from_storage != EnumRefabPlacement.PLACED) { + EnumRefabPlacement from_player_inv = place_refab_stacks(player.inventory, 9, 36); + if(from_player_inv != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; } + if(from_player_inv != EnumRefabPlacement.PLACED) { + EnumRefabPlacement from_hotbar = place_refab_stacks(player.inventory, 0, 9); + if(from_hotbar != EnumRefabPlacement.UNCHANGED) { te_changed = true; player_inventory_changed = true; } + } + } + } break; + case BGui.ACTION_PLACE_SHIFTCLICKED_STACK: { + final int container_slot_id = nbt.getInteger("containerslot"); + if((container_slot_id < 10) || (container_slot_id > 53)) break; // out of range + if(container_slot_id >= 46) { + // from storage + final int storage_slot = container_slot_id - 46 + STORAGE_SLOTS_BEGIN; + EnumRefabPlacement stat = distribute_stack(this, storage_slot); + if(stat != EnumRefabPlacement.UNCHANGED) te_changed = true; + } else { + // from player + int player_slot = (container_slot_id >= 37) ? (container_slot_id-37) : (container_slot_id-10+9); + EnumRefabPlacement stat = distribute_stack(player.inventory, player_slot); + if(stat != EnumRefabPlacement.UNCHANGED) { player_inventory_changed = true; te_changed = true; } + } + } break; } } + if(te_changed) markDirty(); + if(player_inventory_changed) player.inventory.markDirty(); + if(te_changed || player_inventory_changed) { + container.onCraftMatrixChanged(this); + container.detectAndSendChanges(); + } } @Override diff --git a/1.12/src/main/java/wile/engineersdecor/detail/ModConfig.java b/1.12/src/main/java/wile/engineersdecor/detail/ModConfig.java index 280dd24..4feaf14 100644 --- a/1.12/src/main/java/wile/engineersdecor/detail/ModConfig.java +++ b/1.12/src/main/java/wile/engineersdecor/detail/ModConfig.java @@ -107,6 +107,9 @@ public class ModConfig @Config.Name("Without ladder speed boost") public boolean without_ladder_speed_boost = false; + @Config.Comment({"Disable history refabrication feature of the treated wood crafting table."}) + @Config.Name("Without crafting table history") + public boolean without_crafting_table_history = false; } @Config.Comment({ @@ -192,6 +195,12 @@ public class ModConfig @Config.Name("Chairs: Stand up chance %") @Config.RangeDouble(min=0.001, max=10) public double chair_mob_standup_probability_percent = 1; + + @Config.Comment({"Enables small quick-move arrows from/to player/block storage. " + + "Makes the UI a bit too busy, therefore disabled by default." + }) + @Config.Name("Crafting table: Move buttons") + public boolean with_crafting_quickmove_buttons = false; } @SuppressWarnings("unused") @@ -251,7 +260,7 @@ public class ModConfig if(tweaks.furnace_smelts_nuggets) ModRecipes.furnaceRecipeOverrideSmeltsOresToNuggets(); BlockDecorChair.on_config(optout.without_chair_sitting, optout.without_mob_chair_sitting, tweaks.chair_mob_sitting_probability_percent, tweaks.chair_mob_standup_probability_percent); BlockDecorLadder.on_config(optout.without_ladder_speed_boost); - BlockDecorCraftingTable.on_config(!zmisc.with_experimental); + BlockDecorCraftingTable.on_config(optout.without_crafting_table_history, false, tweaks.with_crafting_quickmove_buttons); } } diff --git a/1.12/src/main/java/wile/engineersdecor/eapi/jei/JEIPlugin.java b/1.12/src/main/java/wile/engineersdecor/eapi/jei/JEIPlugin.java index 36262a5..8c1d110 100644 --- a/1.12/src/main/java/wile/engineersdecor/eapi/jei/JEIPlugin.java +++ b/1.12/src/main/java/wile/engineersdecor/eapi/jei/JEIPlugin.java @@ -8,12 +8,13 @@ */ package wile.engineersdecor.eapi.jei; +import wile.engineersdecor.ModEngineersDecor; +import wile.engineersdecor.blocks.BlockDecorCraftingTable; +import wile.engineersdecor.blocks.ModBlocks; +import wile.engineersdecor.detail.ModConfig; import net.minecraft.block.Block; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import wile.engineersdecor.ModEngineersDecor; -import wile.engineersdecor.blocks.ModBlocks; -import wile.engineersdecor.detail.ModConfig; @mezz.jei.api.JEIPlugin public class JEIPlugin implements mezz.jei.api.IModPlugin @@ -22,6 +23,7 @@ public class JEIPlugin implements mezz.jei.api.IModPlugin @SuppressWarnings("deprecation") public void register(mezz.jei.api.IModRegistry registry) { + // Block/item hiding try { for(Block e:ModBlocks.getRegisteredBlocks()) { if(ModConfig.isOptedOut(e)) { @@ -37,7 +39,20 @@ public class JEIPlugin implements mezz.jei.api.IModPlugin } } } catch(Throwable e) { - ModEngineersDecor.logger.warn("Exception in JEI opt-out processing: '" + e.getMessage() + "', skipping further JEI processing."); + ModEngineersDecor.logger.warn("Exception in JEI opt-out processing: '" + e.getMessage() + "', skipping further JEI optout processing."); + } + // Crafting table registration + if(!ModConfig.optout.without_crafting_table) { + try { + mezz.jei.api.recipe.transfer.IRecipeTransferRegistry recipeTranferRegistry = registry.getRecipeTransferRegistry(); + recipeTranferRegistry.addRecipeTransferHandler( + BlockDecorCraftingTable.BContainer.class, + mezz.jei.api.recipe.VanillaRecipeCategoryUid.CRAFTING, + 1, 9, 10, 44 + ); + } catch(Throwable e) { + ModEngineersDecor.logger.warn("Exception in JEI crafting table handler registration: '" + e.getMessage() + "'."); + } } } } diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_front.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_front.png index 8fc207a..06069e9 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_front.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_front.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_side.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_side.png index 273905e..f059bb7 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_side.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_side.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_top.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_top.png index 2e9aead..0462c67 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_top.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_top.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_tray.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_tray.png index 530e0bf..cc16e1f 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_tray.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/crafting_table/treated_wood_crafting_table_tray.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_back.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_back.png index 4465f75..364e1ad 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_back.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_back.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_bottom.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_bottom.png index b56e843..7a0e8d7 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_bottom.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_bottom.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front.png index 218c945..4185ff0 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front_gloom_off.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front_gloom_off.png index cd9ac94..481f72d 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front_gloom_off.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front_gloom_off.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front_gloom_on.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front_gloom_on.png index 8bcef55..02da036 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front_gloom_on.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_front_gloom_on.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_handles.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_handles.png index 9698805..1998de0 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_handles.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_handles.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_left.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_left.png index 14c1b1b..039f719 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_left.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_left.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_right.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_right.png index 95dd1c1..5c417d5 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_right.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_right.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_top.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_top.png index 391188d..d711b45 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_top.png and b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/furnace/small_lab_furnace_top.png differ diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/gui/treated_wood_crafting_table.png b/1.12/src/main/resources/assets/engineersdecor/textures/gui/treated_wood_crafting_table.png index 58d1131..bc26abf 100644 Binary files a/1.12/src/main/resources/assets/engineersdecor/textures/gui/treated_wood_crafting_table.png and b/1.12/src/main/resources/assets/engineersdecor/textures/gui/treated_wood_crafting_table.png differ diff --git a/meta/update.json b/meta/update.json index c718205..c9b567a 100644 --- a/meta/update.json +++ b/meta/update.json @@ -1,6 +1,7 @@ { "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "1.12.2": { + "1.0.4-b1": "[A] Crafting table: JEI integration for recipe placement added.\n[A] Crafting table: History re-fab added, allowing to quickly select and re-craft recent recipes. Selection with arrow buttons, ingredient placement by clicking the result slot. Automatic item distribution on shift-click. Quick-move buttons.\n[F] Crafting table textures modified to prevent optifine glitches on the edges of the legs.", "1.0.3": "[R] Release based on v1.0.3-b5. Release-to-release changes: * Small laboratory furnace added. * Extensive config options for mod packing and tuning added. * Rendering issues fixes (window bleeding, optifine). * Steel framed window added. * Treated wood pole \"end pieces\" added (two support variants). * Sitting on treated wood stool added including mobs (but not villagers, as these are obviously very upright people). * Lang ru_ru added (github contribution from Yaroslavik). * Creative tab logo changed to mod logo. * Table/crafting table bounding boxes refined. * Standalone \"escape\" recipes added if IE is not installed.", "1.0.3-b5": "[F] Fixed typo in en-en lang file.\n[F] Fixed IE concrete texture missing bailout in log if IE is not installed.\n[F] Using forge multi-layer models for windows to circumvent glitches.\n[M] Changed creative tab logo to the mod logo.\n[A] Added alternative recipes for crafting table and furnace if main IE ingredients are missing (for \"stand-alone\" mod usage).", "1.0.3-b4": "[A] Lab furnace supports electrical speedup when a IE external is placed in one of the two auxiliary slots.\n[F] Fixed window rendering issue (issue #15, thanks to ILLOMIURGE).\n[M] Updated ru_ru lang file (Yaroslavik).", @@ -32,7 +33,7 @@ }, "promos": { "1.12.2-recommended": "1.0.3", - "1.12.2-latest": "1.0.3", + "1.12.2-latest": "1.0.4-b1", "1.13.2-recommended": "", "1.13.2-latest": "1.0.2-b3" }