From 5b1a6e0877f8529ab87ce40ef5ea2a40b0fddf87 Mon Sep 17 00:00:00 2001 From: stfwi Date: Sun, 19 May 2019 08:18:37 +0200 Subject: [PATCH] Added small waste incinerator. Metal ladders are easier to break. Missing Override annotations added. Experimental factory dropper concept impl added. --- 1.12/gradle.properties | 2 +- 1.12/meta/update.json | 3 +- 1.12/readme.md | 4 + .../engineersdecor/ModEngineersDecor.java | 4 +- .../blocks/BlockDecorCraftingTable.java | 3 +- .../blocks/BlockDecorDropper.java | 900 ++++++++++++++++++ .../blocks/BlockDecorFurnace.java | 9 +- .../blocks/BlockDecorFurnaceElectrical.java | 6 + .../blocks/BlockDecorLadder.java | 3 +- .../blocks/BlockDecorWasteIncinerator.java | 20 +- .../wile/engineersdecor/blocks/ModBlocks.java | 32 +- .../wile/engineersdecor/detail/ModConfig.java | 14 + .../blockstates/factory_dropper.json | 12 + .../assets/engineersdecor/lang/en_us.lang | 3 + .../assets/engineersdecor/lang/ru_ru.lang | 3 + .../block/device/factory_dropper_model.json | 83 ++ .../engineersdecor/recipes/_constants.json | 4 + .../recipes/factory_dropper_recipe.json | 33 + .../blocks/device/factory_dropper_bottom.png | Bin 0 -> 640 bytes .../blocks/device/factory_dropper_side.png | Bin 0 -> 555 bytes .../blocks/device/factory_dropper_top.png | Bin 0 -> 572 bytes .../textures/gui/factory_dropper_gui.png | Bin 0 -> 19739 bytes meta/update.json | 3 +- 23 files changed, 1114 insertions(+), 27 deletions(-) create mode 100644 1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java create mode 100644 1.12/src/main/resources/assets/engineersdecor/blockstates/factory_dropper.json create mode 100644 1.12/src/main/resources/assets/engineersdecor/models/block/device/factory_dropper_model.json create mode 100644 1.12/src/main/resources/assets/engineersdecor/recipes/factory_dropper_recipe.json create mode 100644 1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_bottom.png create mode 100644 1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_side.png create mode 100644 1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_top.png create mode 100644 1.12/src/main/resources/assets/engineersdecor/textures/gui/factory_dropper_gui.png diff --git a/1.12/gradle.properties b/1.12/gradle.properties index 57d8755..ae024fa 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.5 +version_engineersdecor=1.0.6-b1 diff --git a/1.12/meta/update.json b/1.12/meta/update.json index 4612750..08f95ca 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.6-b1": "[A] Added small waste incinerator (delayed fifo-buffered item disposal).\n[M] Fixed item/block name capitalization (by Voxelo).\n[M] Metal ladders are easier to break/harvest.", "1.0.5": "[R] Release based on v1.0.5-b1. Release-to-release changes: * Small electrical passthrough-furnace added. * Passive fluid accumulator added. * Config options added. * Sign plates added. * Minor bug fixes.\n[A] Added sign \"Electrical hazzard\"/\"Caution hot wire\".\n[A] Added sign \"Caution dangerous there\" (skull/bones).", "1.0.5-b1": "[A] Added passive fluid accumulator.\n[A] Added small electrical passthrough-furnace.\n[F] Fixed version check URL.\n[M] Opt-out config options for valves, passive fluid accumulator, and furni.", "1.0.4": "[R] Release based on v1.0.4-b9. Release-to-release changes: * Crafting table: Quick crafting history re-fab, JEI integration. * Rendering improvements and issue fixes (stairs, ambient occlusion, optifine, etc). * Walls with texture variations. * Thin/thick steel poles with support feet/heads. * Horizontal steel double-T support beams added. * Fluid pipe valves added: Check valve, redstone controlled valve, analog redstone controlled valve. Support pressurized transfer. * Tool tip documentation (CTRL-SHIFT) for stairs added. * Internal code cleanups. * Recipes tuned.\n[E] Added pass-through electrical furnace (experimental, see config).", @@ -36,6 +37,6 @@ }, "promos": { "1.12.2-recommended": "1.0.5", - "1.12.2-latest": "1.0.5" + "1.12.2-latest": "1.0.6-b1" } } \ No newline at end of file diff --git a/1.12/readme.md b/1.12/readme.md index 1a9342e..79b7ccb 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.6-b1 [A] Added small waste incinerator (delayed fifo-buffered item disposal). + [M] Fixed item/block name capitalization (by Voxelo). + [M] Metal ladders are easier to break/harvest. + ------------------------------------------------------------------- - v1.0.5 [R] Release based on v1.0.5-b1. Release-to-release changes: * Small electrical passthrough-furnace added. diff --git a/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java b/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java index 5d70363..141bd39 100644 --- a/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java +++ b/1.12/src/main/java/wile/engineersdecor/ModEngineersDecor.java @@ -155,6 +155,7 @@ public class ModEngineersDecor public static final int GUIID_SMALL_LAB_FURNACE = 213102; public static final int GUIID_ELECTRICAL_LAB_FURNACE = 213103; public static final int GUIID_SMALL_WASTE_INCINERATOR = 213104; + public static final int GUIID_FACTORY_DROPPER = 213105; @Override public Object getServerGuiElement(final int guiid, final EntityPlayer player, final World world, int x, int y, int z) @@ -166,6 +167,7 @@ public class ModEngineersDecor case GUIID_SMALL_LAB_FURNACE: return BlockDecorFurnace.getServerGuiElement(player, world, pos, te); case GUIID_ELECTRICAL_LAB_FURNACE: return BlockDecorFurnaceElectrical.getServerGuiElement(player, world, pos, te); case GUIID_SMALL_WASTE_INCINERATOR: return BlockDecorWasteIncinerator.getServerGuiElement(player, world, pos, te); + case GUIID_FACTORY_DROPPER: return BlockDecorDropper.getServerGuiElement(player, world, pos, te); } return null; } @@ -181,10 +183,10 @@ public class ModEngineersDecor case GUIID_SMALL_LAB_FURNACE: return BlockDecorFurnace.getClientGuiElement(player, world, pos, te); case GUIID_ELECTRICAL_LAB_FURNACE: return BlockDecorFurnaceElectrical.getClientGuiElement(player, world, pos, te); case GUIID_SMALL_WASTE_INCINERATOR: return BlockDecorWasteIncinerator.getClientGuiElement(player, world, pos, te); + case GUIID_FACTORY_DROPPER: return BlockDecorDropper.getClientGuiElement(player, world, pos, te); } return null; } - } @Mod.EventBusSubscriber 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 8d225cb..0a04d0b 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorCraftingTable.java @@ -73,8 +73,7 @@ public class BlockDecorCraftingTable extends BlockDecorDirected } @Override - @SuppressWarnings("deprecation") - public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) + public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { return getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()); } @Override diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java new file mode 100644 index 0000000..853879a --- /dev/null +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java @@ -0,0 +1,900 @@ +/* + * @file BlockDecorDropper.java + * @author Stefan Wilhelm (wile) + * @copyright (C) 2019 Stefan Wilhelm + * @license MIT (see https://opensource.org/licenses/MIT) + * + * Dropper factory automation suitable. + */ +package wile.engineersdecor.blocks; + +import wile.engineersdecor.ModEngineersDecor; +import net.minecraft.block.properties.PropertyBool; +import net.minecraft.block.state.BlockStateContainer; +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.block.BlockDoor; +import net.minecraft.world.World; +import net.minecraft.world.Explosion; +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.tileentity.TileEntity; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.item.*; +import net.minecraft.inventory.*; +import net.minecraft.client.gui.inventory.GuiContainer; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.util.*; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentTranslation; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import wile.engineersdecor.detail.Networking; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.io.IOException; + +public class BlockDecorDropper extends BlockDecorDirected +{ + public static final PropertyBool OPEN = BlockDoor.OPEN; + + public BlockDecorDropper(@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); } + + @Override + protected BlockStateContainer createBlockState() + { return new BlockStateContainer(this, FACING, OPEN); } + + @Override + public IBlockState getStateFromMeta(int meta) + { return super.getStateFromMeta(meta).withProperty(OPEN, (meta & 0x8)!=0); } + + @Override + public int getMetaFromState(IBlockState state) + { return super.getMetaFromState(state) | (state.getValue(OPEN) ? 0x8 : 0x0); } + + @Override + public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) + { return super.getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer, hand).withProperty(OPEN, false); } + + @Override + @SuppressWarnings("deprecation") + public boolean hasComparatorInputOverride(IBlockState state) + { return true; } + + @Override + @SuppressWarnings("deprecation") + public int getComparatorInputOverride(IBlockState blockState, World world, BlockPos pos) + { return Container.calcRedstone(world.getTileEntity(pos)); } + + @Override + public boolean hasTileEntity(IBlockState state) + { return true; } + + @Nullable + public TileEntity createTileEntity(World world, IBlockState state) + { return new BlockDecorDropper.BTileEntity(); } + + @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 BlockDecorDropper.BTileEntity)) return; + ((BlockDecorDropper.BTileEntity)te).readnbt(inventory_nbt, false); + ((BlockDecorDropper.BTileEntity)te).markDirty(); + } + + @Override + public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest) + { + if(world.isRemote) return true; + TileEntity te = world.getTileEntity(pos); + if(!(te instanceof BTileEntity)) return super.removedByPlayer(state, world, pos, player, willHarvest); + 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); + } + 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; + } + + @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); + } + + @Override + public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) + { + if(world.isRemote) return true; + player.openGui(ModEngineersDecor.instance, ModEngineersDecor.GuiHandler.GUIID_FACTORY_DROPPER, world, pos.getX(), pos.getY(), pos.getZ()); + return true; + } + + @Override + public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos neighborPos) + { + if(!(world instanceof World) || (((World) world).isRemote)) return; + TileEntity te = world.getTileEntity(pos); + if(!(te instanceof BTileEntity)) return; + ((BTileEntity)te).block_updated(); + } + + //-------------------------------------------------------------------------------------------------------------------- + // ModEngineersDecor.GuiHandler connectors + //-------------------------------------------------------------------------------------------------------------------- + + 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 static Object getClientGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te) + { return (te instanceof BTileEntity) ? (new BGui(player.inventory, world, pos, (BTileEntity)te)) : null; } + + //-------------------------------------------------------------------------------------------------------------------- + // GUI + //-------------------------------------------------------------------------------------------------------------------- + + @SideOnly(Side.CLIENT) + private static class BGui extends GuiContainer + { + private final BTileEntity te; + + public BGui(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te) + { super(new BContainer(playerInventory, world, pos, te)); this.te = te; } + + @Override + public void initGui() + { super.initGui(); } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) + { + drawDefaultBackground(); + super.drawScreen(mouseX, mouseY, partialTicks); + renderHoveredToolTip(mouseX, mouseY); + } + + @Override + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException + { + super.mouseClicked(mouseX, mouseY, mouseButton); + BContainer container = (BContainer)inventorySlots; + if(container.fields_.length != 16) return; + int mx = mouseX - getGuiLeft(), my = mouseY - getGuiTop(); + if(isPointInRegion(130, 10, 12, 25, mouseX, mouseY)) { + int force_percent = 100 - MathHelper.clamp(((my-10)*100)/25, 0, 100); + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("drop_speed", force_percent); + Networking.PacketTileNotify.sendToServer(te, nbt); + } else if(isPointInRegion(145, 10, 25, 25, mouseX, mouseY)) { + int xdev = MathHelper.clamp(((mx-157) * 100) / 12, -100, 100); + int ydev = -MathHelper.clamp(((my-22) * 100) / 12, -100, 100); + if(Math.abs(xdev) < 3) xdev = 0; + if(Math.abs(ydev) < 3) ydev = 0; + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("drop_xdev", xdev); + nbt.setInteger("drop_ydev", ydev); + Networking.PacketTileNotify.sendToServer(te, nbt); + } else if(isPointInRegion(129, 40, 44, 10, mouseX, mouseY)) { + int ndrop = (mx-135); + if(ndrop < -1) { + ndrop = container.fields_[4] - 1; // - + } else if(ndrop >= 36) { + ndrop = container.fields_[4] + 1; // + + } else { + ndrop = MathHelper.clamp(1+ndrop, 1, 32); // slider + } + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("drop_count", ndrop); + Networking.PacketTileNotify.sendToServer(te, nbt); + } else if( + isPointInRegion(114, 51, 9, 9, mouseX, mouseY) || + isPointInRegion(162, 66, 7, 9, mouseX, mouseY) + ) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("manual_trigger", 1); + Networking.PacketTileNotify.sendToServer(te, nbt); + } + } + + @Override + protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) + { + GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); + mc.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/factory_dropper_gui.png")); + final int x0=getGuiLeft(), y0=getGuiTop(), w=getXSize(), h=getYSize(); + drawTexturedModalRect(x0, y0, 0, 0, w, h); + BContainer container = (BContainer)inventorySlots; + if(container.fields_.length != 16) return; // no init, no cake. + // active drop slot + { + int drop_slot_index = container.fields_[15]; + if((drop_slot_index < 0) || (drop_slot_index >= 16)) drop_slot_index = 0; + int x = (x0+9+((drop_slot_index % 6) * 18)); + int y = (y0+5+((drop_slot_index / 6) * 17)); + drawTexturedModalRect(x, y, 180, 45, 18, 18); + } + // filter LEDs + { + for(int i=0; i<3; ++i) { + int xt = 180 + (6 * container.fields_[12+i]), yt = 38; + int x = x0 + 31 + (i * 36), y = y0 + 65; + drawTexturedModalRect(x, y, xt, yt, 6, 6); + } + } + // force adjustment + { + int hy = 2 + (((100-container.fields_[0]) * 21) / 100); + int x = x0+135, y = y0+12, xt = 181; + int yt = 4 + (23-hy); + drawTexturedModalRect(x, y, xt, yt, 3, hy); + } + // angle adjustment + { + int x = x0 + 157 - 3 + ((container.fields_[1] * 12) / 100); + int y = y0 + 22 - 3 - ((container.fields_[2] * 12) / 100); + drawTexturedModalRect(x, y, 180, 30, 7, 7); + } + // drop count + { + int x = x0 + 134 - 2 + (container.fields_[4]); + int y = y0 + 44; + drawTexturedModalRect(x, y, 190, 31, 5, 5); + } + // redstone input + { + if(container.fields_[11] != 0) { + drawTexturedModalRect(x0+114, y0+51, 189, 18, 9, 9); + } + } + } + } + + //-------------------------------------------------------------------------------------------------------------------- + // container + //-------------------------------------------------------------------------------------------------------------------- + + public static class BContainer extends Container + { + private static final int PLAYER_INV_START_SLOTNO = BTileEntity.NUM_OF_SLOTS; + private final World world; + private final BlockPos pos; + private final EntityPlayer player; + private final BTileEntity te; + private int fields_[] = new int[16]; + + public BContainer(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te) + { + this.player = playerInventory.player; + this.world = world; + this.pos = pos; + this.te = te; + int i=-1; + // input slots (stacks 0 to 11) + for(int y=0; y<2; ++y) { + for(int x=0; x<6; ++x) { + int xpos = 10+x*18, ypos = 6+y*17; + addSlotToContainer(new Slot(te, ++i, xpos, ypos)); + } + } + // filter slots (stacks 12 to 14) + addSlotToContainer(new Slot(te, ++i, 19, 48)); + addSlotToContainer(new Slot(te, ++i, 55, 48)); + addSlotToContainer(new Slot(te, ++i, 91, 48)); + // player slots + for(int x=0; x<9; ++x) { + addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 144)); // player slots: 0..8 + } + 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 + } + } + } + + public BlockPos getPos() + { return pos; } + + @Override + public void addListener(IContainerListener listener) + { super.addListener(listener); listener.sendAllWindowProperties(this, te); } + + @Override + public void detectAndSendChanges() + { + super.detectAndSendChanges(); + for(int il=0; il= fields_.length)) return; + fields_[id] = value; + te.setField(id, value); + } + + @Override + public boolean canInteractWith(EntityPlayer player) + { return (world.getBlockState(pos).getBlock() instanceof BlockDecorDropper) && (player.getDistanceSq(pos) <= 64); } + + @Override + public ItemStack transferStackInSlot(EntityPlayer player, int index) + { + Slot slot = inventorySlots.get(index); + if((slot==null) || (!slot.getHasStack())) return ItemStack.EMPTY; + ItemStack slot_stack = slot.getStack(); + ItemStack transferred = slot_stack.copy(); + if((index>=0) && (index= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO+36)) { + // Player slot + if(!mergeItemStack(slot_stack, 0, BTileEntity.INPUT_SLOTS_SIZE, false)) return ItemStack.EMPTY; + } else { + // invalid slot + return ItemStack.EMPTY; + } + if(slot_stack.isEmpty()) { + slot.putStack(ItemStack.EMPTY); + } else { + slot.onSlotChanged(); + } + if(slot_stack.getCount() == transferred.getCount()) return ItemStack.EMPTY; + slot.onTake(player, slot_stack); + return transferred; + } + } + + //-------------------------------------------------------------------------------------------------------------------- + // Tile entity + //-------------------------------------------------------------------------------------------------------------------- + + public static class BTileEntity extends TileEntity implements ITickable, ISidedInventory, IItemHandler, Networking.IPacketReceiver + { + public static final int TICK_INTERVAL = 32; + public static final int NUM_OF_SLOTS = 15; + public static final int INPUT_SLOTS_FIRST = 0; + public static final int INPUT_SLOTS_SIZE = 12; + public static final int CTRL_SLOTS_FIRST = INPUT_SLOTS_SIZE; + public static final int CTRL_SLOTS_SIZE = 3; + + private int tick_timer_ = 0; + private int filter_matches_[] = new int[CTRL_SLOTS_SIZE]; + private boolean active_ = false; + private boolean block_power_signal_ = false; + private boolean block_power_updated_ = false; + private int drop_speed_ = 10; + private int drop_noise_ = 0; + private int drop_xdev_ = 0; + private int drop_ydev_ = 0; + private int drop_slot_index_ = 0; + private int drop_count_ = 0; + + protected NonNullList stacks_; + + public static void on_config(int cooldown_ticks) + { + // ModEngineersDecor.logger.info("Config factory dropper:"); + } + + public BTileEntity() + { reset(); } + + protected void reset() + { + stacks_ = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); + block_power_signal_ = false; + block_power_updated_ = false; + drop_count_ = 0; + for(int i=0; iwithSize(NUM_OF_SLOTS, ItemStack.EMPTY); + ItemStackHelper.loadAllItems(nbt, stacks_); + while(stacks_.size() < NUM_OF_SLOTS) stacks_.add(ItemStack.EMPTY); + active_ = nbt.getBoolean("active"); + block_power_signal_ = nbt.getBoolean("powered"); + drop_speed_ = nbt.getInteger("drop_speed"); + drop_noise_ = nbt.getInteger("drop_noise"); + drop_xdev_ = nbt.getInteger("drop_xdev"); + drop_ydev_ = nbt.getInteger("drop_ydev"); + drop_slot_index_ = nbt.getInteger("drop_slot_index"); + drop_count_ = nbt.getInteger("drop_count"); + } + + protected void writenbt(NBTTagCompound nbt, boolean update_packet) + { + ItemStackHelper.saveAllItems(nbt, stacks_); + nbt.setBoolean("active", active_); + nbt.setBoolean("powered", block_power_signal_); + nbt.setInteger("drop_speed", drop_speed_); + nbt.setInteger("drop_noise", drop_noise_); + nbt.setInteger("drop_xdev", drop_xdev_); + nbt.setInteger("drop_ydev", drop_ydev_); + nbt.setInteger("drop_slot_index", drop_slot_index_); + nbt.setInteger("drop_count", drop_count_); + } + + private ItemStack shiftStacks(final int index_from, final int index_to) + { + if(index_from >= index_to) return ItemStack.EMPTY; + ItemStack out_stack = ItemStack.EMPTY; + ItemStack stack = stacks_.get(index_from); + for(int i=index_from+1; i<=index_to; ++i) { + out_stack = stacks_.get(i); + stacks_.set(i, stack); + stack = out_stack; + } + stacks_.set(index_from, ItemStack.EMPTY); + return out_stack; + } + + private boolean transferItems(final int index_from, final int index_to, int count) + { + ItemStack from = stacks_.get(index_from); + if(from.isEmpty()) return false; + ItemStack to = stacks_.get(index_to); + if(from.getCount() < count) count = from.getCount(); + if(count <= 0) return false; + boolean changed = true; + if(to.isEmpty()) { + stacks_.set(index_to, from.splitStack(count)); + } else if(to.getCount() >= to.getMaxStackSize()) { + changed = false; + } else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) { + changed = false; + } else { + if((to.getCount()+count) >= to.getMaxStackSize()) { + from.shrink(to.getMaxStackSize()-to.getCount()); + to.setCount(to.getMaxStackSize()); + } else { + from.shrink(count); + to.grow(count); + } + } + if(from.isEmpty() && from!=ItemStack.EMPTY) { + stacks_.set(index_from, ItemStack.EMPTY); + changed = true; + } + return changed; + } + + public void block_updated() + { + // RS power check, both edges + boolean powered = world.isBlockPowered(pos); + if(block_power_signal_ != powered) block_power_updated_ = true; + block_power_signal_ = powered; + tick_timer_ = 1; + } + + public boolean is_input_slot(int index) + { return (index >= INPUT_SLOTS_FIRST) && (index < (INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE)); } + + // TileEntity ------------------------------------------------------------------------------ + + @Override + public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns) + { return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorDropper)); } + + @Override + public void readFromNBT(NBTTagCompound nbt) + { super.readFromNBT(nbt); readnbt(nbt, false); } + + @Override + public NBTTagCompound writeToNBT(NBTTagCompound nbt) + { super.writeToNBT(nbt); writenbt(nbt, false); return nbt; } + + // 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 ------------------------------------------------------------------------------ + + @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); + if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit()); + tick_timer_ = 2; + markDirty(); + } + + @Override + public int getInventoryStackLimit() + { return 64; } + + @Override + public void markDirty() + { super.markDirty(); } + + @Override + public boolean isUsableByPlayer(EntityPlayer player) + { return ((world.getTileEntity(pos) == this) && (player.getDistanceSq(pos.getX()+0.5d, pos.getY()+0.5d, pos.getZ()+0.5d) <= 64.0d)); } + + @Override + public void openInventory(EntityPlayer player) + {} + + @Override + public void closeInventory(EntityPlayer player) + { markDirty(); } + + @Override + public boolean isItemValidForSlot(int index, ItemStack stack) + { return true; } + + @Override + public int getField(int id) + { + switch(id) { + case 0: return drop_speed_; + case 1: return drop_xdev_; + case 2: return drop_ydev_; + case 3: return drop_noise_; + case 4: return drop_count_; + case 10: return active_ ? 1 : 0; + case 11: return block_power_signal_ ? 1 : 0; + case 12: return filter_matches_[0]; + case 13: return filter_matches_[1]; + case 14: return filter_matches_[2]; + case 15: return drop_slot_index_; + default: return 0; + } + } + + @Override + public void setField(int id, int value) + { + switch(id) { + case 0: drop_speed_ = MathHelper.clamp(value, 0, 100); return; + case 1: drop_xdev_ = MathHelper.clamp(value, -100, 100); return; + case 2: drop_ydev_ = MathHelper.clamp(value, -100, 100); return; + case 3: drop_noise_ = MathHelper.clamp(value, 0, 100); return; + case 4: drop_count_ = MathHelper.clamp(value, 1, 64); return; + case 10: active_ = (value != 0); return; + case 11: block_power_signal_ = (value != 0); return; + case 12: filter_matches_[0] = (value & 0x3); return; + case 13: filter_matches_[1] = (value & 0x3); return; + case 14: filter_matches_[2] = (value & 0x3); return; + case 15: drop_slot_index_ = MathHelper.clamp(value, INPUT_SLOTS_FIRST, INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE-1); return; + default: return; + } + } + + @Override + public int getFieldCount() + { return 16; } + + @Override + public void clear() + { stacks_.clear(); } + + // ISidedInventory ---------------------------------------------------------------------------- + + private static final int[] SIDED_INV_SLOTS; + static { + SIDED_INV_SLOTS = new int[INPUT_SLOTS_SIZE]; + for(int i=INPUT_SLOTS_FIRST; i= Math.min(slotstack.getMaxStackSize(), getSlotLimit(index))) return stack; + if(!ItemHandlerHelper.canItemStacksStack(stack, slotstack)) return stack; + if(!canInsertItem(slotno, stack, EnumFacing.UP) || (!isItemValidForSlot(slotno, stack))) return stack; + int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index)) - slotstack.getCount(); + if(stack.getCount() <= n) { + if(!simulate) { + ItemStack copy = stack.copy(); + copy.grow(slotstack.getCount()); + setInventorySlotContents(slotno, copy); + } + return ItemStack.EMPTY; + } else { + stack = stack.copy(); + if(!simulate) { + ItemStack copy = stack.splitStack(n); + copy.grow(slotstack.getCount()); + setInventorySlotContents(slotno, copy); + return stack; + } else { + stack.shrink(n); + return stack; + } + } + } else { + if(!canInsertItem(slotno, stack, EnumFacing.UP) || (!isItemValidForSlot(slotno, stack))) return stack; + int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index)); + if(n < stack.getCount()) { + stack = stack.copy(); + if(!simulate) { + setInventorySlotContents(slotno, stack.splitStack(n)); + return stack; + } else { + stack.shrink(n); + return stack; + } + } else { + if(!simulate) setInventorySlotContents(slotno, stack); + return ItemStack.EMPTY; + } + } + } + + @Override + @Nonnull + public ItemStack extractItem(int index, int amount, boolean simulate) + { + if((amount <= 0) || (!is_input_slot(index))) return ItemStack.EMPTY; + ItemStack stack = stacks_.get(index).copy(); + if(stack.getCount() > amount) stack.setCount(amount); + if(simulate) return stack; + stacks_.get(index).shrink(stack.getCount()); + return stack; + } + + // Capability export ---------------------------------------------------------------------------- + + @Override + public boolean hasCapability(Capability cap, EnumFacing facing) + { return (cap==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) || super.hasCapability(cap, facing); } + + @Override + @SuppressWarnings("unchecked") + @Nullable + public T getCapability(Capability capability, @Nullable EnumFacing facing) + { + if((facing != null) && (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)) { + return (T)this; + } else { + return super.getCapability(capability, facing); + } + } + + // IPacketReceiver ------------------------------------------------------------------------------- + + @Override + public void onServerPacketReceived(NBTTagCompound nbt) + {} + + @Override + public void onClientPacketReceived(EntityPlayer player, NBTTagCompound nbt) + { + if(nbt.hasKey("drop_speed")) drop_speed_ = MathHelper.clamp(nbt.getInteger("drop_speed"), 0, 100); + if(nbt.hasKey("drop_xdev")) drop_xdev_ = MathHelper.clamp(nbt.getInteger("drop_xdev"), -100, 100); + if(nbt.hasKey("drop_ydev")) drop_ydev_ = MathHelper.clamp(nbt.getInteger("drop_ydev"), -100, 100); + if(nbt.hasKey("drop_count")) drop_count_ = MathHelper.clamp(nbt.getInteger("drop_count"), 1, 64); + if(nbt.hasKey("manual_trigger") && (nbt.getInteger("manual_trigger")!=0)) { block_power_signal_ = true; block_power_updated_ = true; tick_timer_ = 1; } + markDirty(); + } + + // ITickable and aux methods --------------------------------------------------------------------- + + private static void drop(World world, BlockPos pos, EnumFacing facing, ItemStack stack, int speed_percent, int xdeviation, int ydeviation, int noise_percent) + { + final double ofs = facing==EnumFacing.DOWN ? 0.8 : 0.7; + Vec3d v0 = new Vec3d(facing.getXOffset(), facing.getYOffset(), facing.getZOffset()); + final EntityItem ei = new EntityItem(world, (pos.getX()+0.5)+(ofs*v0.x), (pos.getY()+0.5)+(ofs*v0.y), (pos.getZ()+0.5)+(ofs*v0.z), stack); + if((xdeviation != 0) || (ydeviation != 0)) { + double vdx = 1e-2 * MathHelper.clamp(xdeviation, -100, 100); + double vdy = 1e-2 * MathHelper.clamp(ydeviation, -100, 100); + switch(facing) { // switch-case faster than coorsys fwd transform + case DOWN: v0 = v0.add( vdx, 0, vdy); break; // down/up: use xz + case NORTH: v0 = v0.add( vdx, vdy, 0); break; + case SOUTH: v0 = v0.add(-vdx, vdy, 0); break; + case EAST: v0 = v0.add(0, vdy, vdx); break; + case WEST: v0 = v0.add(0, vdy, -vdx); break; + case UP: v0 = v0.add( vdx, 0, vdy); break; + } + } + if(noise_percent > 0) { + v0 = v0.add( + ((world.rand.nextDouble()-0.5) * 1e-3 * noise_percent), + ((world.rand.nextDouble()-0.5) * 1e-3 * noise_percent), + ((world.rand.nextDouble()-0.5) * 1e-3 * noise_percent) + ); + } + if(speed_percent < 5) speed_percent = 5; + double speed = 1e-2 * speed_percent; + if(noise_percent > 0) speed += (world.rand.nextDouble()-0.5) * 1e-4 * noise_percent; + v0 = v0.normalize().scale(speed); + ei.motionX = v0.x; + ei.motionY = v0.y; + ei.motionZ = v0.z; + world.spawnEntity(ei); + } + + @Nullable + IBlockState update_blockstate() + { + IBlockState state = world.getBlockState(pos); + if(!(state.getBlock() instanceof BlockDecorDropper)) return null; + if(state.getValue(OPEN) != active_) { + state = state.withProperty(OPEN, active_); + world.setBlockState(pos, state); + } + return state; + } + + private static int next_slot(int i) + { return (i 0)) return; + tick_timer_ = TICK_INTERVAL; + final IBlockState state = update_blockstate(); + if(state == null) { block_power_signal_= false; return; } + boolean dirty = block_power_updated_; + boolean trigger = (block_power_signal_ && block_power_updated_); + int drop_count = MathHelper.clamp(drop_count_, 1, 64); + boolean slot_assigned = false; + if(!trigger) { + int last_filter_matches_[] = filter_matches_.clone(); + for(int ci=0; ci= INPUT_SLOTS_SIZE) drop_slot_index_ = 0; + int ic = drop_slot_index_; + drop_slot_index_ = next_slot(drop_slot_index_); + ItemStack ds = stacks_.get(ic); + if((!ds.isEmpty()) && (ds.getCount() >= drop_count)) { + drop_stack = ds.splitStack(drop_count); + break; + } + } + for(int i=0; i 10)) tick_timer_ = 10; + } + } + +} diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnace.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnace.java index 6bb7c42..8575b28 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnace.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnace.java @@ -79,8 +79,7 @@ public class BlockDecorFurnace extends BlockDecorDirected { return (state.getValue(FACING).getHorizontalIndex() & 0x3) | (state.getValue(LIT) ? 4 : 0); } @Override - @SuppressWarnings("deprecation") - public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) + public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { return getDefaultState().withProperty(FACING, placer.getHorizontalFacing().getOpposite()).withProperty(LIT, false); } @Override @@ -747,21 +746,27 @@ public class BlockDecorFurnace extends BlockDecorDirected // IEnergyStorage ---------------------------------------------------------------------------- + @Override public boolean canExtract() { return false; } + @Override public boolean canReceive() { return true; } + @Override public int getMaxEnergyStored() { return boost_energy_consumption; } + @Override public int getEnergyStored() { return boost_energy_; } + @Override public int extractEnergy(int maxExtract, boolean simulate) { return 0; } + @Override public int receiveEnergy(int maxReceive, boolean simulate) { // only speedup support, no buffering, not in nbt -> no markdirty if((boost_energy_ >= boost_energy_consumption) || (maxReceive < boost_energy_consumption)) return 0; diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnaceElectrical.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnaceElectrical.java index 65a73cf..894ff3f 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnaceElectrical.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnaceElectrical.java @@ -450,21 +450,27 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace // IEnergyStorage ---------------------------------------------------------------------------- + @Override public boolean canExtract() { return false; } + @Override public boolean canReceive() { return true; } + @Override public int getMaxEnergyStored() { return MAX_ENERGY_BUFFER; } + @Override public int getEnergyStored() { return energy_stored_; } + @Override public int extractEnergy(int maxExtract, boolean simulate) { return 0; } + @Override public int receiveEnergy(int maxReceive, boolean simulate) { if(energy_stored_ >= MAX_ENERGY_BUFFER) return 0; diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorLadder.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorLadder.java index a6524e5..9c02892 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorLadder.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorLadder.java @@ -98,8 +98,7 @@ public class BlockDecorLadder extends BlockLadder { return canAttachTo(world, pos.west(), side) || canAttachTo(world, pos.east(), side) || canAttachTo(world, pos.north(), side) || canAttachTo(world, pos.south(), side); } @Override - @SuppressWarnings("deprecation") - public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) + public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { if(facing.getAxis().isHorizontal() && canAttachTo(world, pos.offset(facing.getOpposite()), facing)) return this.getDefaultState().withProperty(FACING, facing); for(EnumFacing e:EnumFacing.Plane.HORIZONTAL) { diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWasteIncinerator.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWasteIncinerator.java index e674434..df92fb8 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWasteIncinerator.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWasteIncinerator.java @@ -70,8 +70,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor { return (state.getValue(LIT) ? 4 : 0); } @Override - @SuppressWarnings("deprecation") - public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) + public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand) { return getDefaultState().withProperty(LIT, false); } @Override @@ -320,7 +319,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor private int tick_timer_; private int check_timer_; private int energy_stored_; - protected NonNullList stacks_; + protected NonNullList stacks_ = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick) { @@ -340,9 +339,10 @@ public class BlockDecorWasteIncinerator extends BlockDecor public void readnbt(NBTTagCompound compound) { - reset(); - ItemStackHelper.loadAllItems(compound, stacks_); - while(stacks_.size() < NUM_OF_SLOTS) stacks_.add(ItemStack.EMPTY); + NonNullList stacks = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); + ItemStackHelper.loadAllItems(compound, stacks); + while(stacks.size() < NUM_OF_SLOTS) stacks.add(ItemStack.EMPTY); + stacks_ = stacks; energy_stored_ = compound.getInteger("Energy"); } @@ -436,7 +436,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor @Override public ItemStack getStackInSlot(int index) - { return (index < getSizeInventory()) ? stacks_.get(index) : ItemStack.EMPTY; } + { return ((index >= 0) && (index < getSizeInventory())) ? stacks_.get(index) : ItemStack.EMPTY; } @Override public ItemStack decrStackSize(int index, int count) @@ -512,21 +512,27 @@ public class BlockDecorWasteIncinerator extends BlockDecor // IEnergyStorage ---------------------------------------------------------------------------- + @Override public boolean canExtract() { return false; } + @Override public boolean canReceive() { return true; } + @Override public int getMaxEnergyStored() { return MAX_ENERGY_BUFFER; } + @Override public int getEnergyStored() { return energy_stored_; } + @Override public int extractEnergy(int maxExtract, boolean simulate) { return 0; } + @Override public int receiveEnergy(int maxReceive, boolean simulate) { if(energy_stored_ >= MAX_ENERGY_BUFFER) return 0; 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 15f5fb6..0a0eae8 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java @@ -12,13 +12,13 @@ */ package wile.engineersdecor.blocks; -import net.minecraft.tileentity.TileEntity; import wile.engineersdecor.ModEngineersDecor; import wile.engineersdecor.detail.ModAuxiliaries; import wile.engineersdecor.detail.ModConfig; import net.minecraft.block.Block; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; +import net.minecraft.tileentity.TileEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.util.ResourceLocation; @@ -56,9 +56,9 @@ public class ModBlocks public static final BlockDecorWall CONCRETE_WALL = new BlockDecorWall("concrete_wall", BlockDecor.CFG_DEFAULT, Material.ROCK, 5f, 20f, SoundType.STONE); - public static final BlockDecorLadder METAL_RUNG_LADDER = new BlockDecorLadder("metal_rung_ladder", 0, Material.IRON, 1.0f, 20f, SoundType.METAL); - public static final BlockDecorLadder METAL_RUNG_STEPS = new BlockDecorLadder("metal_rung_steps", 0, Material.IRON, 1.0f, 20f, SoundType.METAL); - public static final BlockDecorLadder TREATED_WOOD_LADDER = new BlockDecorLadder("treated_wood_ladder", 0, Material.WOOD, 1.0f, 10f, SoundType.WOOD); + public static final BlockDecorLadder METAL_RUNG_LADDER = new BlockDecorLadder("metal_rung_ladder", 0, Material.IRON, 0.5f, 20f, SoundType.METAL); + public static final BlockDecorLadder METAL_RUNG_STEPS = new BlockDecorLadder("metal_rung_steps", 0, Material.IRON, 0.5f, 20f, SoundType.METAL); + public static final BlockDecorLadder TREATED_WOOD_LADDER = new BlockDecorLadder("treated_wood_ladder", 0, Material.WOOD, 0.5f, 10f, SoundType.WOOD); public static final BlockDecorGlassBlock PANZERGLASS_BLOCK = new BlockDecorGlassBlock("panzerglass_block", 0, Material.GLASS, 0.8f, 2000f, SoundType.GLASS); @@ -162,14 +162,15 @@ public class ModBlocks public static final BlockDecorFurnace SMALL_LAB_FURNACE = new BlockDecorFurnace( "small_lab_furnace", - BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT, + BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT| + BlockDecor.CFG_ELECTRICAL, Material.IRON, 0.35f, 15f, SoundType.METAL, ModAuxiliaries.getPixeledAABB(1,0,1, 15,15,16) ); public static final BlockDecorFurnaceElectrical SMALL_ELECTRICAL_FURNACE = new BlockDecorFurnaceElectrical( "small_electrical_furnace", - BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT, + BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_ELECTRICAL, Material.IRON, 0.35f, 15f, SoundType.METAL, ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16) ); @@ -243,7 +244,14 @@ public class ModBlocks public static final BlockDecorWasteIncinerator SMALL_WASTE_INCINERATOR = new BlockDecorWasteIncinerator( "small_waste_incinerator", - BlockDecor.CFG_DEFAULT, + BlockDecor.CFG_DEFAULT|BlockDecor.CFG_ELECTRICAL, + Material.IRON, 0.3f, 15f, SoundType.METAL, + ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16) + ); + + public static final BlockDecorDropper FACTORY_DROPPER = new BlockDecorDropper( + "factory_dropper", + BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_REDSTONE_CONTROLLED, Material.IRON, 0.3f, 15f, SoundType.METAL, ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16) ); @@ -277,6 +285,9 @@ public class ModBlocks private static final TileEntityRegistrationData WASTE_INCINERATOR_TEI = new TileEntityRegistrationData( BlockDecorWasteIncinerator.BTileEntity.class, "te_small_waste_incinerator" ); + private static final TileEntityRegistrationData FACTORY_DROPPER_TEI = new TileEntityRegistrationData( + BlockDecorDropper.BTileEntity.class, "te_factory_dropper" + ); //-------------------------------------------------------------------------------------------------------------------- //-- Registration list @@ -319,12 +330,13 @@ public class ModBlocks STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE, STRAIGHT_PIPE_VALVE_TEI, PASSIVE_FLUID_ACCUMULATOR, PASSIVE_FLUID_ACCUMULATOR_TEI, SMALL_ELECTRICAL_FURNACE, SMALL_ELECTRICAL_FURNACE_TEI, - SIGN_HOTWIRE, SIGN_DANGER + SIGN_HOTWIRE, SIGN_DANGER, + SMALL_WASTE_INCINERATOR, WASTE_INCINERATOR_TEI, }; private static final Object dev_content[] = { SIGN_MINDSTEP, - SMALL_WASTE_INCINERATOR, WASTE_INCINERATOR_TEI + FACTORY_DROPPER, FACTORY_DROPPER_TEI }; //-------------------------------------------------------------------------------------------------------------------- @@ -346,7 +358,7 @@ public class ModBlocks final boolean woor = ModConfig.isWithoutOptOutRegistration(); for(Object e:content) { if(e instanceof Block) { - if((!woor) || (!ModConfig.isOptedOut((Block)e))) { + if((!woor) || (!ModConfig.isOptedOut((Block)e)) || (e==SIGN_MODLOGO)) { registeredBlocks.add((Block) e); } else { ++num_block_registrations_skipped; 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 1e901f6..cb39c5c 100644 --- a/1.12/src/main/java/wile/engineersdecor/detail/ModConfig.java +++ b/1.12/src/main/java/wile/engineersdecor/detail/ModConfig.java @@ -118,11 +118,23 @@ public class ModConfig @Config.Comment({"Disable check valve, and redstone controlled valves."}) @Config.Name("Without valves") + @Config.RequiresMcRestart public boolean without_valves = false; @Config.Comment({"Disable the passive fluid accumulator."}) @Config.Name("Without fluid accumulator") + @Config.RequiresMcRestart public boolean without_passive_fluid_accumulator = false; + + @Config.Comment({"Disable item disposal/trash/void incinerator device."}) + @Config.Name("Without waste incinerator") + @Config.RequiresMcRestart + public boolean without_waste_incinerator = false; + + @Config.Comment({"Disable decorative sign plates (caution, hazards, etc)."}) + @Config.Name("Without signs") + @Config.RequiresMcRestart + public boolean without_sign_plates = false; } @Config.Comment({ @@ -292,9 +304,11 @@ public class ModConfig if(optout.without_lab_furnace && ((block instanceof BlockDecorFurnace)) && (!(block instanceof BlockDecorFurnaceElectrical))) return true; if(optout.without_electrical_furnace && (block instanceof BlockDecorFurnaceElectrical)) return true; if(optout.without_passive_fluid_accumulator && (block instanceof BlockDecorPassiveFluidAccumulator)) return true; + if(optout.without_waste_incinerator && (block instanceof BlockDecorWasteIncinerator)) return true; if(optout.without_windows && rn.endsWith("_window")) return true; if(optout.without_light_sources && rn.endsWith("_light")) return true; if(optout.without_ladders && (block instanceof BlockDecorLadder)) return true; + if(optout.without_sign_plates && rn.startsWith("sign_")) return true; if(optout.without_walls && rn.endsWith("_wall")) return true; if(optout.without_stairs && rn.endsWith("_stairs")) return true; if(optout.without_valves && rn.contains("_pipe_valve")) return true; diff --git a/1.12/src/main/resources/assets/engineersdecor/blockstates/factory_dropper.json b/1.12/src/main/resources/assets/engineersdecor/blockstates/factory_dropper.json new file mode 100644 index 0000000..e50b14c --- /dev/null +++ b/1.12/src/main/resources/assets/engineersdecor/blockstates/factory_dropper.json @@ -0,0 +1,12 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "engineersdecor:device/factory_dropper_model" + }, + "variants": { + "normal": [{}], + "inventory": [{}], + "facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":-90}, "down": {"x":90} }, + "open": { "true":{}, "false":{} } + } +} diff --git a/1.12/src/main/resources/assets/engineersdecor/lang/en_us.lang b/1.12/src/main/resources/assets/engineersdecor/lang/en_us.lang index c53861d..ac3dde1 100644 --- a/1.12/src/main/resources/assets/engineersdecor/lang/en_us.lang +++ b/1.12/src/main/resources/assets/engineersdecor/lang/en_us.lang @@ -121,6 +121,9 @@ tile.engineersdecor.passive_fluid_accumulator.name=Passive Fluid Accumulator tile.engineersdecor.passive_fluid_accumulator.help=§6Vacuum suction based fluid collector.§r Has one output, all other sides are input. \ Drains fluids from adjacent tanks when being drained from the output port by a pump. #----------------------------------------------------------------------------------------------------------- +tile.engineersdecor.factory_dropper.name=Factory Dropper +tile.engineersdecor.factory_dropper.help=§6Dropper suitable for advanced factory automation.§r +#----------------------------------------------------------------------------------------------------------- tile.engineersdecor.sign_decor.name=Sign Plate (Engineer's decor) tile.engineersdecor.sign_decor.help=§6This should not be craftable or visible in JEI. Used for creative tab and screenshots. tile.engineersdecor.sign_hotwire.name=Sign "Caution Hot Wire" diff --git a/1.12/src/main/resources/assets/engineersdecor/lang/ru_ru.lang b/1.12/src/main/resources/assets/engineersdecor/lang/ru_ru.lang index d22c576..31253b9 100644 --- a/1.12/src/main/resources/assets/engineersdecor/lang/ru_ru.lang +++ b/1.12/src/main/resources/assets/engineersdecor/lang/ru_ru.lang @@ -114,6 +114,9 @@ tile.engineersdecor.passive_fluid_accumulator.name=Passive fluid accumulator #tile.engineersdecor.passive_fluid_accumulator.help=§6Vacuum suction based fluid collector.§r Has one output, all other sides are input. \ Drains fluids from adjacent tanks when being drained from the output port by a pump. #----------------------------------------------------------------------------------------------------------- +tile.engineersdecor.factory_dropper.name=Factory dropper +#tile.engineersdecor.factory_dropper.help=§6Dropper suitable for advanced factory automation.§r +#----------------------------------------------------------------------------------------------------------- tile.engineersdecor.sign_decor.name=Sign plate (Engineer's decor logo) #tile.engineersdecor.sign_decor.help=§6This should not be craftable or visible in JEI. Used for creative tab and screenshots. tile.engineersdecor.sign_hotwire.name=Sign "Caution hot wire" diff --git a/1.12/src/main/resources/assets/engineersdecor/models/block/device/factory_dropper_model.json b/1.12/src/main/resources/assets/engineersdecor/models/block/device/factory_dropper_model.json new file mode 100644 index 0000000..d7eb12e --- /dev/null +++ b/1.12/src/main/resources/assets/engineersdecor/models/block/device/factory_dropper_model.json @@ -0,0 +1,83 @@ +{ + "parent": "block/cube", + "textures": { + "top": "engineersdecor:blocks/device/factory_dropper_top", + "bottom": "engineersdecor:blocks/device/factory_dropper_bottom", + "side": "engineersdecor:blocks/device/factory_dropper_side", + "particle": "engineersdecor:blocks/device/factory_dropper_side" + }, + "elements": [ + { + "from": [0, 0, 2], + "to": [16, 16, 16], + "faces": { + "north": {"texture": "#bottom"}, + "east": {"texture": "#side"}, + "south": {"texture": "#top"}, + "west": {"texture": "#side"}, + "up": {"texture": "#side"}, + "down": {"texture": "#side"} + } + }, + { + "from": [12, 0, 0], + "to": [16, 16, 2], + "faces": { + "north": {"texture": "#bottom"}, + "east": {"texture": "#side"}, + "south": {"texture": "#top"}, + "west": {"texture": "#side"}, + "up": {"texture": "#side"}, + "down": {"texture": "#side"} + } + }, + { + "from": [0, 0, 0], + "to": [4, 16, 2], + "faces": { + "north": {"texture": "#bottom"}, + "east": {"texture": "#side"}, + "south": {"texture": "#top"}, + "west": {"texture": "#side"}, + "up": {"texture": "#side"}, + "down": {"texture": "#side"} + } + }, + { + "from": [4, 12, 0], + "to": [12, 16, 2], + "faces": { + "north": {"texture": "#bottom"}, + "east": {"texture": "#side"}, + "south": {"texture": "#top"}, + "west": {"texture": "#side"}, + "up": {"texture": "#side"}, + "down": {"texture": "#side"} + } + }, + { + "from": [4, 0, 0], + "to": [12, 4, 2], + "faces": { + "north": {"texture": "#bottom"}, + "east": {"texture": "#side"}, + "south": {"texture": "#top"}, + "west": {"texture": "#side"}, + "up": {"texture": "#side"}, + "down": {"texture": "#side"} + } + } + ], + "display": { + "ground": { + "scale": [0.2, 0.2, 0.2] + }, + "gui": { + "rotation": [30, 225, 0], + "scale": [0.625, 0.625, 0.625] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/1.12/src/main/resources/assets/engineersdecor/recipes/_constants.json b/1.12/src/main/resources/assets/engineersdecor/recipes/_constants.json index b3294bb..17f17d3 100644 --- a/1.12/src/main/resources/assets/engineersdecor/recipes/_constants.json +++ b/1.12/src/main/resources/assets/engineersdecor/recipes/_constants.json @@ -225,6 +225,10 @@ "ingredient": { "item": "minecraft:furnace", "data": 0 }, "name": "itemFurnace" }, + { + "ingredient": { "item": "minecraft:dropper", "data": 0 }, + "name": "itemDropper" + }, { "ingredient": { "item": "minecraft:paper", "data": 0 }, "name": "paperAny" diff --git a/1.12/src/main/resources/assets/engineersdecor/recipes/factory_dropper_recipe.json b/1.12/src/main/resources/assets/engineersdecor/recipes/factory_dropper_recipe.json new file mode 100644 index 0000000..c298249 --- /dev/null +++ b/1.12/src/main/resources/assets/engineersdecor/recipes/factory_dropper_recipe.json @@ -0,0 +1,33 @@ +{ + "conditions": [ + { + "type": "engineersdecor:grc", + "result": "engineersdecor:factory_dropper", + "required": ["immersiveengineering:material"] + } + ], + "type": "minecraft:crafting_shaped", + "pattern": [ + "WWW", + "WDW", + "WPW" + ], + "key": { + "D": { + "item": "#itemDropper", + "data": 0 + }, + "P": { + "item": "#plateIron", + "data": 0 + }, + "W": { + "item": "#plankTreatedWood", + "data": 0 + } + }, + "result": { + "item": "engineersdecor:factory_dropper", + "count": 1 + } +} diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_bottom.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..f0122f55b13bd76852f8e62e7e51e0dd79187257 GIT binary patch literal 640 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 literal 0 HcmV?d00001 diff --git a/meta/update.json b/meta/update.json index d0ea261..5d109d3 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.6-b1": "[A] Added small waste incinerator (delayed fifo-buffered item disposal).\n[M] Fixed item/block name capitalization (by Voxelo).\n[M] Metal ladders are easier to break/harvest.", "1.0.5": "[R] Release based on v1.0.5-b1. Release-to-release changes: * Small electrical passthrough-furnace added. * Passive fluid accumulator added. * Config options added. * Sign plates added. * Minor bug fixes.\n[A] Added sign \"Electrical hazzard\"/\"Caution hot wire\".\n[A] Added sign \"Caution dangerous there\" (skull/bones).", "1.0.5-b1": "[A] Added passive fluid accumulator.\n[A] Added small electrical passthrough-furnace.\n[F] Fixed version check URL.\n[M] Opt-out config options for valves, passive fluid accumulator, and furni.", "1.0.4": "[R] Release based on v1.0.4-b9. Release-to-release changes: * Crafting table: Quick crafting history re-fab, JEI integration. * Rendering improvements and issue fixes (stairs, ambient occlusion, optifine, etc). * Walls with texture variations. * Thin/thick steel poles with support feet/heads. * Horizontal steel double-T support beams added. * Fluid pipe valves added: Check valve, redstone controlled valve, analog redstone controlled valve. Support pressurized transfer. * Tool tip documentation (CTRL-SHIFT) for stairs added. * Internal code cleanups. * Recipes tuned.\n[E] Added pass-through electrical furnace (experimental, see config).", @@ -45,7 +46,7 @@ }, "promos": { "1.12.2-recommended": "1.0.5", - "1.12.2-latest": "1.0.5", + "1.12.2-latest": "1.0.6-b1", "1.13.2-recommended": "", "1.13.2-latest": "1.0.4-b3" }