From dec60ad3e6ebd95b4b85954562a1980b2a4110cb Mon Sep 17 00:00:00 2001 From: Voxelo <41349408+Voxelo@users.noreply.github.com> Date: Mon, 13 May 2019 11:04:29 -0400 Subject: [PATCH 1/4] Update en_us.lang (#24) Fixed block/item name capitalization (Voxelo). --- .../assets/engineersdecor/lang/en_us.lang | 94 +++++++++---------- 1 file changed, 47 insertions(+), 47 deletions(-) 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 2f1e8b7..c53861d 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 @@ -5,129 +5,129 @@ # #----------------------------------------------------------------------------------------------------------- itemGroup.tabengineersdecor=Engineer's Decor -engineersdecor.config.title=Engineer's Decor config -engineersdecor.tooltip.hint.extended=§6[§9SHIFT§r More info§6]§r +engineersdecor.config.title=Engineer's Decor Config +engineersdecor.tooltip.hint.extended=§6[§9SHIFT§r More Info§6]§r engineersdecor.tooltip.hint.help=§6[§9CTRL-SHIFT§r Help§6]§r #----------------------------------------------------------------------------------------------------------- # Stone/"ceramic material" based blocks #----------------------------------------------------------------------------------------------------------- -tile.engineersdecor.clinker_brick_block.name=Clinker brick block +tile.engineersdecor.clinker_brick_block.name=Clinker Brick Block tile.engineersdecor.clinker_brick_block.help=§6A brick block with position dependent texture variations.§r\nLooks slightly darker and more color intensive than the vanilla brick block. -tile.engineersdecor.slag_brick_block.name=Slag brick block +tile.engineersdecor.slag_brick_block.name=Slag Brick Block tile.engineersdecor.slag_brick_block.help=§6A gray-brown brick block with position dependent texture variations. -tile.engineersdecor.rebar_concrete.name=Rebar concrete block +tile.engineersdecor.rebar_concrete.name=Rebar Concrete Block tile.engineersdecor.rebar_concrete.help=§6Steel reinforced concrete block.§r Expensive but Creeper-proof like obsidian. -tile.engineersdecor.panzerglass_block.name=Panzer glass block +tile.engineersdecor.panzerglass_block.name=Panzer Glass Block tile.engineersdecor.panzerglass_block.help=§6Reinforced glass block.§r Expensive, explosion-proof. Dark gray tint, faint structural lines visible, multi texture for seemless look. -tile.engineersdecor.rebar_concrete_tile.name=Rebar concrete tile +tile.engineersdecor.rebar_concrete_tile.name=Rebar Concrete Tile tile.engineersdecor.rebar_concrete_tile.help=§6Steel reinforced concrete tile.§r Expensive but Creeper-proof like obsidian. #----------------------------------------------------------------------------------------------------------- -tile.engineersdecor.rebar_concrete_wall.name=Rebar concrete wall +tile.engineersdecor.rebar_concrete_wall.name=Rebar Concrete Wall tile.engineersdecor.rebar_concrete_wall.help=§6Steel reinforced concrete wall.§r Expensive but Creeper-proof like obsidian. -tile.engineersdecor.concrete_wall.name=Concrete wall +tile.engineersdecor.concrete_wall.name=Concrete Wall tile.engineersdecor.concrete_wall.help=§6Wall made of solid concrete. -tile.engineersdecor.clinker_brick_wall.name=Clinker brick wall -tile.engineersdecor.clinker_brick_wall.help=§6Simplistic clinker brick wall. -tile.engineersdecor.slag_brick_wall.name=Slag brick wall -tile.engineersdecor.slag_brick_wall.help=§6Simplistic slag brick wall. +tile.engineersdecor.clinker_brick_wall.name=Clinker Brick Wall +tile.engineersdecor.clinker_brick_wall.help=§6Simplistic Clinker Brick Wall. +tile.engineersdecor.slag_brick_wall.name=Slag Brick Wall +tile.engineersdecor.slag_brick_wall.help=§6Simplistic Slag Brick Wall. #----------------------------------------------------------------------------------------------------------- -tile.engineersdecor.metal_rung_ladder.name=Metal rung ladder +tile.engineersdecor.metal_rung_ladder.name=Metal Rung Ladder tile.engineersdecor.metal_rung_ladder.help=§6Typical industrial wall ladder, consisting of horizontal metal rod rungs.§r Look up/down to climb faster. -tile.engineersdecor.metal_rung_steps.name=Staggered metal steps +tile.engineersdecor.metal_rung_steps.name=Staggered Metal Steps tile.engineersdecor.metal_rung_steps.help=§6Staggered rod rungs affixed to a wall, allowing to climb up, fall down, and so on.§r Look up/down to climb faster. -tile.engineersdecor.treated_wood_ladder.name=Treated wood ladder +tile.engineersdecor.treated_wood_ladder.name=Treated Wood Ladder tile.engineersdecor.treated_wood_ladder.help=§6Weather-proof wooden ladder.§r Look up/down to climb faster. #----------------------------------------------------------------------------------------------------------- -tile.engineersdecor.clinker_brick_stairs.name=Clinker brick stairs +tile.engineersdecor.clinker_brick_stairs.name=Clinker Brick Stairs tile.engineersdecor.clinker_brick_stairs.help=§6Looks slightly darker and more color intensive than the vanilla brick block. -tile.engineersdecor.slag_brick_stairs.name=Clinker brick stairs +tile.engineersdecor.slag_brick_stairs.name=Clinker Brick Stairs tile.engineersdecor.slag_brick_stairs.help=§6Looks slightly darker and more color intensive than the vanilla brick block. -tile.engineersdecor.rebar_concrete_stairs.name=Rebar concrete stairs +tile.engineersdecor.rebar_concrete_stairs.name=Rebar Concrete Stairs tile.engineersdecor.rebar_concrete_stairs.help=§6Steel reinforced concrete stairs.§r Expensive but Creeper-proof like obsidian. -tile.engineersdecor.rebar_concrete_tile_stairs.name=Rebar concrete tile stairs +tile.engineersdecor.rebar_concrete_tile_stairs.name=Rebar Concrete Tile Stairs tile.engineersdecor.rebar_concrete_tile_stairs.help=§6Steel reinforced concrete tile stairs.§r Expensive but Creeper-proof like obsidian. #----------------------------------------------------------------------------------------------------------- -tile.engineersdecor.treated_wood_pole.name=Straight treated wood pole +tile.engineersdecor.treated_wood_pole.name=Straight Treated Wood Pole tile.engineersdecor.treated_wood_pole.help=§6Straight pole fragment with a diameter of a wire relay.§r\n\ Can be useful as alternative to the wire posts if special special lengths are needed, \ or as support for structures. -tile.engineersdecor.treated_wood_pole_head.name=Straight treated wood pole head/foot +tile.engineersdecor.treated_wood_pole_head.name=Straight Treated Wood Pole Head/Foot tile.engineersdecor.treated_wood_pole_head.help=§6Wooden part fitting as foot or head of straight poles. -tile.engineersdecor.treated_wood_pole_support.name=Straight treated wood pole support +tile.engineersdecor.treated_wood_pole_support.name=Straight Treated Wood Pole Support tile.engineersdecor.treated_wood_pole_support.help=§6Heavy duty wooden support part fitting as foot or head of straight poles. -tile.engineersdecor.thick_steel_pole.name=Straight thick steel pole +tile.engineersdecor.thick_steel_pole.name=Straight Thick Steel Pole tile.engineersdecor.thick_steel_pole.help=§6Straight hollow pole fragment (6x6x16) for structural support purposes. -tile.engineersdecor.thin_steel_pole.name=Straight thin steel pole +tile.engineersdecor.thin_steel_pole.name=Straight Thin Steel Pole tile.engineersdecor.thin_steel_pole.help=§6Straight hollow pole fragment (4x4x16) for structural support purposes. -tile.engineersdecor.thin_steel_pole_head.name=Straight thin steel pole head/foot +tile.engineersdecor.thin_steel_pole_head.name=Straight Thin Steel Pole head/foot tile.engineersdecor.thin_steel_pole_head.help=§6Steel part fitting as foot or head of the thin steel pole (4x4x16). -tile.engineersdecor.thick_steel_pole_head.name=Straight thick steel pole head/foot +tile.engineersdecor.thick_steel_pole_head.name=Straight Thick Steel Pole Head/Foot tile.engineersdecor.thick_steel_pole_head.help=§6Steel part fitting as foot or head of the thick steel pole (6x6x16). -tile.engineersdecor.steel_double_t_support.name=Steel double T support +tile.engineersdecor.steel_double_t_support.name=Steel Double T Support tile.engineersdecor.steel_double_t_support.help=§6Horizontal ceiling support bream fragment. #----------------------------------------------------------------------------------------------------------- -tile.engineersdecor.treated_wood_table.name=Treated wood table +tile.engineersdecor.treated_wood_table.name=Treated Wood Table tile.engineersdecor.treated_wood_table.help=§6Robust four-legged wood table.§r Indoor and outdoor use. -tile.engineersdecor.treated_wood_stool.name=Treated wood stool -tile.engineersdecor.treated_wood_stool.help=§6Robust wood stool.§r Indoor and outdoor use. -tile.engineersdecor.treated_wood_crafting_table.name=Treated wood crafting table +tile.engineersdecor.treated_wood_stool.name=Treated Wood Stool +tile.engineersdecor.treated_wood_stool.help=§6Robust Wood Stool.§r Indoor and outdoor use. +tile.engineersdecor.treated_wood_crafting_table.name=Treated Wood Crafting Table tile.engineersdecor.treated_wood_crafting_table.help=§6Robust and weather-proof.§r Eight storage slots, keeps inventory, no vanilla recipe book.\n\ Click up/down arrow buttons for crafting history selection, output slot for item placement, X-button \ to clear crafting grid and history. Shift-click stack: player-to-storage stack transfer when crafting \ grid empty, otherwise player-to-grid stack transfer. Automatically distributes the clicked stack. -tile.engineersdecor.iron_inset_light.name=Inset light +tile.engineersdecor.iron_inset_light.name=Inset Light tile.engineersdecor.iron_inset_light.help=§6Small glowstone light source, sunk into the floor, ceiling or wall.§r\n\ Useful to light up places where electrical light installations are problematic.\ Light level like a torch. -tile.engineersdecor.treated_wood_window.name=Treated wood window +tile.engineersdecor.treated_wood_window.name=Treated Wood Window tile.engineersdecor.treated_wood_window.help=§6Wood framed tripple glazed window. Well insulating.§r Does not connect to adjacent blocks like glass panes. -tile.engineersdecor.treated_wood_windowsill.name=Treated wood window sill +tile.engineersdecor.treated_wood_windowsill.name=Treated Wood Window Sill tile.engineersdecor.treated_wood_windowsill.help=§6Simple window decoration. -tile.engineersdecor.steel_framed_window.name=Steel framed window +tile.engineersdecor.steel_framed_window.name=Steel Framed Window tile.engineersdecor.steel_framed_window.help=§6Steel framed tripple glazed window. Well insulating. §r Does not connect to adjacent blocks like glass panes. #----------------------------------------------------------------------------------------------------------- -tile.engineersdecor.small_lab_furnace.name=Small laboratory furnace +tile.engineersdecor.small_lab_furnace.name=Small Laboratory Furnace tile.engineersdecor.small_lab_furnace.help=§6Small metal cased lab kiln.§r Solid fuel consuming, updraught. \ Slightly hotter and better isolated than a cobblestone furnace, therefore more efficient. \ Two auxiliary slots e.g. for storage. Two stack internal hopper fifos for input, output, \ and fuel. Place an external heater into a aux slot and connect power for electrical \ smelting speed boost. -tile.engineersdecor.small_electrical_furnace.name=Small electrical furnace +tile.engineersdecor.small_electrical_furnace.name=Small Electrical Furnace tile.engineersdecor.small_electrical_furnace.help=§6Small metal cased pass-through furnace.§r \ Automatically draws items from the input side and puts items into the inventory at the output side. \ Items can be inserted or drawn from all sides using hoppers. Implicitly bypasses items that cannot be \ smelted or cooked to the output. Slightly more energy efficient and faster than a heated cobblestone \ furnace. Fifos and feeders transfer whole stacks. Feeders require a bit of power. -tile.engineersdecor.small_waste_incinerator.name=Small waste incinerator +tile.engineersdecor.small_waste_incinerator.name=Small Waste Incinerator tile.engineersdecor.small_waste_incinerator.help=§6Trash with internal fifo slots.§r Items can be inserted on all sides, and are kept until \ there is no space left in the fifo. After that the oldest stack will be incinerated. Apply \ electrical RF/FE power to increase the processing speed. Keeps its inventory when being \ relocated. #----------------------------------------------------------------------------------------------------------- -tile.engineersdecor.straight_pipe_valve.name=Fluid pipe check valve +tile.engineersdecor.straight_pipe_valve.name=Fluid Pipe Check Valve tile.engineersdecor.straight_pipe_valve.help=§6Straight fluid pipe fragment.§r Conducts fluids only in one direction. \ Does not connect to the sides. Reduces flow rate. Sneak to place in reverse direction. -tile.engineersdecor.straight_pipe_valve_redstone.name=Redstone controlled fluid valve +tile.engineersdecor.straight_pipe_valve_redstone.name=Redstone Controlled Fluid Valve tile.engineersdecor.straight_pipe_valve_redstone.help=§6Straight fluid pipe fragment.§r Conducts fluids only in one direction. \ Does not connect to the sides. Sneak to place in reverse direction. \ Blocks if not redstone powered. -tile.engineersdecor.straight_pipe_valve_redstone_analog.name=Redstone analog fluid valve +tile.engineersdecor.straight_pipe_valve_redstone_analog.name=Redstone Analog Fluid Valve tile.engineersdecor.straight_pipe_valve_redstone_analog.help=§6Straight fluid pipe fragment.§r Conducts fluids only in one direction. \ Does not connect to the sides. Sneak to place in reverse direction. \ Blocks if not redstone powered, reduces the flow rate linear from power 1 to 14, \ opens to maximum possible valve flow rate for power 15. -tile.engineersdecor.passive_fluid_accumulator.name=Passive fluid accumulator +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.sign_decor.name=Sign plate (Engineer's decor) +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" +tile.engineersdecor.sign_hotwire.name=Sign "Caution Hot Wire" tile.engineersdecor.sign_hotwire.help=§6Placable on walls (horizontally). -tile.engineersdecor.sign_mindstep.name=Sign "Mind the step" +tile.engineersdecor.sign_mindstep.name=Sign "Mind The Step" tile.engineersdecor.sign_mindstep.help=§6Placable on walls (horizontally). -tile.engineersdecor.sign_danger.name=Sign "Caution really dangerous there" +tile.engineersdecor.sign_danger.name=Sign "Caution Really dangerous there" tile.engineersdecor.sign_danger.help=§6Placable on walls (horizontally). #----------------------------------------------------------------------------------------------------------- From 5b1a6e0877f8529ab87ce40ef5ea2a40b0fddf87 Mon Sep 17 00:00:00 2001 From: stfwi Date: Sun, 19 May 2019 08:18:37 +0200 Subject: [PATCH 2/4] 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" } From dcf8a27d824f4ae0b6f5c23fb2efcc7af6777f51 Mon Sep 17 00:00:00 2001 From: stfwi Date: Sun, 19 May 2019 09:38:25 +0200 Subject: [PATCH 3/4] Using dedicated item handler instances to circumvent FML mapping issues of getStackInSlot(). --- 1.12/meta/update.json | 2 +- 1.12/readme.md | 1 + .../blocks/BlockDecorDropper.java | 154 ++++++++------- .../blocks/BlockDecorFurnace.java | 13 +- .../blocks/BlockDecorFurnaceElectrical.java | 182 +++++++++--------- .../blocks/BlockDecorWasteIncinerator.java | 141 ++++++++------ meta/update.json | 2 +- 7 files changed, 267 insertions(+), 228 deletions(-) diff --git a/1.12/meta/update.json b/1.12/meta/update.json index 08f95ca..cf16405 100644 --- a/1.12/meta/update.json +++ b/1.12/meta/update.json @@ -1,7 +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.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.\n[F] Fixed FML remapping issue by using dedicated IItemHandler instances.", "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).", diff --git a/1.12/readme.md b/1.12/readme.md index 79b7ccb..b81e42f 100644 --- a/1.12/readme.md +++ b/1.12/readme.md @@ -13,6 +13,7 @@ Mod sources for Minecraft version 1.12.2. - 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. + [F] Fixed FML remapping issue by using dedicated IItemHandler instances. ------------------------------------------------------------------- - v1.0.5 [R] Release based on v1.0.5-b1. Release-to-release changes: diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java index 853879a..e7dc2b2 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java @@ -391,7 +391,7 @@ public class BlockDecorDropper extends BlockDecorDirected // Tile entity //-------------------------------------------------------------------------------------------------------------------- - public static class BTileEntity extends TileEntity implements ITickable, ISidedInventory, IItemHandler, Networking.IPacketReceiver + public static class BTileEntity extends TileEntity implements ITickable, ISidedInventory, Networking.IPacketReceiver { public static final int TICK_INTERVAL = 32; public static final int NUM_OF_SLOTS = 15; @@ -666,80 +666,95 @@ public class BlockDecorDropper extends BlockDecorDirected // IItemHandler -------------------------------------------------------------------------------- - @Override - public int getSlots() - { return SIDED_INV_SLOTS.length; } - - @Override - public int getSlotLimit(int index) - { return getInventoryStackLimit(); } - - @Override - public boolean isItemValid(int slot, @Nonnull ItemStack stack) - { return is_input_slot(slot); } - - @Override - @Nonnull - public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate) + protected static class BItemHandler implements IItemHandler { - if((stack.isEmpty()) || (!is_input_slot(index))) return ItemStack.EMPTY; - int slotno = 0; - ItemStack slotstack = getStackInSlot(slotno); - if(!slotstack.isEmpty()) + private BTileEntity te; + + BItemHandler(BTileEntity te) + { this.te = te; } + + @Override + public int getSlots() + { return SIDED_INV_SLOTS.length; } + + @Override + public int getSlotLimit(int index) + { return te.getInventoryStackLimit(); } + + @Override + public boolean isItemValid(int slot, @Nonnull ItemStack stack) + { return te.is_input_slot(slot); } + + @Override + @Nonnull + public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate) { - if(slotstack.getCount() >= 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; + if((stack.isEmpty()) || (!te.is_input_slot(index))) return ItemStack.EMPTY; + int slotno = 0; + ItemStack slotstack = getStackInSlot(slotno); + if(!slotstack.isEmpty()) + { + if(slotstack.getCount() >= Math.min(slotstack.getMaxStackSize(), getSlotLimit(index))) return stack; + if(!ItemHandlerHelper.canItemStacksStack(stack, slotstack)) return stack; + if(!te.canInsertItem(slotno, stack, EnumFacing.UP) || (!te.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()); + te.setInventorySlotContents(slotno, copy); + } + return ItemStack.EMPTY; } 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; + stack = stack.copy(); + if(!simulate) { + ItemStack copy = stack.splitStack(n); + copy.grow(slotstack.getCount()); + te.setInventorySlotContents(slotno, copy); + return stack; + } else { + stack.shrink(n); + return stack; + } } } else { - if(!simulate) setInventorySlotContents(slotno, stack); - return ItemStack.EMPTY; + if(!te.canInsertItem(slotno, stack, EnumFacing.UP) || (!te.isItemValidForSlot(slotno, stack))) return stack; + int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index)); + if(n < stack.getCount()) { + stack = stack.copy(); + if(!simulate) { + te.setInventorySlotContents(slotno, stack.splitStack(n)); + return stack; + } else { + stack.shrink(n); + return stack; + } + } else { + if(!simulate) te.setInventorySlotContents(slotno, stack); + return ItemStack.EMPTY; + } } } + + @Override + @Nonnull + public ItemStack extractItem(int index, int amount, boolean simulate) + { + if((amount <= 0) || (!te.is_input_slot(index))) return ItemStack.EMPTY; + ItemStack stack = te.stacks_.get(index).copy(); + if(stack.getCount() > amount) stack.setCount(amount); + if(simulate) return stack; + te.stacks_.get(index).shrink(stack.getCount()); + return stack; + } + + @Override + @Nonnull + public ItemStack getStackInSlot(int index) + { return te.getStackInSlot(index); } } - @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; - } + BItemHandler item_handler_ = new BItemHandler(this); // Capability export ---------------------------------------------------------------------------- @@ -752,11 +767,8 @@ public class BlockDecorDropper extends BlockDecorDirected @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); - } + if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T)item_handler_; + return super.getCapability(capability, facing); } // IPacketReceiver ------------------------------------------------------------------------------- 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 8575b28..ff66b3d 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnace.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnace.java @@ -452,12 +452,6 @@ public class BlockDecorFurnace extends BlockDecorDirected public static final int AUX_0_SLOT_NO = 9; public static final int AUX_1_SLOT_NO =10; - private static final int[] SLOTS_TOP = new int[] {FIFO_INPUT_1_SLOT_NO}; - private static final int[] SLOTS_BOTTOM = new int[] {FIFO_OUTPUT_1_SLOT_NO}; - private static final int[] SLOTS_SIDES = new int[] {FIFO_FUEL_1_SLOT_NO}; - private final IItemHandler sided_itemhandler_top_ = new SidedInvWrapper(this, EnumFacing.UP); - private final IItemHandler sided_itemhandler_down_ = new SidedInvWrapper(this, EnumFacing.DOWN); - private final IItemHandler sided_itemhandler_sides_ = new SidedInvWrapper(this, EnumFacing.WEST); private static double proc_fuel_efficiency_ = 1.0; private static int proc_speed_interval_ = DEFAULT_SPEED_INTERVAL; private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY * TICK_INTERVAL; @@ -725,6 +719,13 @@ public class BlockDecorFurnace extends BlockDecorDirected // ISidedInventory ---------------------------------------------------------------------------- + private static final int[] SLOTS_TOP = new int[] {FIFO_INPUT_1_SLOT_NO}; + private static final int[] SLOTS_BOTTOM = new int[] {FIFO_OUTPUT_1_SLOT_NO}; + private static final int[] SLOTS_SIDES = new int[] {FIFO_FUEL_1_SLOT_NO}; + private final IItemHandler sided_itemhandler_top_ = new SidedInvWrapper(this, EnumFacing.UP); + private final IItemHandler sided_itemhandler_down_ = new SidedInvWrapper(this, EnumFacing.DOWN); + private final IItemHandler sided_itemhandler_sides_ = new SidedInvWrapper(this, EnumFacing.WEST); + @Override public int[] getSlotsForFace(EnumFacing side) { 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 894ff3f..7cec5c3 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnaceElectrical.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorFurnaceElectrical.java @@ -273,7 +273,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace // Tile entity //-------------------------------------------------------------------------------------------------------------------- - public static class BTileEntity extends BlockDecorFurnace.BTileEntity implements ITickable, ISidedInventory, IEnergyStorage, IItemHandler + public static class BTileEntity extends BlockDecorFurnace.BTileEntity implements ITickable, ISidedInventory, IEnergyStorage { public static final int TICK_INTERVAL = 4; public static final int FIFO_INTERVAL = 20; @@ -429,6 +429,10 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace return changed; } + @Override + public ItemStack getStackInSlot(int index) + { return ((index < 0) || (index >= SIDED_INV_SLOTS.length)) ? ItemStack.EMPTY : stacks_.get(SIDED_INV_SLOTS[index]); } + // ISidedInventory ---------------------------------------------------------------------------- private static final int[] SIDED_INV_SLOTS = new int[] { @@ -482,96 +486,104 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace // IItemHandler -------------------------------------------------------------------------------- - @Override - public int getSlots() - { return SIDED_INV_SLOTS.length; } - - @Override - @Nonnull - public ItemStack getStackInSlot(int index) - { return ((index < 0) || (index >= SIDED_INV_SLOTS.length)) ? ItemStack.EMPTY : stacks_.get(SIDED_INV_SLOTS[index]); } - - @Override - public int getSlotLimit(int index) - { return getInventoryStackLimit(); } - - @Override - public boolean isItemValid(int slot, @Nonnull ItemStack stack) - { return true; } - - @Override - @Nonnull - public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate) + protected static class BItemHandler implements IItemHandler { - if(stack.isEmpty()) return ItemStack.EMPTY; - if((index < 0) || (index >= SIDED_INV_SLOTS.length)) return ItemStack.EMPTY; - int slotno = SIDED_INV_SLOTS[index]; - ItemStack slotstack = getStackInSlot(slotno); - if(!slotstack.isEmpty()) + private BTileEntity te; + + BItemHandler(BTileEntity te) + { this.te = te; } + + @Override + public int getSlots() + { return SIDED_INV_SLOTS.length; } + + @Override + @Nonnull + public ItemStack getStackInSlot(int index) + { return te.getStackInSlot(index); } + + @Override + public int getSlotLimit(int index) + { return te.getInventoryStackLimit(); } + + @Override + public boolean isItemValid(int slot, @Nonnull ItemStack stack) + { return true; } + + @Override + @Nonnull + public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate) { - if(slotstack.getCount() >= 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; + if(stack.isEmpty()) return ItemStack.EMPTY; + if((index < 0) || (index >= SIDED_INV_SLOTS.length)) return ItemStack.EMPTY; + int slotno = SIDED_INV_SLOTS[index]; + ItemStack slotstack = getStackInSlot(slotno); + if(!slotstack.isEmpty()) { + if(slotstack.getCount() >= Math.min(slotstack.getMaxStackSize(), getSlotLimit(index))) return stack; + if(!ItemHandlerHelper.canItemStacksStack(stack, slotstack)) return stack; + if(!te.canInsertItem(slotno, stack, EnumFacing.UP) || (!te.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()); + te.setInventorySlotContents(slotno, copy); + } + return ItemStack.EMPTY; } else { - stack.shrink(n); - return stack; + stack = stack.copy(); + if(!simulate) { + ItemStack copy = stack.splitStack(n); + copy.grow(slotstack.getCount()); + te.setInventorySlotContents(slotno, copy); + return stack; + } else { + stack.shrink(n); + return stack; + } + } + } else { + if(!te.canInsertItem(slotno, stack, EnumFacing.UP) || (!te.isItemValidForSlot(slotno, stack))) return stack; + int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index)); + if(n < stack.getCount()) { + stack = stack.copy(); + if(!simulate) { + te.setInventorySlotContents(slotno, stack.splitStack(n)); + return stack; + } else { + stack.shrink(n); + return stack; + } + } else { + if(!simulate) te.setInventorySlotContents(slotno, stack); + return ItemStack.EMPTY; } } - } 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; - } + } + + @Override + @Nonnull + public ItemStack extractItem(int index, int amount, boolean simulate) { + if(amount == 0) return ItemStack.EMPTY; + if((index < 0) || (index >= SIDED_INV_SLOTS.length)) return ItemStack.EMPTY; + int slotno = SIDED_INV_SLOTS[index]; + ItemStack stackInSlot = getStackInSlot(slotno); + if(stackInSlot.isEmpty()) return ItemStack.EMPTY; + if(!te.canExtractItem(slotno, stackInSlot, EnumFacing.DOWN)) return ItemStack.EMPTY; + if(simulate) { + if(stackInSlot.getCount() < amount) return stackInSlot.copy(); + ItemStack ostack = stackInSlot.copy(); + ostack.setCount(amount); + return ostack; } else { - if(!simulate) setInventorySlotContents(slotno, stack); - return ItemStack.EMPTY; + ItemStack ostack = te.decrStackSize(slotno, Math.min(stackInSlot.getCount(), amount)); + te.markDirty(); + return ostack; } } } - @Override - @Nonnull - public ItemStack extractItem(int index, int amount, boolean simulate) - { - if(amount == 0) return ItemStack.EMPTY; - if((index < 0) || (index >= SIDED_INV_SLOTS.length)) return ItemStack.EMPTY; - int slotno = SIDED_INV_SLOTS[index]; - ItemStack stackInSlot = getStackInSlot(slotno); - if(stackInSlot.isEmpty()) return ItemStack.EMPTY; - if(!canExtractItem(slotno, stackInSlot, EnumFacing.DOWN)) return ItemStack.EMPTY; - if(simulate) { - if(stackInSlot.getCount() < amount) return stackInSlot.copy(); - ItemStack ostack = stackInSlot.copy(); - ostack.setCount(amount); - return ostack; - } else { - ItemStack ostack = decrStackSize(slotno, Math.min(stackInSlot.getCount(), amount)); - markDirty(); - return ostack; - } - } + protected BItemHandler item_handler_ = new BItemHandler(this); // Capability export ---------------------------------------------------------------------------- @@ -584,11 +596,9 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace @Nullable public T getCapability(Capability capability, @Nullable EnumFacing facing) { - if((capability == CapabilityEnergy.ENERGY) || (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)) { - return ((T)this); - } else { - return super.getCapability(capability, facing); - } + if(capability == CapabilityEnergy.ENERGY) return ((T)this); + if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T)item_handler_; + return super.getCapability(capability, facing); } // ITickable ------------------------------------------------------------------------------------ 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 df92fb8..31dacff 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWasteIncinerator.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorWasteIncinerator.java @@ -303,7 +303,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor // Tile entity //-------------------------------------------------------------------------------------------------------------------- - public static class BTileEntity extends TileEntity implements ITickable, ISidedInventory, IEnergyStorage, IItemHandler + public static class BTileEntity extends TileEntity implements ITickable, ISidedInventory, IEnergyStorage { public static final int TICK_INTERVAL = 20; public static final int ENERGIZED_TICK_INTERVAL = 5; @@ -449,8 +449,8 @@ public class BlockDecorWasteIncinerator extends BlockDecor @Override public void setInventorySlotContents(int index, ItemStack stack) { - stacks_.set(index, stack); if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit()); + stacks_.set(index, stack); markDirty(); } @@ -476,7 +476,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor @Override public boolean isItemValidForSlot(int index, ItemStack stack) - { return index==0; } + { return (index==0); } @Override public int getField(int id) @@ -544,74 +544,89 @@ public class BlockDecorWasteIncinerator extends BlockDecor // IItemHandler -------------------------------------------------------------------------------- - @Override - public int getSlots() - { return 1; } - - @Override - public int getSlotLimit(int index) - { return getInventoryStackLimit(); } - - @Override - public boolean isItemValid(int slot, @Nonnull ItemStack stack) - { return true; } - - @Override - @Nonnull - public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate) + protected static class BItemHandler implements IItemHandler { - if(stack.isEmpty()) return ItemStack.EMPTY; - if(index != 0) return ItemStack.EMPTY; - int slotno = 0; - ItemStack slotstack = getStackInSlot(slotno); - if(!slotstack.isEmpty()) + private BTileEntity te; + + BItemHandler(BTileEntity te) + { this.te = te; } + + @Override + public int getSlots() + { return 1; } + + @Override + public int getSlotLimit(int index) + { return te.getInventoryStackLimit(); } + + @Override + public boolean isItemValid(int slot, @Nonnull ItemStack stack) + { return true; } + + @Override + @Nonnull + public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate) { - if(slotstack.getCount() >= 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; + if(stack.isEmpty()) return ItemStack.EMPTY; + if(index != 0) return ItemStack.EMPTY; + int slotno = 0; + ItemStack slotstack = getStackInSlot(slotno); + if(!slotstack.isEmpty()) + { + if(slotstack.getCount() >= Math.min(slotstack.getMaxStackSize(), getSlotLimit(index))) return stack; + if(!ItemHandlerHelper.canItemStacksStack(stack, slotstack)) return stack; + if(!te.canInsertItem(slotno, stack, EnumFacing.UP) || (!te.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()); + te.setInventorySlotContents(slotno, copy); + } + return ItemStack.EMPTY; } 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; + stack = stack.copy(); + if(!simulate) { + ItemStack copy = stack.splitStack(n); + copy.grow(slotstack.getCount()); + te.setInventorySlotContents(slotno, copy); + return stack; + } else { + stack.shrink(n); + return stack; + } } } else { - if(!simulate) setInventorySlotContents(slotno, stack); - return ItemStack.EMPTY; + if(!te.canInsertItem(slotno, stack, EnumFacing.UP) || (!te.isItemValidForSlot(slotno, stack))) return stack; + int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index)); + if(n < stack.getCount()) { + stack = stack.copy(); + if(!simulate) { + te.setInventorySlotContents(slotno, stack.splitStack(n)); + return stack; + } else { + stack.shrink(n); + return stack; + } + } else { + if(!simulate) te.setInventorySlotContents(slotno, stack); + return ItemStack.EMPTY; + } } } + + @Override + @Nonnull + public ItemStack extractItem(int index, int amount, boolean simulate) + { return ItemStack.EMPTY; } + + @Override + @Nonnull + public ItemStack getStackInSlot(int index) + { return te.getStackInSlot(index); } } - @Override - @Nonnull - public ItemStack extractItem(int index, int amount, boolean simulate) - { return ItemStack.EMPTY; } + private BItemHandler item_handler_ = new BItemHandler(this); // Capability export ---------------------------------------------------------------------------- @@ -625,7 +640,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor public T getCapability(Capability capability, @Nullable EnumFacing facing) { if((facing != null) && (capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)) { - return (T)this; + return (T)item_handler_; } else if(capability == CapabilityEnergy.ENERGY) { return (T)this; } else { diff --git a/meta/update.json b/meta/update.json index 5d109d3..ee2d14b 100644 --- a/meta/update.json +++ b/meta/update.json @@ -1,7 +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.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.\n[F] Fixed FML remapping issue by using dedicated IItemHandler instances.", "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).", From c05ae7249164f90c1ba7138ddfcc8610a76cbcde Mon Sep 17 00:00:00 2001 From: stfwi Date: Tue, 21 May 2019 20:02:51 +0200 Subject: [PATCH 4/4] Release version for hotfixing issue #25. --- 1.12/gradle.properties | 2 +- 1.12/meta/update.json | 5 +- 1.12/readme.md | 10 + .../blocks/BlockDecorDropper.java | 450 +++++++++--------- .../wile/engineersdecor/blocks/ModBlocks.java | 2 +- .../blockstates/factory_dropper.json | 2 +- .../block/device/factory_dropper_model.json | 103 ++-- .../device/factory_dropper_model_open.json | 108 +++++ .../blocks/device/factory_dropper_bottom.png | Bin 640 -> 535 bytes .../blocks/device/factory_dropper_shutter.png | Bin 0 -> 410 bytes .../blocks/device/factory_dropper_side.png | Bin 555 -> 622 bytes .../blocks/device/factory_dropper_top.png | Bin 572 -> 527 bytes .../textures/gui/factory_dropper_gui.png | Bin 19739 -> 20850 bytes meta/update.json | 5 +- 14 files changed, 414 insertions(+), 273 deletions(-) create mode 100644 1.12/src/main/resources/assets/engineersdecor/models/block/device/factory_dropper_model_open.json create mode 100644 1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_shutter.png diff --git a/1.12/gradle.properties b/1.12/gradle.properties index ae024fa..0128884 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.6-b1 +version_engineersdecor=1.0.6 diff --git a/1.12/meta/update.json b/1.12/meta/update.json index cf16405..9786b11 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": "[R] Release based on v1.0.6-b1. Release-to-release changes: * Fixed FML remapping issue (COULD CAUSE CRASHES). * Small waste incinerator added. * Lang files updated/corrections. * Metal ladder easier to break.\n[A] Added factory dropper (config:experimental).\n[C] Thx to abdurraslan for the detailed issue #25.", "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.\n[F] Fixed FML remapping issue by using dedicated IItemHandler instances.", "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.", @@ -36,7 +37,7 @@ "1.0.0-b1": "[A] Initial structure.\n[A] Added clinker bricks and clinker brick stairs.\n[A] Added slag bricks and slag brick stairs.\n[A] Added metal rung ladder.\n[A] Added staggered metal steps ladder.\n[A] Added treated wood ladder.\n[A] Added treated wood pole.\n[A] Added treated wood table." }, "promos": { - "1.12.2-recommended": "1.0.5", - "1.12.2-latest": "1.0.6-b1" + "1.12.2-recommended": "1.0.6", + "1.12.2-latest": "1.0.6" } } \ No newline at end of file diff --git a/1.12/readme.md b/1.12/readme.md index b81e42f..b9ed8e2 100644 --- a/1.12/readme.md +++ b/1.12/readme.md @@ -10,6 +10,16 @@ Mod sources for Minecraft version 1.12.2. ---- ## Revision history + ------------------------------------------------------------------- + - v1.0.6 [R] Release based on v1.0.6-b1. Release-to-release changes: + * Fixed FML remapping issue (COULD CAUSE CRASHES). + * Small waste incinerator added. + * Lang files updated/corrections. + * Metal ladder easier to break. + ------------------------------------------------------------------- + [A] Added factory dropper (config:experimental). + [C] Thx to abdurraslan for the detailed issue #25. + - 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. diff --git a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java index e7dc2b2..6d6142b 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/BlockDecorDropper.java @@ -8,7 +8,9 @@ */ package wile.engineersdecor.blocks; +import net.minecraftforge.items.wrapper.SidedInvWrapper; import wile.engineersdecor.ModEngineersDecor; +import wile.engineersdecor.detail.Networking; import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.Block; @@ -26,6 +28,7 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.item.*; import net.minecraft.inventory.*; +import net.minecraft.init.SoundEvents; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.util.*; @@ -38,14 +41,13 @@ 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; +import java.util.Arrays; public class BlockDecorDropper extends BlockDecorDirected { @@ -192,16 +194,18 @@ public class BlockDecorDropper extends BlockDecorDirected 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)) { + if(!isPointInRegion(114, 1, 61, 79, mouseX, mouseY)) { + return; + } else 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; + int xdev = MathHelper.clamp( (int)Math.round(((double)((mx-157) * 100)) / 12), -100, 100); + int ydev = MathHelper.clamp(-(int)Math.round(((double)((my- 22) * 100)) / 12), -100, 100); + if(Math.abs(xdev) < 9) xdev = 0; + if(Math.abs(ydev) < 9) ydev = 0; NBTTagCompound nbt = new NBTTagCompound(); nbt.setInteger("drop_xdev", xdev); nbt.setInteger("drop_ydev", ydev); @@ -209,22 +213,44 @@ public class BlockDecorDropper extends BlockDecorDirected } 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 if(ndrop >= 34) { ndrop = container.fields_[4] + 1; // + } else { - ndrop = MathHelper.clamp(1+ndrop, 1, 32); // slider + ndrop = MathHelper.clamp(1+ndrop, 1, BTileEntity.MAX_DROP_COUNT); // 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) - ) { + } else if(isPointInRegion(129, 50, 44, 10, mouseX, mouseY)) { + int period = (mx-135); + if(period < -1) { + period = container.fields_[6] - 1; // - + } else if(period >= 34) { + period = container.fields_[6] + 1; // + + } else { + period = (int)(0.5 + ((100.0 * period)/34)); + } + period = MathHelper.clamp(period, 0, 100); + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("drop_period", period); + Networking.PacketTileNotify.sendToServer(te, nbt); + } else if(isPointInRegion(114, 51, 9, 9, mouseX, mouseY)) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("manual_rstrigger", 1); + Networking.PacketTileNotify.sendToServer(te, nbt); + } else if(isPointInRegion(162, 66, 7, 9, mouseX, mouseY)) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setInteger("manual_trigger", 1); Networking.PacketTileNotify.sendToServer(te, nbt); + } else if(isPointInRegion(132, 66, 9, 9, mouseX, mouseY)) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("drop_logic", container.fields_[5] ^ BTileEntity.DROPLOGIC_FILTER_ANDGATE); + Networking.PacketTileNotify.sendToServer(te, nbt); + } else if(isPointInRegion(148, 66, 9, 9, mouseX, mouseY)) { + NBTTagCompound nbt = new NBTTagCompound(); + nbt.setInteger("drop_logic", container.fields_[5] ^ BTileEntity.DROPLOGIC_EXTERN_ANDGATE); + Networking.PacketTileNotify.sendToServer(te, nbt); } } @@ -269,7 +295,14 @@ public class BlockDecorDropper extends BlockDecorDirected // drop count { int x = x0 + 134 - 2 + (container.fields_[4]); - int y = y0 + 44; + int y = y0 + 45; + drawTexturedModalRect(x, y, 190, 31, 5, 5); + } + // drop period + { + int px = ((container.fields_[6] * 34) / 100); + int x = x0 + 134 - 2 + MathHelper.clamp(px, 0, 33); + int y = y0 + 56; drawTexturedModalRect(x, y, 190, 31, 5, 5); } // redstone input @@ -278,6 +311,19 @@ public class BlockDecorDropper extends BlockDecorDirected drawTexturedModalRect(x0+114, y0+51, 189, 18, 9, 9); } } + // trigger logic + { + int filter_gate_offset = ((container.fields_[5] & BTileEntity.DROPLOGIC_FILTER_ANDGATE) != 0) ? 11 : 0; + int extern_gate_offset = ((container.fields_[5] & BTileEntity.DROPLOGIC_EXTERN_ANDGATE) != 0) ? 11 : 0; + drawTexturedModalRect(x0+132, y0+66, 179+filter_gate_offset, 66, 9, 9); + drawTexturedModalRect(x0+148, y0+66, 179+extern_gate_offset, 66, 9, 9); + } + // drop timer running indicator + { + if((container.fields_[9] > BTileEntity.DROP_PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) { + drawTexturedModalRect(x0+149, y0+51, 201, 39, 3, 3); + } + } } } @@ -399,19 +445,30 @@ public class BlockDecorDropper extends BlockDecorDirected 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; + public static final int SHUTTER_CLOSE_DELAY = 40; + public static final int MAX_DROP_COUNT = 32; + public static final int DROP_PERIOD_OFFSET = 10; + /// + public static final int DROPLOGIC_FILTER_ANDGATE = 0x1; + public static final int DROPLOGIC_EXTERN_ANDGATE = 0x2; + public static final int DROPLOGIC_SILENT_DROP = 0x4; + public static final int DROPLOGIC_SILENT_OPEN = 0x8; + /// private int filter_matches_[] = new int[CTRL_SLOTS_SIZE]; - private boolean active_ = false; + private int open_timer_ = 0; + private int drop_timer_ = 0; + private boolean triggered_ = 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_count_ = 1; + private int drop_logic_ = 0; + private int drop_period_ = 20; private int drop_slot_index_ = 0; - private int drop_count_ = 0; - + private int tick_timer_ = 0; protected NonNullList stacks_; public static void on_config(int cooldown_ticks) @@ -427,7 +484,9 @@ public class BlockDecorDropper extends BlockDecorDirected stacks_ = NonNullList.withSize(NUM_OF_SLOTS, ItemStack.EMPTY); block_power_signal_ = false; block_power_updated_ = false; - drop_count_ = 0; + drop_count_ = 1; + drop_period_ = 20; + drop_logic_ = DROPLOGIC_EXTERN_ANDGATE; 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"); + open_timer_ = nbt.getInteger("open_timer"); 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"); + drop_count_ = MathHelper.clamp(nbt.getInteger("drop_count"), 1, MAX_DROP_COUNT); + drop_logic_ = nbt.getInteger("drop_logic"); + drop_period_ = nbt.getInteger("drop_period"); } protected void writenbt(NBTTagCompound nbt, boolean update_packet) { ItemStackHelper.saveAllItems(nbt, stacks_); - nbt.setBoolean("active", active_); nbt.setBoolean("powered", block_power_signal_); + nbt.setInteger("open_timer", open_timer_); 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; + nbt.setInteger("drop_logic", drop_logic_); + nbt.setInteger("drop_period", drop_period_); } public void block_updated() @@ -570,7 +589,7 @@ public class BlockDecorDropper extends BlockDecorDirected { stacks_.set(index, stack); if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit()); - tick_timer_ = 2; + if(tick_timer_ > 8) tick_timer_ = 8; markDirty(); } @@ -607,7 +626,10 @@ public class BlockDecorDropper extends BlockDecorDirected case 2: return drop_ydev_; case 3: return drop_noise_; case 4: return drop_count_; - case 10: return active_ ? 1 : 0; + case 5: return drop_logic_; + case 6: return drop_period_; + case 9: return drop_timer_; + case 10: return open_timer_; case 11: return block_power_signal_ ? 1 : 0; case 12: return filter_matches_[0]; case 13: return filter_matches_[1]; @@ -621,12 +643,15 @@ public class BlockDecorDropper extends BlockDecorDirected 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 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, MAX_DROP_COUNT); return; + case 5: drop_logic_ = value; return; + case 6: drop_period_ = MathHelper.clamp(value, 0, 100); return; + case 9: drop_timer_ = MathHelper.clamp(value, 0, 400); return; + case 10: open_timer_ = MathHelper.clamp(value, 0, 400); 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; @@ -646,10 +671,11 @@ public class BlockDecorDropper extends BlockDecorDirected // ISidedInventory ---------------------------------------------------------------------------- + private final IItemHandler item_handler_ = new SidedInvWrapper(this, EnumFacing.UP); 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(!te.canInsertItem(slotno, stack, EnumFacing.UP) || (!te.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()); - te.setInventorySlotContents(slotno, copy); - } - return ItemStack.EMPTY; - } else { - stack = stack.copy(); - if(!simulate) { - ItemStack copy = stack.splitStack(n); - copy.grow(slotstack.getCount()); - te.setInventorySlotContents(slotno, copy); - return stack; - } else { - stack.shrink(n); - return stack; - } - } - } else { - if(!te.canInsertItem(slotno, stack, EnumFacing.UP) || (!te.isItemValidForSlot(slotno, stack))) return stack; - int n = Math.min(stack.getMaxStackSize(), getSlotLimit(index)); - if(n < stack.getCount()) { - stack = stack.copy(); - if(!simulate) { - te.setInventorySlotContents(slotno, stack.splitStack(n)); - return stack; - } else { - stack.shrink(n); - return stack; - } - } else { - if(!simulate) te.setInventorySlotContents(slotno, stack); - return ItemStack.EMPTY; - } - } - } - - @Override - @Nonnull - public ItemStack extractItem(int index, int amount, boolean simulate) - { - if((amount <= 0) || (!te.is_input_slot(index))) return ItemStack.EMPTY; - ItemStack stack = te.stacks_.get(index).copy(); - if(stack.getCount() > amount) stack.setCount(amount); - if(simulate) return stack; - te.stacks_.get(index).shrink(stack.getCount()); - return stack; - } - - @Override - @Nonnull - public ItemStack getStackInSlot(int index) - { return te.getStackInSlot(index); } - } - - BItemHandler item_handler_ = new BItemHandler(this); - // Capability export ---------------------------------------------------------------------------- @Override @@ -783,8 +717,11 @@ public class BlockDecorDropper extends BlockDecorDirected 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; } + if(nbt.hasKey("drop_count")) drop_count_ = MathHelper.clamp(nbt.getInteger("drop_count"), 1, MAX_DROP_COUNT); + if(nbt.hasKey("drop_period")) drop_period_ = MathHelper.clamp(nbt.getInteger("drop_period"), 0, 100); + if(nbt.hasKey("drop_logic")) drop_logic_ = nbt.getInteger("drop_logic"); + if(nbt.hasKey("manual_rstrigger") && (nbt.getInteger("manual_rstrigger")!=0)) { block_power_signal_=true; block_power_updated_=true; tick_timer_=1; } + if(nbt.hasKey("manual_trigger") && (nbt.getInteger("manual_trigger")!=0)) { tick_timer_ = 1; triggered_ = true; } markDirty(); } @@ -829,9 +766,17 @@ public class BlockDecorDropper extends BlockDecorDirected { 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); + boolean open = (open_timer_ > 0); + if(state.getValue(OPEN) != open) { + state = state.withProperty(OPEN, open); + world.setBlockState(pos, state, 2|16); + if((drop_logic_ & DROPLOGIC_SILENT_OPEN) == 0) { + if(open) { + world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_TRAPDOOR_OPEN, SoundCategory.BLOCKS, 0.08f, 3f); + } else { + world.playSound(null, pos, SoundEvents.BLOCK_WOODEN_TRAPDOOR_CLOSE, SoundCategory.BLOCKS, 0.08f, 3f); + } + } } return state; } @@ -842,71 +787,122 @@ public class BlockDecorDropper extends BlockDecorDirected @Override public void update() { - if((world.isRemote) || (--tick_timer_ > 0)) return; + if(world.isRemote) return; + if(--open_timer_ < 0) open_timer_ = 0; + if((drop_timer_ > 0) && ((--drop_timer_) == 0)) markDirty(); + if(--tick_timer_ > 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= drop_count_) { droppable_slot_found = true; break; } + } + int filter_nset = 0; + // From filters / inventory checks + { + int last_filter_matches_[] = filter_matches_.clone(); + boolean slot_assigned = false; + for(int ci=0; ci 0) ++filter_nset; + if(filter_matches_[i] > 1) ++nmatched; + if(filter_matches_[i] != last_filter_matches_[i]) dirty = true; + } + filter_trigger = ((filter_nset >0) && (nmatched > 0)); + if(((drop_logic_ & DROPLOGIC_FILTER_ANDGATE) != 0) && (nmatched != filter_nset)) filter_trigger = false; + } + // gates + { + if(filter_nset > 0) { + trigger = ((drop_logic_ & DROPLOGIC_EXTERN_ANDGATE) != 0) ? (filter_trigger && redstone_trigger) : (filter_trigger || redstone_trigger); + } else { + trigger = redstone_trigger; + } + if(triggered_) { triggered_ = false; trigger = true; } + if(!droppable_slot_found) { + if(open_timer_> 10) open_timer_ = 10; // override if dropping is not possible at all. + } else if(trigger || filter_trigger || redstone_trigger) { + open_timer_ = SHUTTER_CLOSE_DELAY; } } - for(int i=0; i= 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; + // drop stack for non-filter triggers + if(!filter_trigger) { + Arrays.fill(filter_trigger_slots,-1); + for(int i=0; i= 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_)) { + filter_trigger_slots[0] = ic; + break; + } } } - for(int i=0; i= drop_count_) { + ItemStack drop_stack = ds.splitStack(drop_count_); + if(!drop_stack.isEmpty()) { + dirty = true; + drop(world, pos, state.getValue(FACING), drop_stack, drop_speed_, drop_xdev_, drop_ydev_, drop_noise_); + dropped = true; + } + } + } + // cooldown + if(dropped) drop_timer_ = DROP_PERIOD_OFFSET + drop_period_ * 2; // 0.1s time base -> 100%===10s + // drop sound + if(dropped && ((drop_logic_ & DROPLOGIC_SILENT_DROP) == 0)) { + world.playSound(null, pos, SoundEvents.BLOCK_CLOTH_STEP, SoundCategory.BLOCKS, 0.1f, 4f); + } + // advance to next nonempty slot. + for(int i = 0; i < INPUT_SLOTS_SIZE; ++i) { + if(!stacks_.get(drop_slot_index_).isEmpty()) break; + drop_slot_index_ = next_slot(drop_slot_index_); + } } } if(dirty) markDirty(); if(trigger && (tick_timer_ > 10)) tick_timer_ = 10; } } - } 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 0a0eae8..dc1ee93 100644 --- a/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java +++ b/1.12/src/main/java/wile/engineersdecor/blocks/ModBlocks.java @@ -253,7 +253,7 @@ public class ModBlocks "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) + ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,15) ); //-------------------------------------------------------------------------------------------------------------------- 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 index e50b14c..7e3175d 100644 --- a/1.12/src/main/resources/assets/engineersdecor/blockstates/factory_dropper.json +++ b/1.12/src/main/resources/assets/engineersdecor/blockstates/factory_dropper.json @@ -7,6 +7,6 @@ "normal": [{}], "inventory": [{}], "facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":-90}, "down": {"x":90} }, - "open": { "true":{}, "false":{} } + "open": { "false":{}, "true":{ "model": "engineersdecor:device/factory_dropper_model_open" } } } } 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 index d7eb12e..f505044 100644 --- 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 @@ -1,6 +1,7 @@ { "parent": "block/cube", "textures": { + "shutter": "engineersdecor:blocks/device/factory_dropper_shutter", "top": "engineersdecor:blocks/device/factory_dropper_top", "bottom": "engineersdecor:blocks/device/factory_dropper_bottom", "side": "engineersdecor:blocks/device/factory_dropper_side", @@ -8,63 +9,87 @@ }, "elements": [ { - "from": [0, 0, 2], + "from": [0, 0, 3], "to": [16, 16, 16], "faces": { - "north": {"texture": "#bottom"}, - "east": {"texture": "#side"}, - "south": {"texture": "#top"}, - "west": {"texture": "#side"}, - "up": {"texture": "#side"}, - "down": {"texture": "#side"} + "north": {"uv": [0, 0, 16, 16], "texture": "#bottom"}, + "east": {"uv": [3, 0, 16, 16], "rotation": 180, "texture": "#side"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#top"}, + "west": {"uv": [3, 0, 16, 16], "texture": "#side"}, + "up": {"uv": [3, 0, 16, 16], "rotation": 90, "texture": "#side"}, + "down": {"uv": [3, 0, 16, 16], "rotation": 270, "texture": "#side"} } }, { - "from": [12, 0, 0], - "to": [16, 16, 2], + "from": [12, 0, 1], + "to": [16, 16, 3], "faces": { - "north": {"texture": "#bottom"}, - "east": {"texture": "#side"}, - "south": {"texture": "#top"}, - "west": {"texture": "#side"}, - "up": {"texture": "#side"}, - "down": {"texture": "#side"} + "north": {"uv": [0, 0, 4, 16], "texture": "#bottom"}, + "east": {"uv": [1, 0, 3, 16], "rotation": 180, "texture": "#side"}, + "south": {"uv": [12, 0, 16, 16], "texture": "#top"}, + "west": {"uv": [1, 0, 3, 16], "texture": "#side"}, + "up": {"uv": [1, 12, 3, 16], "rotation": 90, "texture": "#side"}, + "down": {"uv": [1, 12, 3, 16], "rotation": 270, "texture": "#side"} } }, { - "from": [0, 0, 0], - "to": [4, 16, 2], + "from": [0, 0, 1], + "to": [4, 16, 3], "faces": { - "north": {"texture": "#bottom"}, - "east": {"texture": "#side"}, - "south": {"texture": "#top"}, - "west": {"texture": "#side"}, - "up": {"texture": "#side"}, - "down": {"texture": "#side"} + "north": {"uv": [12, 0, 16, 16], "texture": "#bottom"}, + "east": {"uv": [13, 0, 15, 16], "texture": "#side"}, + "south": {"uv": [0, 0, 4, 16], "texture": "#top"}, + "west": {"uv": [1, 0, 3, 16], "texture": "#side"}, + "up": {"uv": [1, 0, 3, 4], "rotation": 90, "texture": "#side"}, + "down": {"uv": [1, 12, 3, 16], "rotation": 270, "texture": "#side"} } }, { - "from": [4, 12, 0], - "to": [12, 16, 2], + "from": [4, 12, 1], + "to": [12, 16, 3], "faces": { - "north": {"texture": "#bottom"}, - "east": {"texture": "#side"}, - "south": {"texture": "#top"}, - "west": {"texture": "#side"}, - "up": {"texture": "#side"}, - "down": {"texture": "#side"} + "north": {"uv": [4, 0, 12, 4], "texture": "#bottom"}, + "east": {"uv": [13, 0, 15, 4], "texture": "#side"}, + "south": {"uv": [4, 0, 12, 4], "texture": "#top"}, + "west": {"uv": [1, 0, 3, 4], "texture": "#side"}, + "up": {"uv": [1, 4, 3, 12], "rotation": 90, "texture": "#side"}, + "down": {"uv": [4, 13, 12, 15], "texture": "#side"} } }, { - "from": [4, 0, 0], - "to": [12, 4, 2], + "from": [4, 0, 1], + "to": [12, 4, 3], "faces": { - "north": {"texture": "#bottom"}, - "east": {"texture": "#side"}, - "south": {"texture": "#top"}, - "west": {"texture": "#side"}, - "up": {"texture": "#side"}, - "down": {"texture": "#side"} + "north": {"uv": [4, 12, 12, 16], "texture": "#bottom"}, + "east": {"uv": [13, 12, 15, 16], "texture": "#side"}, + "south": {"uv": [4, 12, 12, 16], "texture": "#top"}, + "west": {"uv": [1, 12, 3, 16], "texture": "#side"}, + "up": {"uv": [4, 1, 12, 3], "texture": "#side"}, + "down": {"uv": [1, 4, 3, 12], "rotation": 270, "texture": "#side"} + } + }, + { + "from": [4, 4, 2], + "to": [8, 12, 3], + "faces": { + "north": {"uv": [8, 4, 12, 12], "texture": "#shutter"}, + "east": {"uv": [13, 4, 14, 12], "texture": "#shutter"}, + "south": {"uv": [4, 4, 8, 12], "texture": "#shutter"}, + "west": {"uv": [2, 4, 3, 12], "texture": "#shutter"}, + "up": {"uv": [4, 2, 8, 3], "texture": "#shutter"}, + "down": {"uv": [4, 13, 8, 14], "texture": "#shutter"} + } + }, + { + "from": [8.25, 4, 2], + "to": [12, 12, 3], + "faces": { + "north": {"uv": [4, 4, 7.75, 12], "texture": "#shutter"}, + "east": {"uv": [13, 4, 14, 12], "texture": "#shutter"}, + "south": {"uv": [8.25, 4, 12, 12], "texture": "#shutter"}, + "west": {"uv": [2, 4, 3, 12], "texture": "#shutter"}, + "up": {"uv": [8.25, 2, 12, 3], "texture": "#shutter"}, + "down": {"uv": [8.25, 13, 12, 14], "texture": "#shutter"} } } ], diff --git a/1.12/src/main/resources/assets/engineersdecor/models/block/device/factory_dropper_model_open.json b/1.12/src/main/resources/assets/engineersdecor/models/block/device/factory_dropper_model_open.json new file mode 100644 index 0000000..94672c1 --- /dev/null +++ b/1.12/src/main/resources/assets/engineersdecor/models/block/device/factory_dropper_model_open.json @@ -0,0 +1,108 @@ +{ + "parent": "block/cube", + "textures": { + "shutter": "engineersdecor:blocks/device/factory_dropper_shutter", + "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, 3], + "to": [16, 16, 16], + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#bottom"}, + "east": {"uv": [3, 0, 16, 16], "rotation": 180, "texture": "#side"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#top"}, + "west": {"uv": [3, 0, 16, 16], "texture": "#side"}, + "up": {"uv": [3, 0, 16, 16], "rotation": 90, "texture": "#side"}, + "down": {"uv": [3, 0, 16, 16], "rotation": 270, "texture": "#side"} + } + }, + { + "from": [12, 0, 1], + "to": [16, 16, 3], + "faces": { + "north": {"uv": [0, 0, 4, 16], "texture": "#bottom"}, + "east": {"uv": [1, 0, 3, 16], "rotation": 180, "texture": "#side"}, + "south": {"uv": [12, 0, 16, 16], "texture": "#top"}, + "west": {"uv": [1, 0, 3, 16], "texture": "#side"}, + "up": {"uv": [1, 0, 3, 4], "rotation": 90, "texture": "#side"}, + "down": {"uv": [1, 12, 3, 16], "rotation": 270, "texture": "#side"} + } + }, + { + "from": [0, 0, 1], + "to": [4, 16, 3], + "faces": { + "north": {"uv": [12, 0, 16, 16], "texture": "#bottom"}, + "east": {"uv": [13, 0, 15, 16], "texture": "#side"}, + "south": {"uv": [0, 0, 4, 16], "texture": "#top"}, + "west": {"uv": [1, 0, 3, 16], "texture": "#side"}, + "up": {"uv": [1, 12, 3, 16], "rotation": 90, "texture": "#side"}, + "down": {"uv": [1, 0, 3, 4], "rotation": 270, "texture": "#side"} + } + }, + { + "from": [4, 12, 1], + "to": [12, 16, 3], + "faces": { + "north": {"uv": [4, 0, 12, 4], "texture": "#bottom"}, + "east": {"uv": [13, 0, 15, 4], "texture": "#side"}, + "south": {"uv": [4, 0, 12, 4], "texture": "#top"}, + "west": {"uv": [1, 0, 3, 4], "texture": "#side"}, + "up": {"uv": [1, 4, 3, 12], "rotation": 90, "texture": "#side"}, + "down": {"uv": [4, 13, 12, 15], "texture": "#side"} + } + }, + { + "from": [4, 0, 1], + "to": [12, 4, 3], + "faces": { + "north": {"uv": [4, 12, 12, 16], "texture": "#bottom"}, + "east": {"uv": [13, 12, 15, 16], "texture": "#side"}, + "south": {"uv": [4, 12, 12, 16], "texture": "#top"}, + "west": {"uv": [1, 12, 3, 16], "texture": "#side"}, + "up": {"uv": [4, 1, 12, 3], "texture": "#side"}, + "down": {"uv": [1, 4, 3, 12], "rotation": 270, "texture": "#side"} + } + }, + { + "from": [4, 4, 0], + "to": [5, 12, 3], + "faces": { + "north": {"uv": [11, 4, 12, 12], "texture": "#shutter"}, + "east": {"uv": [13, 4, 16, 12], "texture": "#shutter"}, + "south": {"uv": [4, 4, 5, 12], "texture": "#shutter"}, + "west": {"uv": [0, 4, 3, 12], "texture": "#shutter"}, + "up": {"uv": [4, 0, 5, 3], "texture": "#shutter"}, + "down": {"uv": [4, 13, 5, 16], "texture": "#shutter"} + } + }, + { + "from": [11, 4, 0], + "to": [12, 12, 3], + "faces": { + "north": {"uv": [4, 4, 5, 12], "texture": "#shutter"}, + "east": {"uv": [13, 4, 16, 12], "texture": "#shutter"}, + "south": {"uv": [11, 4, 12, 12], "texture": "#shutter"}, + "west": {"uv": [0, 4, 3, 12], "texture": "#shutter"}, + "up": {"uv": [11, 0, 12, 3], "texture": "#shutter"}, + "down": {"uv": [11, 13, 12, 16], "texture": "#shutter"} + } + } + ], + "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/textures/blocks/device/factory_dropper_bottom.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_bottom.png index f0122f55b13bd76852f8e62e7e51e0dd79187257..25a96ba52c5f4862b0188bd905a8b29bee5daa0a 100644 GIT binary patch delta 471 zcmV;|0Vw`}1(yVnN`C>jNkl|O^)I)5QRVg1_TJP0k&|0=_SYEqz<*926R+wDf*_oyls;OFOu*MIB9IF6*0NGUN*6Qz_! zRiAUtZNG>t1n2Xa)9J)83=M6XCY*E4g0&X!J*vv#aA3dRGYkXXS_^=+7FFf@`x^jb z%z|ibv*MlO&({~b-40-RA7g9{^Hs405ukH!@$Nm= zT5Qg_1ymbV^?!q8J;Ia{BEm2Xi-0kv;Z(0{8WCZgQ{7+5tg5zyQc2cT3DzX_1M@sD zW2_-L=RWeN*Lod7XxZePu^|M!_f2FS;J*TOthHi{pXVUP$m8)Kgn)C7loByUN-1r0 z06Awu2u#zoSh!p+^nFj)b$`cWEyv>#5kW*S#xRZ}B2dEpey8tyQc8=3dbR<)_sw4^ zg=w0aNENU9opX2*;cz%`xmzQ>p*} N002ovPDHLkV1l~H1s11b_vQN`C?%NklGz~dtVvGz11M0da=L|sGws`N$ zw=o70K~-@8lgWgtst6&Vs-%?Y_xq%j0O<94u~-me zCbJA0Gp-Uak1^@>0tEa&p4o%?1u27t<-D z(TL%2NL|+$V@%<-Uak23^n|JcpsLh$UDlh|SDv4r=|;{O7eWBw*W)9r^&00KIcG%V z({#?U-EMh%dw(OR#P{oKL%&xA9F=DMPFKdiA=P<@#RFxPb z`LG#d#27=(x1oFjx#>ZEZnvf5R26>^t8H6)yh9-hS^>>n70}c z=378S0PxzPh~T;|GP4W*t=+3(fjbe=01N{#Jc7Kgo1!GDL|(1*rr@Ig3`r2F2W$|owGgvpCqHdvCcUv90 zruck5yzaT?V1b@uJ!h}6w5rYsk}wI)=Fc^5F(EQDs_NvRAAf{tMFT0ZAGyd(UOije z6){~NLbaerNSR}Hg!a>YkRKH9Fm1Re<~gyKbQmn+7H8J^CsY`aHO#h~8Q$4nzbDpJ zROO72w=?d|*4JwHwy`R27Rw|exH9J-IhF!=1W33$f4dG3B6FE#ga7~l07*qoM6N<$ Eg7qw`)c^nh literal 0 HcmV?d00001 diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_side.png b/1.12/src/main/resources/assets/engineersdecor/textures/blocks/device/factory_dropper_side.png index bc0d9b4a03fcd0a28fde5a8df9d8ef1d9c499982..96b02bc27c98c4c8753ab77d478a80bea1747caa 100644 GIT binary patch delta 559 zcmV+~0?_@d1nvZoN`C?lNkl#2sc37ARXd_ zX`+-#leDS0K$@fiDH2G?_RdU-wSOt5n_a#4&3kfxe_vHaYYkOpyWJup0Eh^giK>#B zR23pZRRN%?D1f_jeSJ-9jnmUpX0sXYK22+l*=$B@jpO5E)_?0Yi^YQdTL<9r@sX#e zCoV59`TgSyDneGFdo@{wt8n(=cG_L7R=9}Jd*}T8oaJ&!RbeW)Dg~%O6f|HL!^X+U z35&&o&1QoGWF`QAzJEq27RQZBFjcCOEQl(aD}R4}MJUd0?l80Q!2wES;;L-6ftykh zAP`w(7DWMqh<{9={XkemP=Q?!Ocf#aq=kr~0-z}R{u*Y6?{>TCOp(x<(acbw08?;t zc9CQixo6aSXS>}Fh$4cj;-+LI9dJ>Sq7X8Ys9_by%P~cCRC9!*EZf=Q)sS_$9xI4?`lFeo_;HaYR zpoZF*tPy8bWxZZApU+1g9v&X5wZ_ZK3(wEbTwPsZW>Yo}Nj0;nsjsiE|GUsyBO;j3 x=UiM|@F@27HfpL$RndE&qF#Fi0ISssfPdX7H5%Nkl*4iATbcw5|B#JHBzQanM?S1 zxk9es(yejGq>8x{0XZoE-5ihL>$e}=-rl0BWYzgmRZ$T> z-)v}Z44Qx$#XaZ|cvecEbyyIynXT+9!qkjvhNZbd^lg9#K>$K)jd2|34Mc?HSin>p z5kWOaC1wa2Ef6~R2#%#7nm zjtE+7q?7>odj(<42@wIHltNyTmQtdd^W_S{rS`Wwr}s`?5+x$!q*oDC;Jx)9a!|X` zx}hqRZs^;p9zj;YW3GGe48uUJbr$jA;epfX#PR!2mSkM?-f?%f+b!;nh%ikP?#|(G z;B-1sNlDhCh3JO9V&>5FwNj@)oJnq)y8_<`wb` z*C0W;4GmQkZfC}Jie)!RH4^knX|9BM851 zKQNh@8LB!bMUNt=z=FMwaTo?fgxa0f9aUlKj=o_|xMSJf&JUsC9^aQXf+(&ySGij}@Q(77?yO5c)4=ye) zI6Xb(<>iH87}hnewGt6*HXBrxX__#by?1kS!!%9&0T0fSz9&zuJOBUy07*qoM6N<$ Eg6~1x;s5{u delta 507 zcmV0OMl!+L_t(I%Y~CWZX7WThCfn|&3FtX1_G>$RK~)$NSQ8WS|2i3 z$Q4|=-L$Ua>^wv=g?1Khf)zkO5-EZoe@dR7ohHSr&56tm{fdkaI>vhzKHr zZHWl2HMG{s@jPvef&jiL$Y%U>>L{?oO?h91*PRN=gZUKUWZHPKXEq^E{KcsY)r)%=vr;;qTJU zciv^(CQ3xeNv|TPbjdgA^H#p9vNU6DhN>_(L(ipp1aw&ikG^lMQA+9mMnu@}_Z*K$ z4&Q!YW__s6=H9z5B23eSyYuky!0~wG?d=VHKidE~=L?^iu`J6a$)^1l9}!)J{eI6l xj=a9UQfnomOSL^NrCiRX6hwsk`+Mej<{$dNc88@;{=onM002ovPDHLkV1jW=@NobD diff --git a/1.12/src/main/resources/assets/engineersdecor/textures/gui/factory_dropper_gui.png b/1.12/src/main/resources/assets/engineersdecor/textures/gui/factory_dropper_gui.png index de9b81c9fc5ac793332a404329df1946391479cf..748681374d2f054bc6e8e5f43f8084a67e011a1f 100644 GIT binary patch literal 20850 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%0A&>dSGP#+aQmFF= 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 diff --git a/meta/update.json b/meta/update.json index ee2d14b..dad7cae 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": "[R] Release based on v1.0.6-b1. Release-to-release changes: * Fixed FML remapping issue (COULD CAUSE CRASHES). * Small waste incinerator added. * Lang files updated/corrections. * Metal ladder easier to break.\n[A] Added factory dropper (config:experimental).\n[C] Thx to abdurraslan for the detailed issue #25.", "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.\n[F] Fixed FML remapping issue by using dedicated IItemHandler instances.", "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.", @@ -45,8 +46,8 @@ "1.0.0-a1": "[A] Initial port to 1.13.2 with Forge beta." }, "promos": { - "1.12.2-recommended": "1.0.5", - "1.12.2-latest": "1.0.6-b1", + "1.12.2-recommended": "1.0.6", + "1.12.2-latest": "1.0.6", "1.13.2-recommended": "", "1.13.2-latest": "1.0.4-b3" }