diff --git a/1.12/gradle.properties b/1.12/gradle.properties index c5a9039..46ec143 100644 --- a/1.12/gradle.properties +++ b/1.12/gradle.properties @@ -3,7 +3,7 @@ org.gradle.daemon=false org.gradle.jvmargs=-Xmx8G version_minecraft=1.12.2 version_forge=14.23.5.2768 -version_engineersdecor=1.0.1-b3 +version_engineersdecor=1.0.1-b4 # # jar signing data loaded from signing.properties in the project root. # diff --git a/1.12/meta/update.json b/1.12/meta/update.json index 83e4333..707db83 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.1-b4": "[M] Crafting table keeps inventory and has eight storage slots.\n[M] Adapted inset light strength and harvest tool.\n[M] Crafting table recipe adapted.", "1.0.1-b3": "[A] Added inset light (glowstone-metal, light level like torch, can be used as floor/ceiling/wall light).\n[M] Crafting table model updated (issue #7, thanks majijn).\n[M] Logo image updated.", "1.0.1-b2": "[A] Added treated wood crafting table.\n[A] Added treated wood stool.\n[F] Fixed ladder bounding boxes to allow climbing connected trap doors (issue #6, thanks to Forgilageord).\n[M] Improved wall-block connections (wall elements only connect to other walls or gates, as well as to solid blocks if these blocks are in a straight line with at least two wall elements).\n[M] Decor walls are defined \"solid\" on top, so that e.g. torches and redstone tracks can be placed on them.", "1.0.1-b1": "[F] Fixed missing condition for ie:stone_deco in recipe constants.\n[A] Added clinker brick wall.", @@ -12,6 +13,6 @@ }, "promos": { "1.12.2-recommended": "1.0.0", - "1.12.2-latest": "1.0.1-b3" + "1.12.2-latest": "1.0.1-b4" } } \ No newline at end of file diff --git a/1.12/readme.md b/1.12/readme.md index fb99220..bd756b8 100644 --- a/1.12/readme.md +++ b/1.12/readme.md @@ -10,6 +10,10 @@ Mod sources for Minecraft version 1.12.2. ---- ## Revision history + - v1.0.1-b4 [M] Crafting table keeps inventory and has eight storage slots. + [M] Adapted inset light strength and harvest tool. + [M] Crafting table recipe adapted. + - v1.0.1-b3 [A] Added inset light (glowstone-metal, light level like torch, can be used as floor/ceiling/wall light). [M] Crafting table model updated (issue #7, thanks majijn). diff --git a/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java b/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java index 297108f..2f57c24 100644 --- a/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java +++ b/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java @@ -126,8 +126,7 @@ public class ModEngineersDecor final BlockPos pos = new BlockPos(x,y,z); final TileEntity te = world.getTileEntity(pos); switch(guiid) { - case GUIID_CRAFTING_TABLE: - return (te instanceof BlockDecorCraftingTable.BEntity) ? (new BlockDecorCraftingTable.BContainer(player.inventory, world, pos)) : null; + case GUIID_CRAFTING_TABLE: return BlockDecorCraftingTable.getServerGuiElement(player, world, pos, te); } return null; } @@ -139,8 +138,7 @@ public class ModEngineersDecor final BlockPos pos = new BlockPos(x,y,z); final TileEntity te = (world instanceof WorldClient) ? world.getTileEntity(pos) : null; switch(guiid) { - case GUIID_CRAFTING_TABLE: - return (te instanceof BlockDecorCraftingTable.BEntity) ? (new BlockDecorCraftingTable.BGuiCrafting(player.inventory, world, pos)) : null; + case GUIID_CRAFTING_TABLE: return BlockDecorCraftingTable.getClientGuiElement(player, world, pos, te); } return null; } diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecor.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecor.java index 2a991a9..9166e91 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecor.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecor.java @@ -165,7 +165,6 @@ public class BlockDecor extends Block { return super.getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer, hand); } @Override - public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) - { return super.removedByPlayer(state, world, pos, player, willHarvest); } - + public boolean canHarvestBlock(IBlockAccess world, BlockPos pos, EntityPlayer player) + { return true; } } 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 3f402a2..07b2af5 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java @@ -8,25 +8,33 @@ */ package wile.engineersdecor.blocks; +import wile.engineersdecor.ModEngineersDecor; +import net.minecraft.block.Block; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; +import net.minecraft.world.Explosion; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.*; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; +import net.minecraft.util.NonNullList; import net.minecraft.util.ResourceLocation; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentTranslation; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; -import wile.engineersdecor.ModEngineersDecor; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -34,6 +42,7 @@ import javax.annotation.Nullable; public class BlockDecorCraftingTable extends BlockDecorDirected { + public BlockDecorCraftingTable(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB) { super(registryName, config, material, hardness, resistance, sound, unrotatedAABB); @@ -51,7 +60,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected @Nullable public TileEntity createTileEntity(World world, IBlockState state) - { return new BlockDecorCraftingTable.BEntity(); } + { return new BlockDecorCraftingTable.BTileEntity(); } @Override public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) @@ -61,45 +70,71 @@ public class BlockDecorCraftingTable extends BlockDecorDirected return true; } - //-------------------------------------------------------------------------------------------------------------------- - // TE - //-------------------------------------------------------------------------------------------------------------------- - public static class BEntity extends TileEntity + @Override + public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack) { + if(world.isRemote) return; + if((!stack.hasTagCompound()) || (!stack.getTagCompound().hasKey("inventory"))) return; + NBTTagCompound inventory_nbt = stack.getTagCompound().getCompoundTag("inventory"); + if(inventory_nbt.isEmpty()) return; + final TileEntity te = world.getTileEntity(pos); + if(!(te instanceof BTileEntity)) return; + ((BTileEntity)te).readnbt(inventory_nbt); + ((BTileEntity)te).markDirty(); + } + + private ItemStack itemize_with_inventory(World world, BlockPos pos) + { + TileEntity te = world.getTileEntity(pos); + if(!(te instanceof BTileEntity)) return ItemStack.EMPTY; + ItemStack stack = new ItemStack(this, 1); + NBTTagCompound inventory_nbt = new NBTTagCompound(); + ItemStackHelper.saveAllItems(inventory_nbt, ((BTileEntity)te).stacks, false); + if(!inventory_nbt.isEmpty()) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setTag("inventory", inventory_nbt); + stack.setTagCompound(nbt); + } + return stack; + } + + @Override + public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) + { + if(world.isRemote) return true; + final ItemStack stack = itemize_with_inventory(world, pos); + if(stack != ItemStack.EMPTY) { + world.spawnEntity(new EntityItem(world, pos.getX()+0.5, pos.getY()+0.5, pos.getZ()+0.5, stack)); + world.setBlockToAir(pos); + world.removeTileEntity(pos); + return false; + } else { + return super.removedByPlayer(state, world, pos, player, willHarvest); + } + } + + @Override + public void onBlockExploded(World world, BlockPos pos, Explosion explosion) + { + if(world.isRemote) return; + TileEntity te = world.getTileEntity(pos); + if(!(te instanceof BTileEntity)) return; + for(ItemStack stack: ((BTileEntity)te).stacks) { + if(!stack.isEmpty()) world.spawnEntity(new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack)); + } + ((BTileEntity)te).reset(); + super.onBlockExploded(world, pos, explosion); } //-------------------------------------------------------------------------------------------------------------------- - // Container + // ModEngineersDecor.GuiHandler connectors //-------------------------------------------------------------------------------------------------------------------- - public static class BContainer extends ContainerWorkbench - { - private World world; - private BlockPos pos; - private EntityPlayer player; + public static Object getServerGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te) + { return (te instanceof BTileEntity) ? (new BContainer(player.inventory, world, pos, (BTileEntity)te)) : null; } - public BContainer(InventoryPlayer inv, World world, BlockPos pos) - { - super(inv, world, pos); - this.world = world; - this.pos = pos; - this.player = inv.player; - } - - @Override - public boolean canInteractWith(EntityPlayer playerIn) - { return (world.getBlockState(this.pos).getBlock() instanceof BlockDecorCraftingTable) && (playerIn.getDistanceSq(this.pos) <= 8*8); } - - @Override - public void onCraftMatrixChanged(IInventory inv) - { - try { - slotChangedCraftingGrid(this.world, player, this.craftMatrix, this.craftResult); - } catch(Throwable exc) { - ModEngineersDecor.logger.error("Recipe failed:", exc); - } - } - } + public static Object getClientGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te) + { return (te instanceof BTileEntity) ? (new BGuiCrafting(player.inventory, world, pos, (BTileEntity)te)) : null; } //-------------------------------------------------------------------------------------------------------------------- // GUI @@ -108,8 +143,8 @@ public class BlockDecorCraftingTable extends BlockDecorDirected @SideOnly(Side.CLIENT) public static class BGuiCrafting extends GuiContainer { - public BGuiCrafting(InventoryPlayer playerInventory, World world, BlockPos pos) - { super(new BContainer(playerInventory, world, pos)); } + public BGuiCrafting(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te) + { super(new BContainer(playerInventory, world, pos, te)); } @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) @@ -128,4 +163,302 @@ public class BlockDecorCraftingTable extends BlockDecorDirected } } + //-------------------------------------------------------------------------------------------------------------------- + // Crafting container + //-------------------------------------------------------------------------------------------------------------------- + + public static class BContainer extends Container + { + private final World world; + private final BlockPos pos; + private final EntityPlayer player; + private final BTileEntity te; + public BInventoryCrafting craftMatrix; + public InventoryCraftResult craftResult = new InventoryCraftResult(); + + + public BContainer(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te) + { + this.player = playerInventory.player; + this.world = world; + this.pos = pos; + this.te = te; + this.craftMatrix = new BInventoryCrafting(this, te); + this.craftMatrix.openInventory(player); + this.addSlotToContainer(new SlotCrafting(playerInventory.player, this.craftMatrix, this.craftResult, 0, 124+14, 35)); + for(int y=0; y<3; ++y) { + for(int x=0; x<3; ++x) { + addSlotToContainer(new Slot(this.craftMatrix, x+y*3, 28+30+x*18, 17+y*18)); // block slots 0..8 + } + } + for(int y=0; y<3; ++y) { + for (int x=0; x<9; ++x) { + this.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) { + this.addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144)); // player slots: 0..8 + } + for(int y=0; y<4; ++y) { + for (int x=0; x<2; ++x) { + this.addSlotToContainer(new Slot(this.craftMatrix, x+y*2+9, 8+x*18, 9+y*18)); // block slots 9..17 + } + } + this.onCraftMatrixChanged(this.craftMatrix); + } + + @Override + public boolean canInteractWith(EntityPlayer player) + { return (world.getBlockState(pos).getBlock() instanceof BlockDecorCraftingTable) && (player.getDistanceSq(pos) <= 64); } + + @Override + public void onCraftMatrixChanged(IInventory inv) + { + try { + slotChangedCraftingGrid(this.world, this.player, this.craftMatrix, this.craftResult); + } catch(Throwable exc) { + ModEngineersDecor.logger.error("Recipe failed:", exc); + } + } + + @Override + public void onContainerClosed(EntityPlayer player) + { + craftMatrix.closeInventory(player); + craftResult.clear(); + craftResult.closeInventory(player); + if(player!=null) { + for(Slot e:player.inventoryContainer.inventorySlots) { + if(e instanceof SlotCrafting) { + ((SlotCrafting)e).putStack(ItemStack.EMPTY); + } + } + } + } + + @Override + public boolean canMergeSlot(ItemStack stack, Slot slot) + { return (slot.inventory != this.craftResult) && (super.canMergeSlot(stack, slot)); } + + @Override + public ItemStack transferStackInSlot(EntityPlayer playerIn, int index) + { + ItemStack stack = ItemStack.EMPTY; + Slot slot = this.inventorySlots.get(index); + if((slot == null) || (!slot.getHasStack())) return stack; + ItemStack slotstack = slot.getStack(); + stack = slotstack.copy(); + if(index == 0) { + slotstack.getItem().onCreated(slotstack, this.world, playerIn); + if(!this.mergeItemStack(slotstack, 10, 46, true)) return ItemStack.EMPTY; + slot.onSlotChange(slotstack, stack); + } else if (index >= 10 && (index < 37)) { + if(!this.mergeItemStack(slotstack, 37, 46, false)) return ItemStack.EMPTY; + } else if((index >= 37) && (index < 46)) { + if(!this.mergeItemStack(slotstack, 10, 37, false)) return ItemStack.EMPTY; + } else if(!this.mergeItemStack(slotstack, 10, 46, false)) { + return ItemStack.EMPTY; + } + if(slotstack.isEmpty()) { + slot.putStack(ItemStack.EMPTY); + } else { + slot.onSlotChanged(); + } + if(slotstack.getCount() == stack.getCount()) { + return ItemStack.EMPTY; + } + ItemStack itemstack2 = slot.onTake(playerIn, slotstack); + if(index == 0) { + playerIn.dropItem(itemstack2, false); + } + return stack; + } + } + + //-------------------------------------------------------------------------------------------------------------------- + // Crafting inventory (needed to allow SlotCrafting to have a InventoryCrafting) + //-------------------------------------------------------------------------------------------------------------------- + + public static class BInventoryCrafting extends InventoryCrafting + { + protected final Container container; + protected final IInventory inventory; + + public BInventoryCrafting(Container container_, IInventory inventory_te) { + super(container_, 3, 3); + container = container_; + inventory = inventory_te; + } + + @Override + public int getSizeInventory() + { return 9; } + + @Override + public void openInventory(EntityPlayer player) + { inventory.openInventory(player); } + + @Override + public void closeInventory(EntityPlayer player) + { inventory.closeInventory(player); } + + @Override + public void markDirty() + { inventory.markDirty(); } + + @Override + public void setInventorySlotContents(int index, ItemStack stack) + { + inventory.setInventorySlotContents(index, stack); + container.onCraftMatrixChanged(this); + } + + @Override + public ItemStack getStackInSlot(int index) + { return inventory.getStackInSlot(index); } + + @Override + public ItemStack decrStackSize(int index, int count) + { + final ItemStack stack = inventory.decrStackSize(index, count); + if(!stack.isEmpty()) container.onCraftMatrixChanged(this); + return stack; + } + } + + //-------------------------------------------------------------------------------------------------------------------- + // Tile entity + //-------------------------------------------------------------------------------------------------------------------- + public static class BTileEntity extends TileEntity implements IInventory + { + public static final int NUM_OF_CRAFTING_SLOTS = 9; + public static final int NUM_OF_STORAGE_SLOTS = 9; + public static final int NUM_OF_SLOTS = NUM_OF_CRAFTING_SLOTS+NUM_OF_STORAGE_SLOTS; + protected NonNullList stacks; + + public BTileEntity() + { stacks = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); } + + public void reset() + { stacks = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); } + + public void readnbt(NBTTagCompound compound) + { + reset(); + ItemStackHelper.loadAllItems(compound, this.stacks); + while(this.stacks.size() < NUM_OF_SLOTS) this.stacks.add(ItemStack.EMPTY); + } + + private void writenbt(NBTTagCompound compound) + { ItemStackHelper.saveAllItems(compound, this.stacks); } + + // TileEntity ------------------------------------------------------------------------------ + + @Override + public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns) + { return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorCraftingTable)); } + + @Override + public void readFromNBT(NBTTagCompound compound) + { super.readFromNBT(compound); readnbt(compound); } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound compound) + { super.writeToNBT(compound); writenbt(compound); return compound; } + + //@Override + //public NBTTagCompound getUpdateTag() + //{ return writeToNBT(new NBTTagCompound()); } + + //@Override + //public SPacketUpdateTileEntity getUpdatePacket() + //{ return new SPacketUpdateTileEntity(getPos(), 0x1, getUpdateTag()); } + // + //@Override + //public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) + //{ readFromNBT(pkt.getNbtCompound()); super.onDataPacket(net, pkt); } + + // IWorldNamable --------------------------------------------------------------------------- + + @Override + public String getName() + { final Block block=getBlockType(); return (block!=null) ? (block.getTranslationKey() + ".name") : (""); } + + @Override + public boolean hasCustomName() + { return false; } + + @Override + public ITextComponent getDisplayName() + { return new TextComponentTranslation(getName(), new Object[0]); } + + // IInventory ------------------------------------------------------------------------------ + // @see net.minecraft.inventory.InventoryCrafting + + @Override + public int getSizeInventory() + { return stacks.size(); } + + @Override + public boolean isEmpty() + { for(ItemStack stack: stacks) { if(!stack.isEmpty()) return false; } return true; } + + @Override + public ItemStack getStackInSlot(int index) + { return (index < getSizeInventory()) ? stacks.get(index) : ItemStack.EMPTY; } + + @Override + public ItemStack decrStackSize(int index, int count) + { return ItemStackHelper.getAndSplit(stacks, index, count); } + + @Override + public ItemStack removeStackFromSlot(int index) + { return ItemStackHelper.getAndRemove(stacks, index); } + + @Override + public void setInventorySlotContents(int index, ItemStack stack) + { stacks.set(index, stack); } + + @Override + public int getInventoryStackLimit() + { return 64; } + + @Override + public void markDirty() + { super.markDirty(); } + + @Override + public boolean isUsableByPlayer(EntityPlayer player) + { return true; } + + @Override + public void openInventory(EntityPlayer player) + {} + + @Override + public void closeInventory(EntityPlayer player) + { this.markDirty(); } + + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) + { return true; } + + @Override + public int getField(int id) + { return 0; } + + @Override + public void setField(int id, int value) + {} + + @Override + public int getFieldCount() + { return 0; } + + @Override + public void clear() + { stacks.clear(); } + + } + } diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWall.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWall.java index ab90b07..d63d694 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWall.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWall.java @@ -175,4 +175,9 @@ public class BlockDecorWall extends BlockDecor private boolean canWallConnectTo(IBlockAccess world, BlockPos pos, EnumFacing facing) { return canConnectTo(world, pos, pos.offset(facing), facing.getOpposite()); } + + @Override + public boolean canPlaceTorchOnTop(IBlockState state, IBlockAccess world, BlockPos pos) + { return true; } + } diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java b/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java index ed37653..84bf152 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java @@ -84,7 +84,7 @@ public class ModBlocks public static final BlockDecorDirected INSET_LIGHT_IRON = new BlockDecorDirected( "iron_inset_light", BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT|(14<