1.14/1.15: Config tweaks for mod packing. Added Factory Hopper bottom item handler. Block shapes refined. Fixed duping bug (issue #87).

This commit is contained in:
stfwi 2020-02-13 21:18:12 +01:00
parent 123319eaf0
commit 85384a91a4
55 changed files with 998 additions and 368 deletions

View file

@ -2,7 +2,7 @@
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx8G
version_minecraft=1.14.4
version_forge_minecraft=1.14.4-28.1.116
version_forge_minecraft=1.14.4-28.2.0
version_fml_mappings=20190719-1.14.3
version_jei=1.14.4:6.0.0.10
version_engineersdecor=1.0.19-b2
version_engineersdecor=1.0.19-b3

View file

@ -1,6 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.14.4": {
"1.0.19-b3": "[M] Config tweaks: Value limit ranges increased to facilitate modpacking.\n[A] Factory Hopper: Added bottom item handler (CR#227).\n[M] Block shapes refined.\n[F] Fixed duping bug (issue #87, thx Nachtflame)",
"1.0.19-b2": "[F] Fixed Floor Grating item pass-through jitters (thx Cid).\n[M] Removed obsolete recipe collision testing recipes.\n[F] Fixed missing Block Breaker dynamic block drops.\n[F] Block Placer planting race condition issue fixed (issue #83, thx jcardii).\n[F] Factory Hopper: Added second standard insertion after smart-insert to circumcent compat issues (issue #84, thx NillerMedDild).",
"1.0.19-b1": "[F] Fixed Tree Cutter / Block Breaker not accepting small energy transfers (thx WindFox, issue #82).",
"1.0.18-b4": "[M] Lang update ru_ru (PR#77, thanks Smollet777).\n[F] Fixed Milking machine cow path issue, added milking delay cow tracking.\n[F] Slab / Slab Slice placement adapted to vanilla standard.",
@ -46,6 +47,6 @@
},
"promos": {
"1.14.4-recommended": "",
"1.14.4-latest": "1.0.19-b2"
"1.14.4-latest": "1.0.19-b3"
}
}

View file

@ -11,6 +11,11 @@ Mod sources for Minecraft version 1.14.4.
## Version history
- v1.0.19-b3 [M] Config tweaks: Value limit ranges increased to facilitate modpacking.
[A] Factory Hopper: Added bottom item handler (CR#227).
[M] Block shapes refined.
[F] Fixed duping bug (issue #87, thx Nachtflame)
- v1.0.19-b2 [F] Fixed Floor Grating item pass-through jitters (thx Cid).
[M] Removed obsolete recipe collision testing recipes.
[F] Fixed missing Block Breaker dynamic block drops.

View file

@ -13,6 +13,10 @@
package wile.engineersdecor;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import net.minecraft.client.gui.ScreenManager;
@ -35,6 +39,7 @@ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.event.RegistryEvent;
import org.apache.commons.lang3.ArrayUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
import javax.annotation.Nonnull;
@ -222,7 +227,12 @@ public class ModContent
public static final BlockDecorChair TREATED_WOOD_STOOL = (BlockDecorChair)(new BlockDecorChair(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
Auxiliaries.getPixeledAABB(4.1,0,4.1, 11.8,8.8,11.8)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(4,7,4, 12,8.8,12),
Auxiliaries.getPixeledAABB(7,0,7, 9,7,9),
Auxiliaries.getPixeledAABB(4,0,7, 12,1,9),
Auxiliaries.getPixeledAABB(7,0,4, 9,1,12),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_stool"));
public static final BlockDecor.WaterLoggable TREATED_WOOD_SIDE_TABLE = (BlockDecor.WaterLoggable)(new BlockDecor.WaterLoggable(
@ -374,19 +384,31 @@ public class ModContent
public static final BlockDecorCraftingTable.CraftingTableBlock TREATED_WOOD_CRAFTING_TABLE = (BlockDecorCraftingTable.CraftingTableBlock)(new BlockDecorCraftingTable.CraftingTableBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 15f).sound(SoundType.WOOD),
Auxiliaries.getPixeledAABB(1,0,1, 15,15.9,15)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(0,13,0, 16,16,16),
Auxiliaries.getPixeledAABB(1, 0,1, 15,13,15)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_crafting_table"));
public static final BlockDecorFurnace SMALL_LAB_FURNACE = (BlockDecorFurnace)(new BlockDecorFurnace(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(1,0,1, 15,15,16.0)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(1,0,1, 15, 1,15),
Auxiliaries.getPixeledAABB(0,1,1, 16,16,16),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_lab_furnace"));
public static final BlockDecorFurnaceElectrical SMALL_ELECTRICAL_FURNACE = (BlockDecorFurnaceElectrical)(new BlockDecorFurnaceElectrical(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(0, 0,0, 16,11,16),
Auxiliaries.getPixeledAABB(1,11,0, 15,12,16),
Auxiliaries.getPixeledAABB(2,12,0, 14,13,16),
Auxiliaries.getPixeledAABB(3,13,0, 13,14,16),
Auxiliaries.getPixeledAABB(4,14,0, 12,16,16),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_electrical_furnace"));
public static final BlockDecorDropper FACTORY_DROPPER = (BlockDecorDropper)(new BlockDecorDropper(
@ -398,19 +420,70 @@ public class ModContent
public static final BlockDecorPlacer FACTORY_PLACER = (BlockDecorPlacer)(new BlockDecorPlacer(
BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(2,2,2, 14,14,14)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(0,0,2, 16,16,16),
Auxiliaries.getPixeledAABB( 0,0,0, 1,16, 2),
Auxiliaries.getPixeledAABB(15,0,0,16,16, 2)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "factory_placer"));
public static final BlockDecorBreaker SMALL_BLOCK_BREAKER = (BlockDecorBreaker)(new BlockDecorBreaker(
BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0,0,0, 16,12,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(1,0,0, 15, 4, 7),
Auxiliaries.getPixeledAABB(1,0,7, 15,12,16),
Auxiliaries.getPixeledAABB(0,0,0, 1, 5, 4),
Auxiliaries.getPixeledAABB(0,0,4, 1,12,16),
Auxiliaries.getPixeledAABB(15,0,0, 16, 5, 4),
Auxiliaries.getPixeledAABB(15,0,4, 16,12,16)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_block_breaker"));
public static final BlockDecorHopper FACTORY_HOPPER = (BlockDecorHopper)(new BlockDecorHopper(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,16)
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL), ()->{
final AxisAlignedBB[] down_aabbs = new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 5, 0, 5, 11, 1,11),
Auxiliaries.getPixeledAABB( 4, 1, 4, 12, 7,12),
Auxiliaries.getPixeledAABB( 2, 7, 2, 14,10,14),
Auxiliaries.getPixeledAABB( 0,10, 0, 16,16,16),
Auxiliaries.getPixeledAABB( 0, 4, 5, 2,10,11),
Auxiliaries.getPixeledAABB(14, 4, 5, 16,10,11),
Auxiliaries.getPixeledAABB( 5, 4, 0, 11,10, 2),
Auxiliaries.getPixeledAABB( 5, 4,14, 11,10,16),
};
final AxisAlignedBB[] up_aabbs = new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 5,15, 5, 11,16,11),
Auxiliaries.getPixeledAABB( 4,14, 4, 12, 9,12),
Auxiliaries.getPixeledAABB( 2, 9, 2, 14, 6,14),
Auxiliaries.getPixeledAABB( 0, 6, 0, 16, 0,16),
Auxiliaries.getPixeledAABB( 0,12, 5, 2, 6,11),
Auxiliaries.getPixeledAABB(14,12, 5, 16, 6,11),
Auxiliaries.getPixeledAABB( 5,12, 0, 11, 6, 2),
Auxiliaries.getPixeledAABB( 5,12,14, 11, 6,16),
};
final AxisAlignedBB[] north_aabbs = new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 5, 0, 5, 11, 1,11),
Auxiliaries.getPixeledAABB( 4, 1, 4, 12, 7,12),
Auxiliaries.getPixeledAABB( 2, 7, 2, 14,10,14),
Auxiliaries.getPixeledAABB( 0,10, 0, 16,16,16),
Auxiliaries.getPixeledAABB( 0, 4, 5, 2,10,11),
Auxiliaries.getPixeledAABB(14, 4, 5, 16,10,11),
Auxiliaries.getPixeledAABB( 5, 1, 0, 11, 7, 4),
Auxiliaries.getPixeledAABB( 5, 4,14, 11,10,16),
};
return new ArrayList<VoxelShape>(Arrays.asList(
Auxiliaries.getUnionShape(down_aabbs),
Auxiliaries.getUnionShape(up_aabbs),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(north_aabbs, Direction.NORTH, false)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(north_aabbs, Direction.SOUTH, false)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(north_aabbs, Direction.WEST, false)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(north_aabbs, Direction.EAST, false)),
VoxelShapes.fullCube(),
VoxelShapes.fullCube()
));
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "factory_hopper"));
public static final BlockDecorWasteIncinerator SMALL_WASTE_INCINERATOR = (BlockDecorWasteIncinerator)(new BlockDecorWasteIncinerator(
@ -434,46 +507,81 @@ public class ModContent
public static final BlockDecorMilker SMALL_MILKING_MACHINE = (BlockDecorMilker)(new BlockDecorMilker(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,13)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 1, 1,0, 15,14,10),
Auxiliaries.getPixeledAABB( 0,14,0, 16,16,13),
Auxiliaries.getPixeledAABB( 0, 0,0, 16, 1,13),
Auxiliaries.getPixeledAABB( 0, 1,1, 1,14,11),
Auxiliaries.getPixeledAABB(15, 1,1, 16,14,11)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_milking_machine"));
public static final BlockDecorTreeCutter SMALL_TREE_CUTTER = (BlockDecorTreeCutter)(new BlockDecorTreeCutter(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0,0,0, 16,8,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 0,0, 0, 16,3,16),
Auxiliaries.getPixeledAABB( 0,3, 0, 3,8,16),
Auxiliaries.getPixeledAABB( 3,7, 0, 5,8,16),
Auxiliaries.getPixeledAABB(15,0, 0, 16,6,16),
Auxiliaries.getPixeledAABB( 0,0,13, 16,8,16),
Auxiliaries.getPixeledAABB( 5,6,12, 16,8,13),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_tree_cutter"));
public static final BlockDecorPipeValve STRAIGHT_CHECK_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_CHECK_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(4,4,0, 12,12,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(2,2, 0, 14,14, 2),
Auxiliaries.getPixeledAABB(2,2,14, 14,14,16),
Auxiliaries.getPixeledAABB(3,3, 5, 13,13,11),
Auxiliaries.getPixeledAABB(4,4, 2, 12,12,14),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_REDSTONE_CONTROLLED_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(4,4,0, 12,12,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(2,2, 0, 14,14, 2),
Auxiliaries.getPixeledAABB(2,2,14, 14,14,16),
Auxiliaries.getPixeledAABB(3,3, 5, 13,13,11),
Auxiliaries.getPixeledAABB(4,4, 2, 12,12,14),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve_redstone"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_ANALOG_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_REDSTONE_CONTROLLED_VALVE|BlockDecorPipeValve.CFG_ANALOG_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(4,4,0, 12,12,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(2,2, 0, 14,14, 2),
Auxiliaries.getPixeledAABB(2,2,14, 14,14,16),
Auxiliaries.getPixeledAABB(3,3, 5, 13,13,11),
Auxiliaries.getPixeledAABB(4,4, 2, 12,12,14),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve_redstone_analog"));
public static final BlockDecorPassiveFluidAccumulator PASSIVE_FLUID_ACCUMULATOR = (BlockDecorPassiveFluidAccumulator)(new BlockDecorPassiveFluidAccumulator(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(3,3,0, 13,13, 1),
Auxiliaries.getPixeledAABB(0,0,1, 16,16,16)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "passive_fluid_accumulator"));
public static final BlockDecorFluidFunnel SMALL_FLUID_FUNNEL = (BlockDecorFluidFunnel)(new BlockDecorFluidFunnel(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(0, 0,0, 16,14,16),
Auxiliaries.getPixeledAABB(1,14,1, 15,15,15),
Auxiliaries.getPixeledAABB(0,15,0, 16,16,16)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_fluid_funnel"));
// -------------------------------------------------------------------------------------------------------------------
@ -522,7 +630,8 @@ public class ModContent
public static final BlockDecorFence STEEL_MESH_FENCE = (BlockDecorFence)(new BlockDecorFence(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL)
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
1.5, 16, 0.25, 0, 16
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "steel_mesh_fence"));
// -------------------------------------------------------------------------------------------------------------------

View file

@ -19,6 +19,8 @@ import net.minecraft.block.IWaterLoggable;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.block.Block;
import java.util.ArrayList;
import java.util.function.Supplier;
public class BlockDecor extends StandardBlocks.BaseBlock implements IDecorBlock
@ -46,6 +48,9 @@ public class BlockDecor extends StandardBlocks.BaseBlock implements IDecorBlock
public BlockDecor(long conf, Block.Properties properties, VoxelShape voxel_shape)
{ super(conf, properties, voxel_shape); }
public BlockDecor(long conf, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(conf, properties, aabbs); }
public static class WaterLoggable extends StandardBlocks.WaterLoggable implements IStandardBlock, IWaterLoggable
{
public WaterLoggable(long config, Block.Properties properties)
@ -62,23 +67,47 @@ public class BlockDecor extends StandardBlocks.BaseBlock implements IDecorBlock
{
public Directed(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public Directed(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, properties, unrotatedAABBs); }
public Directed(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, properties, shape_supplier); }
}
public static class DirectedWaterLoggable extends StandardBlocks.DirectedWaterLoggable implements IDecorBlock,IWaterLoggable
{
public DirectedWaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config, properties, aabb); }
public DirectedWaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config, properties, aabbs); }
public DirectedWaterLoggable(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, properties, shape_supplier); }
}
public static class Horizontal extends StandardBlocks.Horizontal implements IDecorBlock
{
public Horizontal(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public Horizontal(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, properties, unrotatedAABBs); }
public Horizontal(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, properties, shape_supplier); }
}
public static class HorizontalWaterLoggable extends StandardBlocks.HorizontalWaterLoggable implements IWaterLoggable
{
public HorizontalWaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config, properties, aabb); }
public HorizontalWaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config, properties, aabbs); }
public HorizontalWaterLoggable(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, properties, shape_supplier); }
}
}

View file

@ -46,8 +46,8 @@ public class BlockDecorBreaker extends StandardBlocks.HorizontalWaterLoggable im
{
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public BlockDecorBreaker(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public BlockDecorBreaker(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
@ -132,7 +132,7 @@ public class BlockDecorBreaker extends StandardBlocks.HorizontalWaterLoggable im
public static void on_config(int boost_energy_per_tick, int breaking_time_per_hardness, int min_breaking_time_ticks, boolean power_required)
{
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 4, 4096);
breaking_reluctance = MathHelper.clamp(breaking_time_per_hardness, 5, 50);
min_breaking_time = MathHelper.clamp(min_breaking_time_ticks, 10, 100);
requires_power = power_required;

View file

@ -43,8 +43,8 @@ public class BlockDecorChair extends StandardBlocks.HorizontalWaterLoggable
ModEngineersDecor.logger().info("Config chairs: " + sitting_enabled + ", sit: " + sitting_probability, ", stand up: " + standup_probability);
}
public BlockDecorChair(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder.tickRandomly(), unrotatedAABB); }
public BlockDecorChair(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder.tickRandomly(), unrotatedAABBs); }
@Override
@SuppressWarnings("deprecation")

View file

@ -15,11 +15,11 @@
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.IWaterLoggable;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.inventory.container.*;
import net.minecraft.network.play.server.SSetSlotPacket;
@ -90,8 +90,8 @@ public class BlockDecorCraftingTable
public static final class CraftingTableBlock extends StandardBlocks.HorizontalWaterLoggable implements IDecorBlock
{
public CraftingTableBlock(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public CraftingTableBlock(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
@Override
public boolean hasTileEntity(BlockState state)
@ -579,7 +579,7 @@ public class BlockDecorCraftingTable
if(nbt.contains("move-all")) {
for(int i=0; i < player.inventory.getSizeInventory(); ++i) {
final ItemStack stack = player.inventory.getStackInSlot(i);
if(!reference_stack.isItemEqual(stack)) continue;
if(!Inventories.areItemStacksIdentical(reference_stack, stack)) continue;
if(distribute_stack(player.inventory, i) == PlacementResult.UNCHANGED) break; // grid is full
}
}
@ -616,7 +616,7 @@ public class BlockDecorCraftingTable
boolean abort = false;
for(int i=0; (i < from_inventory.getSizeInventory()) && (!abort); ++i) {
final ItemStack stack = from_inventory.getStackInSlot(i);
if(!reference_stack.isItemEqual(stack)) continue;
if(Inventories.areItemStacksDifferent(reference_stack, stack)) continue;
ItemStack remaining = from_inventory.getStackInSlot(i);
for(SlotRange range:to_ranges) {
remaining = move_stack_to_inventory(remaining, range, false, 0);
@ -738,7 +738,7 @@ public class BlockDecorCraftingTable
for(SlotRange range: search_ranges) {
for(int i=0; i<range.inventory.getSizeInventory(); ++i) {
ItemStack stack = range.inventory.getStackInSlot(i);
if(stack.isItemEqual(match_stack)) return match_stack;
if(Inventories.areItemStacksIdentical(stack, match_stack)) return match_stack;
}
}
return not_found_value;
@ -797,7 +797,7 @@ public class BlockDecorCraftingTable
if(to_replace.isEmpty() || (!search_inventory(to_replace, ItemStack.EMPTY).isEmpty())) continue; // no replacement needed
for(int ingredient_index=0; ingredient_index<recipe.getIngredients().size(); ++ingredient_index) {
ItemStack[] match_stacks = recipe.getIngredients().get(ingredient_index).getMatchingStacks();
if(Arrays.stream(match_stacks).anyMatch(s->s.isItemEqual(to_replace))) {
if(Arrays.stream(match_stacks).anyMatch(s->Inventories.areItemStacksIdentical(s, to_replace))) {
replacement = search_inventory(match_stacks, to_replace);
changed = true;
break;
@ -946,7 +946,7 @@ public class BlockDecorCraftingTable
for(int i = slot_begin+1; i < slot_end-1; ++i) {
final ItemStack stack = inventory.getStackInSlot(i);
if(!stack.isEmpty()) continue;
if((!inventory.getStackInSlot(i+1).isItemEqual(mvstack)) && (!inventory.getStackInSlot(i-1).isItemEqual(mvstack))) continue;
if((Inventories.areItemStacksDifferent(inventory.getStackInSlot(i+1), mvstack)) && (Inventories.areItemStacksDifferent(inventory.getStackInSlot(i-1), mvstack))) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack placed = mvstack.copy();
placed.setCount(nmax);
@ -986,17 +986,14 @@ public class BlockDecorCraftingTable
int smallest_stack_index = -1;
for(int i = slot_begin; i < slot_end; ++i) {
final ItemStack stack = inventory.getStackInSlot(i);
if((!stack.isEmpty()) && (stack.isItemEqual(request_stack))) {
// Never automatically place stuff with nbt (except a few allowed like "Damage"),
// as this could be a full crate, a valuable tool item, etc. For these recipes
// the user has to place this item manually.
if((!stack.isEmpty()) && (Inventories.areItemStacksIdentical(stack, request_stack))) {
if(stack.hasTag()) {
final CompoundNBT nbt = stack.getTag();
int n = nbt.size();
if((n > 0) && (nbt.contains("Damage"))) --n;
if(n > 0) continue;
}
fetched_stack = stack.copy(); // copy exact stack with nbt and tool damage, otherwise we have an automagical repair of items.
fetched_stack = stack.copy();
fetched_stack.setCount(0);
int n = stack.getCount();
if((n < smallest_stack_size) || (smallest_stack_size <= 0)) {
@ -1103,24 +1100,20 @@ public class BlockDecorCraftingTable
int matching_grid_stack_sizes[] = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
int max_matching_stack_size = -1;
int min_matching_stack_size = 65;
int total_num_missing_stacks = 0;
for(int i=0; i<9; ++i) {
final ItemStack grid_stack = inventory_.getStackInSlot(i+CRAFTING_SLOTS_BEGIN);
final ItemStack refab_stack = to_refab.isEmpty() ? ItemStack.EMPTY : to_refab.get(i).copy();
if((!grid_stack.isEmpty()) && (grid_stack.isItemEqual(to_distribute))) {
if((!grid_stack.isEmpty()) && Inventories.areItemStacksIdentical(grid_stack, to_distribute)) {
matching_grid_stack_sizes[i] = grid_stack.getCount();
total_num_missing_stacks += grid_stack.getMaxStackSize()-grid_stack.getCount();
if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i];
if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i];
} else if((!refab_stack.isEmpty()) && (refab_stack.isItemEqual(to_distribute))) {
} else if((!refab_stack.isEmpty()) && (Inventories.areItemStacksIdentical(refab_stack, to_distribute))) {
matching_grid_stack_sizes[i] = 0;
total_num_missing_stacks += grid_stack.getMaxStackSize();
if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i];
if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i];
} else if(grid_stack.isEmpty() && (!refab_stack.isEmpty())) {
if(itemstack_recipe_match(to_distribute, refab_stack)) {
matching_grid_stack_sizes[i] = 0;
total_num_missing_stacks += grid_stack.getMaxStackSize();
if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i];
if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i];
}

View file

@ -11,6 +11,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.inventory.container.INamedContainerProvider;
@ -552,7 +553,6 @@ public class BlockDecorDropper extends StandardBlocks.Directed implements IDecor
{
int filter_nset = 0;
int last_filter_matches_[] = filter_matches_.clone();
boolean slot_assigned = false;
for(int ci=0; ci<CTRL_SLOTS_SIZE; ++ci) {
filter_matches_[ci] = 0;
final ItemStack cmp_stack = stacks_.get(CTRL_SLOTS_FIRST+ci);
@ -563,7 +563,7 @@ public class BlockDecorDropper extends StandardBlocks.Directed implements IDecor
int slot = drop_slot_index_;
for(int i=INPUT_SLOTS_FIRST; i<(INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE); ++i) {
final ItemStack inp_stack = stacks_.get(slot);
if(!inp_stack.isItemEqual(cmp_stack)) { slot = next_slot(slot); continue; }
if(Inventories.areItemStacksDifferent(inp_stack, cmp_stack)) { slot = next_slot(slot); continue; }
inventory_item_count += inp_stack.getCount();
if(inventory_item_count < cmp_stack_count) { slot = next_slot(slot); continue; }
filter_matches_[ci] = 2;
@ -628,7 +628,7 @@ public class BlockDecorDropper extends StandardBlocks.Directed implements IDecor
int ntoremove = drop_stacks[fi].getCount();
for(int i=INPUT_SLOTS_SIZE-1; (i>=0) && (ntoremove>0); --i) {
ItemStack stack = stacks_.get(i);
if(!stack.isItemEqual(drop_stacks[fi])) continue;
if(Inventories.areItemStacksDifferent(stack, drop_stacks[fi])) continue;
if(stack.getCount() <= ntoremove) {
ntoremove -= stack.getCount();
stacks_.set(i, ItemStack.EMPTY);

View file

@ -13,6 +13,9 @@ import net.minecraft.block.*;
public class BlockDecorFence extends StandardFenceBlock implements IDecorBlock
{
public BlockDecorFence(long config, Block.Properties builder)
{ super(config, builder); }
public BlockDecorFence(long config, Block.Properties properties)
{ super(config, properties); }
public BlockDecorFence(long config, Block.Properties properties, double pole_width, double pole_height, double side_width, double side_max_y, double side_min_y)
{ super(config, properties, pole_width, pole_height, side_width, side_max_y, side_min_y); }
}

View file

@ -48,7 +48,7 @@ public class BlockDecorFluidFunnel extends StandardBlocks.BaseBlock implements I
public static final int FILL_LEVEL_MAX = 3;
public static final IntegerProperty FILL_LEVEL = IntegerProperty.create("level", 0, FILL_LEVEL_MAX);
public BlockDecorFluidFunnel(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorFluidFunnel(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@ -139,7 +139,7 @@ public class BlockDecorFluidFunnel extends StandardBlocks.BaseBlock implements I
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, ICapabilityProvider
public static class BTileEntity extends TileEntity implements ITickableTileEntity, ICapabilityProvider, IFluidTank
{
public static final int TANK_CAPACITY = 3000;
public static final int TICK_INTERVAL = 10; // ca 500ms
@ -198,24 +198,8 @@ public class BlockDecorFluidFunnel extends StandardBlocks.BaseBlock implements I
@Override public int getTankCapacity(int tank) { return TANK_CAPACITY; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return true; }
@Override public int fill(FluidStack resource, FluidAction action) { return 0; }
@Override public FluidStack drain(FluidStack resource, FluidAction action)
{
if((resource==null) || (te.tank_.isEmpty())) return FluidStack.EMPTY;
return (!(te.tank_.isFluidEqual(resource))) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action);
}
@Override public FluidStack drain(int maxDrain, FluidAction action)
{
if(te.tank_.isEmpty()) return FluidStack.EMPTY;
FluidStack res = te.tank_.copy();
maxDrain = MathHelper.clamp(maxDrain ,0 , te.tank_.getAmount());
res.setAmount(maxDrain);
if(action != FluidAction.EXECUTE) return res;
te.tank_.setAmount(te.tank_.getAmount()-maxDrain);
if(te.tank_.getAmount() <= 0) te.tank_ = FluidStack.EMPTY;
return res;
}
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return te.drain(resource, action); }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return te.drain(maxDrain, action); }
}
private final LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> new OutputFluidHandler(this));
@ -227,6 +211,51 @@ public class BlockDecorFluidFunnel extends StandardBlocks.BaseBlock implements I
return super.getCapability(capability, facing);
}
// IFluidTank ------------------------------------------------------------------------------------------
@Override
@Nonnull
public FluidStack getFluid()
{ return tank_.copy(); }
@Override
public int getFluidAmount()
{ return tank_.getAmount(); }
@Override
public int getCapacity()
{ return TANK_CAPACITY; }
@Override
public boolean isFluidValid(FluidStack stack)
{ return true; }
@Override
public int fill(FluidStack resource, FluidAction action)
{ return 0; }
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action)
{
if((resource==null) || (tank_.isEmpty())) return FluidStack.EMPTY;
return (!(tank_.isFluidEqual(resource))) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action);
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action)
{
if(tank_.isEmpty()) return FluidStack.EMPTY;
FluidStack res = tank_.copy();
maxDrain = MathHelper.clamp(maxDrain ,0 , tank_.getAmount());
res.setAmount(maxDrain);
if(action != FluidAction.EXECUTE) return res;
tank_.setAmount(tank_.getAmount()-maxDrain);
if(tank_.getAmount() <= 0) tank_ = FluidStack.EMPTY;
return res;
}
// ITickableTileEntity --------------------------------------------------------------------------------
private IFluidState get_fluidstate(BlockPos pos)

View file

@ -12,6 +12,7 @@ import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ExtItems;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.tileentity.*;
import net.minecraft.inventory.container.*;
@ -68,11 +69,8 @@ public class BlockDecorFurnace extends StandardBlocks.Horizontal
{
public static final BooleanProperty LIT = RedstoneTorchBlock.LIT;
public BlockDecorFurnace(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{
super(config, builder, unrotatedAABB);
setDefaultState(super.getDefaultState().with(LIT, false));
}
public BlockDecorFurnace(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABB)
{ super(config, properties, unrotatedAABB); setDefaultState(super.getDefaultState().with(LIT, false)); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
@ -216,7 +214,7 @@ public class BlockDecorFurnace extends StandardBlocks.Horizontal
{
proc_speed_ = ((double)MathHelper.clamp(speed_percent, 10, 500)) / 100;
proc_fuel_efficiency_ = ((double) MathHelper.clamp(fuel_efficiency_percent, 10, 500)) / 100;
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 4, 4096);
ModEngineersDecor.logger().info("Config lab furnace speed:" + (proc_speed_*100) + "%, efficiency:" + (proc_fuel_efficiency_*100) + "%");
}
@ -351,7 +349,7 @@ public class BlockDecorFurnace extends StandardBlocks.Horizontal
public void setInventorySlotContents(int index, ItemStack stack)
{
ItemStack slot_stack = stacks_.get(index);
boolean already_in_slot = (!stack.isEmpty()) && (stack.isItemEqual(slot_stack)) && (ItemStack.areItemStackTagsEqual(stack, slot_stack));
boolean already_in_slot = (!stack.isEmpty()) && (Inventories.areItemStacksIdentical(stack, slot_stack));
stacks_.set(index, stack);
if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit());
if((index == SMELTING_INPUT_SLOT_NO) && (!already_in_slot)) {
@ -625,7 +623,7 @@ public class BlockDecorFurnace extends StandardBlocks.Horizontal
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
} else if(Inventories.areItemStacksDifferent(from, to)) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {

View file

@ -10,6 +10,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.inventory.container.*;
import net.minecraft.item.crafting.AbstractCookingRecipe;
@ -59,8 +60,8 @@ import java.util.Random;
public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
{
public BlockDecorFurnaceElectrical(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public BlockDecorFurnaceElectrical(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
@Override
@Nullable
@ -137,7 +138,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
public static void on_config(int speed_percent, int standard_energy_per_tick, boolean with_automatic_inventory_pulling)
{
proc_speed_percent_ = MathHelper.clamp(speed_percent, 10, 500);
energy_consumption_ = MathHelper.clamp(standard_energy_per_tick, 10, 256) * HEAT_INCREMENT * proc_speed_percent_ / 100;
energy_consumption_ = MathHelper.clamp(standard_energy_per_tick, 4, 4096) * HEAT_INCREMENT * proc_speed_percent_ / 100;
transfer_energy_consumption_ = MathHelper.clamp(energy_consumption_ / 8, 8, HEAT_INCREMENT);
with_automatic_inventory_pulling_ = with_automatic_inventory_pulling;
ModEngineersDecor.logger().info("Config electrical furnace speed:" + proc_speed_percent_ + ", power consumption:" + energy_consumption_);
@ -514,7 +515,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
} else if(Inventories.areItemStacksDifferent(from, to)) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {

View file

@ -11,6 +11,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
@ -34,6 +35,7 @@ import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.util.*;
import net.minecraft.util.math.*;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.text.*;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
@ -49,12 +51,13 @@ import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorBlock
{
public BlockDecorHopper(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public BlockDecorHopper(long config, Block.Properties builder, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, builder, shape_supplier); }
@Override
@SuppressWarnings("deprecation")
@ -395,7 +398,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
// ISidedInventory --------------------------------------------------------------------------------------
LazyOptional<? extends IItemHandler>[] item_handlers = SidedInvWrapper.create(this, Direction.UP);
LazyOptional<? extends IItemHandler>[] item_handlers = SidedInvWrapper.create(this, Direction.UP, Direction.DOWN);
private static final int[] SIDED_INV_SLOTS;
static {
SIDED_INV_SLOTS = new int[NUM_OF_SLOTS];
@ -420,7 +423,10 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if(facing == Direction.UP) return item_handlers[0].cast();
if(facing == Direction.DOWN) return item_handlers[1].cast();
}
}
return super.getCapability(capability, facing);
}
@ -438,7 +444,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
for(int i=0; i<stacks_.size(); ++i) {
final ItemStack slotstack = stacks_.get(i);
if((first_empty_slot < 0) && slotstack.isEmpty()) { first_empty_slot=i; continue; }
if(!stack.isItemEqual(slotstack)) continue;
if(Inventories.areItemStacksDifferent(stack, slotstack)) continue;
int nspace = slotstack.getMaxStackSize() - slotstack.getCount();
if(nspace <= 0) {
continue;
@ -491,7 +497,7 @@ public class BlockDecorHopper extends StandardBlocks.Directed implements IDecorB
// First stack comletion insert run.
for(int i=0; i<ih.getSlots(); ++i) {
final ItemStack target_stack = ih.getStackInSlot(i);
if(!target_stack.isItemEqual(insert_stack)) continue;
if(Inventories.areItemStacksDifferent(target_stack, insert_stack)) continue;
insert_stack = ih.insertItem(i, insert_stack.copy(), false);
if(insert_stack.isEmpty()) break;
}

View file

@ -11,7 +11,8 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.detail.ExtItems;
import wile.engineersdecor.detail.ItemHandling;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import wile.engineersdecor.libmc.detail.Inventories;
import net.minecraft.world.World;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.IBlockReader;
@ -40,13 +41,12 @@ import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
@ -59,8 +59,8 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
public static final BooleanProperty FILLED = BooleanProperty.create("filled");
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public BlockDecorMilker(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public BlockDecorMilker(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
@ -134,7 +134,7 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, IEnergyStorage, ICapabilityProvider
public static class BTileEntity extends TileEntity implements ITickableTileEntity, IEnergyStorage, IFluidTank, ICapabilityProvider
{
public static final int BUCKET_SIZE = 1000;
public static final int TICK_INTERVAL = 80;
@ -146,10 +146,11 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
public static final int MAX_ENERGY_TRANSFER = 512;
public static final int DEFAULT_ENERGY_CONSUMPTION = 0;
public static final int DEFAULT_MILKING_DELAY_PER_COW = 4000;
private static final FluidStack NO_MILK_FLUID = new FluidStack(Fluids.WATER, 0);
private static final Direction FLUID_TRANSFER_DIRECTRIONS[] = {Direction.DOWN,Direction.EAST,Direction.SOUTH,Direction.WEST,Direction.NORTH};
private enum MilkingState { IDLE, PICKED, COMING, POSITIONING, MILKING, LEAVING, WAITING }
private static FluidStack milk_fluid_ = new FluidStack(Fluids.WATER, 0);
private static FluidStack milk_fluid_ = NO_MILK_FLUID;
private static HashMap<ItemStack, ItemStack> milk_containers_ = new HashMap<>();
private static int energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
private static long min_milking_delay_per_cow_ticks = DEFAULT_MILKING_DELAY_PER_COW;
@ -164,7 +165,7 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
public static void on_config(int energy_consumption_per_tick, int min_milking_delay_per_cow)
{
energy_consumption = MathHelper.clamp(energy_consumption_per_tick, 0, 128);
energy_consumption = MathHelper.clamp(energy_consumption_per_tick, 0, 1024);
min_milking_delay_per_cow_ticks = MathHelper.clamp(min_milking_delay_per_cow, 1000, 24000);
{
Fluid milk = null; // FluidRe.getFluid("milk");
@ -260,31 +261,61 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
// IFluidHandler / IFluidTankProperties ---------------------------------------------------------------------
private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)new BFluidHandler(this));
private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)new OutputFluidHandler(this));
private static class BFluidHandler implements IFluidHandler
private static class OutputFluidHandler implements IFluidHandler
{
private final BTileEntity te;
BFluidHandler(BTileEntity te) { this.te = te; }
OutputFluidHandler(BTileEntity te) { this.te = te; }
@Override public int getTanks() { return 1; }
@Override public FluidStack getFluidInTank(int tank) { return new FluidStack(milk_fluid_, te.fluid_level()); }
@Override public int getTankCapacity(int tank) { return TANK_CAPACITY; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return false; }
@Override public FluidStack getFluidInTank(int tank) { return te.getFluid(); }
@Override public int getTankCapacity(int tank) { return te.getCapacity(); }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return te.isFluidValid(stack); }
@Override public int fill(FluidStack resource, FluidAction action) { return 0; }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return te.drain(resource, action); }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return te.drain(maxDrain, action); }
}
@Override
public FluidStack drain(FluidStack resource, FluidAction action)
{ return (!resource.isFluidEqual(milk_fluid_)) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action); }
// IFluidTank ------------------------------------------------------------------------------------------
@Override
public FluidStack drain(int maxDrain, FluidAction action)
{
if(te.fluid_level() <= 0) return FluidStack.EMPTY;
FluidStack fs = milk_fluid_.copy();
fs.setAmount(Math.min(fs.getAmount(), te.fluid_level()));
if(action==FluidAction.EXECUTE) te.tank_level_ -= fs.getAmount();
return fs;
}
private boolean has_milk_fluid()
{ return !(NO_MILK_FLUID.isFluidEqual(milk_fluid_)); }
@Override
@Nonnull
public FluidStack getFluid()
{ return has_milk_fluid() ? (new FluidStack(milk_fluid_, fluid_level())) : (FluidStack.EMPTY); }
@Override
public int getFluidAmount()
{ return has_milk_fluid() ? fluid_level() : 0; }
@Override
public int getCapacity()
{ return TANK_CAPACITY; }
@Override
public boolean isFluidValid(FluidStack stack)
{ return has_milk_fluid() && stack.isFluidEqual(milk_fluid_); }
@Override
public int fill(FluidStack resource, FluidAction action)
{ return 0; }
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action)
{ return (!resource.isFluidEqual(milk_fluid_)) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action); }
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action)
{
if((!has_milk_fluid()) || (fluid_level() <= 0)) return FluidStack.EMPTY;
FluidStack fs = milk_fluid_.copy();
fs.setAmount(Math.min(fs.getAmount(), fluid_level()));
if(action==FluidAction.EXECUTE) tank_level_ -= Math.max(0, fs.getAmount());
return fs;
}
// ICapabilityProvider ---------------------------------------------------------------------------
@ -293,7 +324,7 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if((capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && (!milk_fluid_.isEmpty())) {
if((capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && has_milk_fluid()) {
return fluid_handler_.cast();
} else if((capability == CapabilityEnergy.ENERGY) && (energy_consumption>0)) {
return energy_handler_.cast();
@ -309,21 +340,21 @@ public class BlockDecorMilker extends StandardBlocks.Horizontal implements IDeco
private static final HashMap<Integer, Long> tracked_cows_ = new HashMap<Integer, Long>();
private static ItemStack milk_filled_container_item(ItemStack stack)
{ return milk_containers_.entrySet().stream().filter(e->e.getKey().isItemEqual(stack)).map(Map.Entry::getValue).findFirst().orElse(ItemStack.EMPTY); }
{ return milk_containers_.entrySet().stream().filter(e->Inventories.areItemStacksIdentical(e.getKey(), stack)).map(Map.Entry::getValue).findFirst().orElse(ItemStack.EMPTY); }
private void fill_adjacent_inventory_item_containers(Direction block_facing)
{
// Check inventory existence, back to down is preferred, otherwise sort back into same inventory.
IItemHandler src = ItemHandling.itemhandler(world, pos.offset(block_facing), block_facing.getOpposite());
IItemHandler dst = ItemHandling.itemhandler(world, pos.down(), Direction.UP);
IItemHandler src = Inventories.itemhandler(world, pos.offset(block_facing), block_facing.getOpposite());
IItemHandler dst = Inventories.itemhandler(world, pos.down(), Direction.UP);
if(src==null) { src = dst; } else if(dst==null) { dst = src; }
if((src==null) || (dst==null)) return;
while((tank_level_ >= BUCKET_SIZE)) {
boolean inserted = false;
for(Entry<ItemStack,ItemStack> e:milk_containers_.entrySet()) {
if(ItemHandling.extract(src, e.getKey(), 1, true).isEmpty()) continue;
if(!ItemHandling.insert(dst, e.getValue().copy(), false).isEmpty()) continue;
ItemHandling.extract(src, e.getKey(), 1, false);
if(Inventories.extract(src, e.getKey(), 1, true).isEmpty()) continue;
if(!Inventories.insert(dst, e.getValue().copy(), false).isEmpty()) continue;
Inventories.extract(src, e.getKey(), 1, false);
tank_level_ -= BUCKET_SIZE;
inserted = true;
}

View file

@ -240,7 +240,7 @@ public class BlockDecorMineralSmelter extends StandardBlocks.Horizontal implemen
public static void on_config(int energy_consumption, int heatup_per_second)
{
energy_consumption = MathHelper.clamp(energy_consumption, 32, 4096);
energy_consumption = MathHelper.clamp(energy_consumption, 8, 4096);
heatup_rate = MathHelper.clamp(heatup_per_second, 1, 5);
cooldown_rate = MathHelper.clamp(heatup_per_second/2, 1, 5);
ModEngineersDecor.logger().info("Config mineal smelter energy consumption:" + energy_consumption + "rf/t, heat-up rate: " + heatup_rate + "%/s.");

View file

@ -43,7 +43,7 @@ import javax.annotation.Nullable;
public class BlockDecorPassiveFluidAccumulator extends StandardBlocks.Directed implements IDecorBlock
{
public BlockDecorPassiveFluidAccumulator(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorPassiveFluidAccumulator(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override

View file

@ -63,7 +63,7 @@ public class BlockDecorPipeValve extends StandardBlocks.DirectedWaterLoggable im
ModEngineersDecor.logger().info("Config pipe valve: maxflow:" + BTileEntity.fluid_maxflow_mb + "mb, redstone amp:" + BTileEntity.redstone_flow_slope_mb + "mb/sig");
}
public BlockDecorPipeValve(long config, int valve_config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorPipeValve(long config, int valve_config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); this.valve_config = valve_config; }
private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos)

View file

@ -56,7 +56,7 @@ import java.util.List;
public class BlockDecorPlacer extends StandardBlocks.Directed
{
public BlockDecorPlacer(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorPlacer(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override

View file

@ -78,7 +78,7 @@ public class BlockDecorSolarPanel extends StandardBlocks.BaseBlock
public static void on_config(int peak_power_per_tick)
{
peak_power_per_tick_ = peak_power_per_tick;
peak_power_per_tick_ = MathHelper.clamp(peak_power_per_tick, 2, 8192);
ModEngineersDecor.logger().info("Config small solar panel: Peak production:" + peak_power_per_tick_ + "/tick");
}

View file

@ -41,7 +41,7 @@ public class BlockDecorTreeCutter extends StandardBlocks.Horizontal
{
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public BlockDecorTreeCutter(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorTreeCutter(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@ -100,7 +100,7 @@ public class BlockDecorTreeCutter extends StandardBlocks.Horizontal
public static void on_config(int boost_energy_per_tick, int cutting_time_seconds, boolean power_required)
{
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 4, 4096);
cutting_time_needed = 20 * MathHelper.clamp(cutting_time_seconds, 10, 240);
requires_power = power_required;
ModEngineersDecor.logger().info("Config tree cutter: Boost energy consumption:" + boost_energy_consumption + "rf/t" + (requires_power?" (power required for operation) ":"") + ", cutting time " + cutting_time_needed + "t." );

View file

@ -10,6 +10,8 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import wile.engineersdecor.libmc.detail.Inventories;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
@ -50,7 +52,6 @@ import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import com.mojang.blaze3d.platform.GlStateManager;
import wile.engineersdecor.libmc.blocks.StandardBlocks;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -180,7 +181,7 @@ public class BlockDecorWasteIncinerator extends StandardBlocks.BaseBlock
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick)
{
energy_consumption = MathHelper.clamp(boost_energy_per_tick, 16, 512);
energy_consumption = MathHelper.clamp(boost_energy_per_tick, 4, 4096);
ModEngineersDecor.logger().info("Config waste incinerator boost energy consumption:" + energy_consumption);
}
@ -575,7 +576,7 @@ public class BlockDecorWasteIncinerator extends StandardBlocks.BaseBlock
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
} else if(Inventories.areItemStacksDifferent(from, to)) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {

View file

@ -361,14 +361,14 @@ public class ModConfig
.comment("Defines, in percent, how fast the lab furnace smelts compared to " +
"a vanilla furnace. 100% means vanilla furnace speed, 150% means the " +
"lab furnace is faster. The value can be changed on-the-fly for tuning.")
.defineInRange("furnace_smelting_speed_percent", 130, 50, 500);
.defineInRange("furnace_smelting_speed_percent", 130, 50, 800);
furnace_fuel_efficiency_percent = builder
.translation(ModEngineersDecor.MODID + ".config.furnace_fuel_efficiency_percent")
.comment("Defines, in percent, how fuel efficient the lab furnace is, compared " +
"to a vanilla furnace. 100% means vanilla furnace consumiton, 200% means " +
"the lab furnace needs about half the fuel of a vanilla furnace, " +
"The value can be changed on-the-fly for tuning.")
.defineInRange("furnace_fuel_efficiency_percent", 100, 50, 250);
.defineInRange("furnace_fuel_efficiency_percent", 100, 50, 400);
furnace_boost_energy_consumption = builder
.translation(ModEngineersDecor.MODID + ".config.furnace_boost_energy_consumption")
.comment("Defines the energy consumption (per tick) for speeding up the smelting process. " +
@ -376,7 +376,7 @@ public class ModConfig
"of the lab furnace. The power source needs to be able to provide at least 4 times " +
"this consumption (fixed threshold value). The value can be changed on-the-fly for tuning. " +
"The default value corresponds to the IE heater consumption.")
.defineInRange("furnace_boost_energy_consumption", 24, 16, 256);
.defineInRange("furnace_boost_energy_consumption", 24, 8, 1024);
chair_mob_sitting_probability_percent = builder
.translation(ModEngineersDecor.MODID + ".config.chair_mob_sitting_probability_percent")
.comment("Defines, in percent, how high the probability is that a mob sits on a chair " +
@ -403,27 +403,27 @@ public class ModConfig
"That is technically the 'storage size' specified for blocks that want to fill " +
"fluids into the valve (the valve has no container and forward that to the output " +
"block), The value can be changed on-the-fly for tuning. ")
.defineInRange("pipevalve_max_flowrate", 1000, 1, 10000);
.defineInRange("pipevalve_max_flowrate", 1000, 1, 32000);
pipevalve_redstone_gain = builder
.translation(ModEngineersDecor.MODID + ".config.pipevalve_redstone_gain")
.comment("Defines how many millibuckets per redstone signal strength can be transferred per tick " +
"through the analog redstone controlled valves. Note: power 0 is always off, power 15 is always " +
"the max flow rate. Between power 1 and 14 this scaler will result in a flow = 'redstone slope' * 'current redstone power'. " +
"The value can be changed on-the-fly for tuning. ")
.defineInRange("pipevalve_redstone_gain", 20, 1, 10000);
.defineInRange("pipevalve_redstone_gain", 20, 1, 32000);
e_furnace_speed_percent = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_speed_percent")
.comment("Defines, in percent, how fast the electrical furnace smelts compared to " +
"a vanilla furnace. 100% means vanilla furnace speed, 150% means the " +
"electrical furnace is faster. The value can be changed on-the-fly for tuning.")
.defineInRange("e_furnace_speed_percent", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_SPEED_PERCENT, 50, 500);
.defineInRange("e_furnace_speed_percent", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_SPEED_PERCENT, 50, 800);
e_furnace_power_consumption = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_power_consumption")
.comment("Defines how much RF per tick the the electrical furnace consumed (average) for smelting. " +
"The feeders transferring items from/to adjacent have this consumption/8 for each stack transaction. " +
"The default value is only slightly higher than a furnace with an IE external heater (and no burning fuel inside)." +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("e_furnace_power_consumption", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 10, 256);
.defineInRange("e_furnace_power_consumption", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 8, 4096);
e_furnace_automatic_pulling = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_automatic_pulling")
.comment("Defines if the electrical furnace automatically pulls items from an inventory at the input side." +
@ -435,12 +435,12 @@ public class ModConfig
"Note that the agerage power is much less, as no power is produced at all during the night, " +
"and the power curve is nonlinear rising/falling during the day. Bad weather conditions also " +
"decrease the production. The config value can be changed on-the-fly for tuning.")
.defineInRange("small_solar_panel_peak_production", BlockDecorSolarPanel.BTileEntity.DEFAULT_PEAK_POWER, 10, 256);
.defineInRange("small_solar_panel_peak_production", BlockDecorSolarPanel.BTileEntity.DEFAULT_PEAK_POWER, 2, 4096);
block_breaker_power_consumption = builder
.translation(ModEngineersDecor.MODID + ".config.block_breaker_power_consumption")
.comment("Defines how much RF power the Small Block Breaker requires to magnificently increase the processing speed. " +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("block_breaker_power_consumption", BlockDecorBreaker.BTileEntity.DEFAULT_BOOST_ENERGY, 16, 512);
.defineInRange("block_breaker_power_consumption", BlockDecorBreaker.BTileEntity.DEFAULT_BOOST_ENERGY, 4, 1024);
block_breaker_reluctance = builder
.translation(ModEngineersDecor.MODID + ".config.block_breaker_reluctance")
.comment("Defines how much time the Small Block Breaker needs per block hardness, " +
@ -461,7 +461,7 @@ public class ModConfig
.translation(ModEngineersDecor.MODID + ".config.tree_cuttter_energy_consumption")
.comment("Defines how much RF power the Small Tree Cutter requires to magnificently increase the processing speed. " +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("tree_cuttter_energy_consumption", BlockDecorTreeCutter.BTileEntity.DEFAULT_BOOST_ENERGY, 16, 512);
.defineInRange("tree_cuttter_energy_consumption", BlockDecorTreeCutter.BTileEntity.DEFAULT_BOOST_ENERGY, 4, 1024);
tree_cuttter_cutting_time_needed = builder
.translation(ModEngineersDecor.MODID + ".config.tree_cuttter_cutting_time_needed")
.comment("Defines how much time the Small Tree Cutter needs to cut a tree without RF power. " +
@ -478,7 +478,7 @@ public class ModConfig
"Note this is a permanent standby power, not only when the device does something. " +
"Use zero to disable energy dependency and energy handling of the machine. " +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("milking_machine_energy_consumption", BlockDecorMilker.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 0, 128);
.defineInRange("milking_machine_energy_consumption", BlockDecorMilker.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 0, 1024);
milking_machine_milking_delay = builder
.translation(ModEngineersDecor.MODID + ".config.milking_machine_milking_delay")
.comment("Defines (for each individual cow) the minimum time between milking." )

View file

@ -26,11 +26,9 @@ import net.minecraft.fluid.Fluids;
import net.minecraft.world.IWorld;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
import net.minecraft.util.math.shapes.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.block.material.PushReaction;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.item.ItemStack;
@ -41,12 +39,12 @@ import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
public class StandardBlocks
@ -88,6 +86,14 @@ public class StandardBlocks
public BaseBlock(long conf, Block.Properties properties, VoxelShape voxel_shape)
{ super(properties); config = conf; vshape = voxel_shape; }
public BaseBlock(long conf, Block.Properties properties, AxisAlignedBB[] aabbs)
{
super(properties); config = conf;
VoxelShape shape = VoxelShapes.empty();
for(AxisAlignedBB aabb:aabbs) shape = VoxelShapes.combine(shape, VoxelShapes.create(aabb), IBooleanFunction.OR);
vshape = shape;
}
@Override
@OnlyIn(Dist.CLIENT)
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
@ -206,6 +212,9 @@ public class StandardBlocks
public WaterLoggable(long config, Block.Properties properties, VoxelShape voxel_shape)
{ super(config|CFG_WATERLOGGABLE, properties, voxel_shape); }
public WaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config|CFG_WATERLOGGABLE, properties, aabbs); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
@ -214,25 +223,35 @@ public class StandardBlocks
public static class Directed extends BaseBlock implements IStandardBlock
{
public static final DirectionProperty FACING = DirectionalBlock.FACING;
protected final ArrayList<VoxelShape> AABBs;
protected final ArrayList<VoxelShape> vshapes;
public Directed(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public Directed(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{
super(config, builder);
super(config, properties);
setDefaultState(stateContainer.getBaseState().with(FACING, Direction.UP));
final boolean is_horizontal = ((config & CFG_HORIZIONTAL)!=0);
AABBs = new ArrayList<VoxelShape>(Arrays.asList(
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.DOWN, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.UP, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.NORTH, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.SOUTH, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.WEST, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.EAST, is_horizontal)),
VoxelShapes.create(unrotatedAABB),
VoxelShapes.create(unrotatedAABB)
));
vshapes = shape_supplier.get();
}
public Directed(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABBs)
{
this(config, properties, ()->{
final boolean is_horizontal = ((config & CFG_HORIZIONTAL)!=0);
return new ArrayList<VoxelShape>(Arrays.asList(
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.DOWN, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.UP, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.NORTH, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.SOUTH, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.WEST, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.EAST, is_horizontal)),
VoxelShapes.fullCube(),
VoxelShapes.fullCube()
));
});
}
public Directed(long config, Block.Properties properties, final AxisAlignedBB unrotatedAABB)
{ this(config, properties, new AxisAlignedBB[]{unrotatedAABB}); }
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
@ -249,7 +268,7 @@ public class StandardBlocks
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs.get((state.get(FACING)).getIndex() & 0x7); }
{ return vshapes.get((state.get(FACING)).getIndex() & 0x7); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
@ -285,24 +304,34 @@ public class StandardBlocks
public static class Horizontal extends BaseBlock implements IStandardBlock
{
public static final DirectionProperty HORIZONTAL_FACING = HorizontalBlock.HORIZONTAL_FACING;
protected final ArrayList<VoxelShape> AABBs;
protected final ArrayList<VoxelShape> vshapes;
public Horizontal(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public Horizontal(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{
super(config|CFG_HORIZIONTAL, builder, unrotatedAABB);
super(config|CFG_HORIZIONTAL, properties);
setDefaultState(stateContainer.getBaseState().with(HORIZONTAL_FACING, Direction.NORTH));
AABBs = new ArrayList<VoxelShape>(Arrays.asList(
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.DOWN, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.UP, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.NORTH, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.SOUTH, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.WEST, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.EAST, true)),
VoxelShapes.create(unrotatedAABB),
VoxelShapes.create(unrotatedAABB)
));
vshapes = shape_supplier.get();
}
public Horizontal(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABBs)
{
this(config, properties, ()->{
return new ArrayList<VoxelShape>(Arrays.asList(
VoxelShapes.fullCube(),
VoxelShapes.fullCube(),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.NORTH, true)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.SOUTH, true)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.WEST, true)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.EAST, true)),
VoxelShapes.fullCube(),
VoxelShapes.fullCube()
));
});
}
public Horizontal(long config, Block.Properties properties, final AxisAlignedBB unrotatedAABB)
{ this(config, properties, new AxisAlignedBB[]{unrotatedAABB}); }
@Override
@OnlyIn(Dist.CLIENT)
public BlockRenderLayer getRenderLayer()
@ -319,7 +348,7 @@ public class StandardBlocks
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs.get((state.get(HORIZONTAL_FACING)).getIndex() & 0x7); }
{ return vshapes.get((state.get(HORIZONTAL_FACING)).getIndex() & 0x7); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
@ -362,6 +391,12 @@ public class StandardBlocks
public DirectedWaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config|CFG_WATERLOGGABLE, properties, aabb); }
public DirectedWaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config|CFG_WATERLOGGABLE, properties, aabbs); }
public DirectedWaterLoggable(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config|CFG_WATERLOGGABLE, properties, shape_supplier); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
@ -372,6 +407,12 @@ public class StandardBlocks
public HorizontalWaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config|CFG_WATERLOGGABLE|CFG_HORIZIONTAL, properties, aabb); }
public HorizontalWaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config|CFG_WATERLOGGABLE|CFG_HORIZIONTAL, properties, aabbs); }
public HorizontalWaterLoggable(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config|CFG_WATERLOGGABLE|CFG_HORIZIONTAL, properties, shape_supplier); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }

View file

@ -8,6 +8,7 @@
*/
package wile.engineersdecor.libmc.blocks;
import net.minecraft.util.math.shapes.VoxelShapes;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import net.minecraft.world.*;
import net.minecraft.fluid.IFluidState;
@ -36,11 +37,14 @@ public class StandardFenceBlock extends WallBlock implements StandardBlocks.ISta
private final VoxelShape[] shape_voxels;
private final VoxelShape[] collision_shape_voxels;
public StandardFenceBlock(long config, Block.Properties builder)
public StandardFenceBlock(long config, Block.Properties properties)
{ this(config, properties, 1.5,16, 1.5, 0, 16); }
public StandardFenceBlock(long config, Block.Properties properties, double pole_width, double pole_height, double side_width, double side_max_y, double side_min_y)
{
super(builder);
this.shape_voxels = buildWallShapes(1.5f, 1.5f, 16f, 0f, 16f);
this.collision_shape_voxels = buildWallShapes(1.5f, 1.5f, 24f, 0f, 24f);
super(properties);
this.shape_voxels = buildShapes(pole_width, pole_height, side_width, side_max_y, side_min_y);
this.collision_shape_voxels = buildShapes(pole_width,24, pole_width, 0, 24);
}
@Override
@ -48,8 +52,35 @@ public class StandardFenceBlock extends WallBlock implements StandardBlocks.ISta
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{ Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
protected VoxelShape[] buildWallShapes(float pole_width_x, float pole_width_z, float pole_height, float side_min_y, float side_max_y)
{ return super.makeShapes(pole_width_x, pole_width_z, pole_height, side_min_y, side_max_y); }
protected VoxelShape[] buildShapes(double pole_width, double pole_height, double side_width, double side_min_y, double side_max_y)
{
final double px0=8d-pole_width, px1=8d+pole_width, sx0=8d-side_width, sx1=8d+side_width;
VoxelShape vp = Block.makeCuboidShape(px0, 0, px0, px1, pole_height, px1);
VoxelShape vs1 = Block.makeCuboidShape(sx0, side_min_y, 0, sx1, side_max_y, sx1);
VoxelShape vs2 = Block.makeCuboidShape(sx0, side_min_y, sx0, sx1, side_max_y, 16);
VoxelShape vs3 = Block.makeCuboidShape(0, side_min_y, sx0, sx1, side_max_y, sx1);
VoxelShape vs4 = Block.makeCuboidShape(sx0, side_min_y, sx0, 16, side_max_y, sx1);
VoxelShape vs5 = VoxelShapes.or(vs1, vs4);
VoxelShape vs6 = VoxelShapes.or(vs2, vs3);
return new VoxelShape[] {
vp,
VoxelShapes.or(vp, vs2),
VoxelShapes.or(vp, vs3),
VoxelShapes.or(vp, vs6),
VoxelShapes.or(vp, vs1),
VoxelShapes.or(vs2, vs1),
VoxelShapes.or(vp, VoxelShapes.or(vs3, vs1)),
VoxelShapes.or(vp, VoxelShapes.or(vs6, vs1)),
VoxelShapes.or(vp, vs4),
VoxelShapes.or(vp, VoxelShapes.or(vs2, vs4)),
VoxelShapes.or(vs3, vs4),
VoxelShapes.or(vp, VoxelShapes.or(vs6, vs4)),
VoxelShapes.or(vp, vs5),
VoxelShapes.or(vp, VoxelShapes.or(vs2, vs5)),
VoxelShapes.or(vp, VoxelShapes.or(vs3, vs5)),
VoxelShapes.or(vp, VoxelShapes.or(vs6, vs5))
};
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)

View file

@ -13,6 +13,9 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.SharedConstants;
import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.IBlockReader;
@ -249,6 +252,20 @@ public class Auxiliaries
return bb;
}
public static final AxisAlignedBB[] getRotatedAABB(AxisAlignedBB[] bbs, Direction new_facing, boolean horizontal_rotation)
{
AxisAlignedBB[] transformed = new AxisAlignedBB[bbs.length];
for(int i=0; i<bbs.length; ++i) transformed[i] = getRotatedAABB(bbs[i], new_facing, horizontal_rotation);
return transformed;
}
public static final VoxelShape getUnionShape(AxisAlignedBB[] aabbs)
{
VoxelShape shape = VoxelShapes.empty();
for(AxisAlignedBB aabb: aabbs) shape = VoxelShapes.combine(shape, VoxelShapes.create(aabb), IBooleanFunction.OR);
return shape;
}
@SuppressWarnings("unused")
public static void playerChatMessage(final PlayerEntity player, final String message)
{

View file

@ -1,4 +1,12 @@
package wile.engineersdecor.detail;
/*
* @file Inventories.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* General inventory item handling functionality.
*/
package wile.engineersdecor.libmc.detail;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@ -12,13 +20,20 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import javax.annotation.Nullable;
public class ItemHandling
public class Inventories
{
public static boolean areItemStacksIdentical(ItemStack a, ItemStack b)
{ return (a.getItem()==b.getItem()) && ItemStack.areItemStackTagsEqual(a, b); }
public static boolean areItemStacksDifferent(ItemStack a, ItemStack b)
{ return (a.getItem()!=b.getItem()) || (!ItemStack.areItemStackTagsEqual(a, b)); }
public static IItemHandler itemhandler(World world, BlockPos pos, @Nullable Direction side)
{
TileEntity te = world.getTileEntity(pos);
@ -56,9 +71,9 @@ public class ItemHandling
final ItemStack stack = inventory.getStackInSlot(i);
if(stack.isEmpty()) continue;
if(out_stack.isEmpty()) {
if((match!=null) && (!stack.isItemEqual(match))) continue;
if((match!=null) && Inventories.areItemStacksDifferent(stack, match)) continue;
out_stack = inventory.extractItem(i, amount, simulate);
} else if(stack.isItemEqual(out_stack)) {
} else if(Inventories.areItemStacksIdentical(stack, out_stack)) {
ItemStack es = inventory.extractItem(i, (amount-out_stack.getCount()), simulate);
out_stack.grow(es.getCount());
}
@ -67,4 +82,4 @@ public class ItemHandling
return out_stack;
}
}
}

View file

@ -1,7 +1,7 @@
{
"textures": {
"end": "engineersdecor:block/pipe/passive_fluid_accumulator_front_texture",
"particle": "engineersdecor:block/pipe/passive_fluid_accumulator_front_texture",
"end": "engineersdecor:block/pipe/passive_fluid_accumulator_front_texture",
"side": "engineersdecor:block/pipe/passive_fluid_accumulator_side_texture",
"back": "engineersdecor:block/pipe/passive_fluid_accumulator_back_texture"
},
@ -42,7 +42,7 @@
"scale": [0.35, 0.35, 0.35]
},
"ground": {
"translation": [0, 1.75, 0],
"translation": [0, 1.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {

View file

@ -2,7 +2,7 @@
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx8G
version_minecraft=1.15.2
version_forge_minecraft=1.15.2-31.0.1
version_forge_minecraft=1.15.2-31.1.1
version_fml_mappings=20191105-1.14.3
version_jei=1.15.2:6.0.0.2
version_engineersdecor=1.0.19-b2
version_engineersdecor=1.0.19-b3

View file

@ -1,6 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.15.2": {
"1.0.19-b3": "[M] Config tweaks: Value limit ranges increased to facilitate modpacking.\n[A] Factory Hopper: Added bottom item handler (CR#227).\n[M] Block shapes refined.\n[F] Fixed duping bug (issue #87, thx Nachtflame)",
"1.0.19-b2": "[F] Fixed Floor Grating item pass-through jitters (thx Cid).\n[M] Removed obsolete recipe collision testing recipes.\n[F] Fixed missing Block Breaker dynamic block drops.\n[F] Block Placer planting race condition issue fixed (issue #83, thx jcardii).\n[F] Factory Hopper: Added second standard insertion run after smart-insert to circumcent compat issues (issue #84, thx NillerMedDild).\n[A] Enabled JEI plugin (issue #85, thx ProsperCraft/Goshen).",
"1.0.19-b1": "[U] Update to 1.15.2.\n[F] Fixed Tree Cutter / Block Breaker not accepting small energy transfers (thx WindFox, issue #82).",
"1.0.18-b4": "[A] Ported Treated Wood Crafting Table item rendering.\n[F] Fixed Milking machine cow path issue, added milking delay cow tracking.\n[F] Slab / Slab Slice placement adapted to vanilla standard.\n[M] Lang update ru_ru (PR#77, thanks Smollet777).",
@ -11,6 +12,6 @@
},
"promos": {
"1.15.2-recommended": "",
"1.15.2-latest": "1.0.19-b2"
"1.15.2-latest": "1.0.19-b3"
}
}

View file

@ -11,6 +11,11 @@ Mod sources for Minecraft version 1.15.1.
## Version history
- v1.0.19-b3 [M] Config tweaks: Value limit ranges increased to facilitate modpacking.
[A] Factory Hopper: Added bottom item handler (CR#227).
[M] Block shapes refined.
[F] Fixed duping bug (issue #87, thx Nachtflame)
- v1.0.19-b2 [F] Fixed Floor Grating item pass-through jitters (thx Cid).
[M] Removed obsolete recipe collision testing recipes.
[F] Fixed missing Block Breaker dynamic block drops.

View file

@ -27,6 +27,10 @@ import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraft.inventory.container.ContainerType;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.client.gui.ScreenManager;
@ -38,6 +42,7 @@ import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import org.apache.commons.lang3.ArrayUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Collections;
import javax.annotation.Nonnull;
@ -226,7 +231,12 @@ public class ModContent
public static final BlockDecorChair TREATED_WOOD_STOOL = (BlockDecorChair)(new BlockDecorChair(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(2f, 15f).sound(SoundType.WOOD),
Auxiliaries.getPixeledAABB(4.1,0,4.1, 11.8,8.8,11.8)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(4,7,4, 12,8.8,12),
Auxiliaries.getPixeledAABB(7,0,7, 9,7,9),
Auxiliaries.getPixeledAABB(4,0,7, 12,1,9),
Auxiliaries.getPixeledAABB(7,0,4, 9,1,12),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_stool"));
public static final BlockDecor.WaterLoggable TREATED_WOOD_SIDE_TABLE = (BlockDecor.WaterLoggable)(new BlockDecor.WaterLoggable(
@ -268,7 +278,7 @@ public class ModContent
public static final BlockDecorFloorGrating STEEL_FLOOR_GRATING = (BlockDecorFloorGrating)(new BlockDecorFloorGrating(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(0,14,0, 16,15.9,16)
Auxiliaries.getPixeledAABB(0,14,0, 16,15.5,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "steel_floor_grating"));
// -------------------------------------------------------------------------------------------------------------------
@ -378,19 +388,31 @@ public class ModContent
public static final BlockDecorCraftingTable.CraftingTableBlock TREATED_WOOD_CRAFTING_TABLE = (BlockDecorCraftingTable.CraftingTableBlock)(new BlockDecorCraftingTable.CraftingTableBlock(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.WOOD, MaterialColor.WOOD).hardnessAndResistance(1f, 15f).sound(SoundType.WOOD),
Auxiliaries.getPixeledAABB(1,0,1, 15,15.9,15)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(0,13,0, 16,16,16),
Auxiliaries.getPixeledAABB(1, 0,1, 15,13,15)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "treated_wood_crafting_table"));
public static final BlockDecorFurnace SMALL_LAB_FURNACE = (BlockDecorFurnace)(new BlockDecorFurnace(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(1f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(1,0,1, 15,15,16.0)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(1,0,1, 15, 1,15),
Auxiliaries.getPixeledAABB(0,1,1, 16,16,16),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_lab_furnace"));
public static final BlockDecorFurnaceElectrical SMALL_ELECTRICAL_FURNACE = (BlockDecorFurnaceElectrical)(new BlockDecorFurnaceElectrical(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(0, 0,0, 16,11,16),
Auxiliaries.getPixeledAABB(1,11,0, 15,12,16),
Auxiliaries.getPixeledAABB(2,12,0, 14,13,16),
Auxiliaries.getPixeledAABB(3,13,0, 13,14,16),
Auxiliaries.getPixeledAABB(4,14,0, 12,16,16),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_electrical_furnace"));
public static final BlockDecorDropper FACTORY_DROPPER = (BlockDecorDropper)(new BlockDecorDropper(
@ -402,19 +424,70 @@ public class ModContent
public static final BlockDecorPlacer FACTORY_PLACER = (BlockDecorPlacer)(new BlockDecorPlacer(
BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(2,2,2, 14,14,14)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(0,0,2, 16,16,16),
Auxiliaries.getPixeledAABB( 0,0,0, 1,16, 2),
Auxiliaries.getPixeledAABB(15,0,0,16,16, 2)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "factory_placer"));
public static final BlockDecorBreaker SMALL_BLOCK_BREAKER = (BlockDecorBreaker)(new BlockDecorBreaker(
BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(0,0,0, 16,12,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(1,0,0, 15, 4, 7),
Auxiliaries.getPixeledAABB(1,0,7, 15,12,16),
Auxiliaries.getPixeledAABB(0,0,0, 1, 5, 4),
Auxiliaries.getPixeledAABB(0,0,4, 1,12,16),
Auxiliaries.getPixeledAABB(15,0,0, 16, 5, 4),
Auxiliaries.getPixeledAABB(15,0,4, 16,12,16)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_block_breaker"));
public static final BlockDecorHopper FACTORY_HOPPER = (BlockDecorHopper)(new BlockDecorHopper(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,16)
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),()->{
final AxisAlignedBB[] down_aabbs = new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 5, 0, 5, 11, 1,11),
Auxiliaries.getPixeledAABB( 4, 1, 4, 12, 7,12),
Auxiliaries.getPixeledAABB( 2, 7, 2, 14,10,14),
Auxiliaries.getPixeledAABB( 0,10, 0, 16,16,16),
Auxiliaries.getPixeledAABB( 0, 4, 5, 2,10,11),
Auxiliaries.getPixeledAABB(14, 4, 5, 16,10,11),
Auxiliaries.getPixeledAABB( 5, 4, 0, 11,10, 2),
Auxiliaries.getPixeledAABB( 5, 4,14, 11,10,16),
};
final AxisAlignedBB[] up_aabbs = new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 5,15, 5, 11,16,11),
Auxiliaries.getPixeledAABB( 4,14, 4, 12, 9,12),
Auxiliaries.getPixeledAABB( 2, 9, 2, 14, 6,14),
Auxiliaries.getPixeledAABB( 0, 6, 0, 16, 0,16),
Auxiliaries.getPixeledAABB( 0,12, 5, 2, 6,11),
Auxiliaries.getPixeledAABB(14,12, 5, 16, 6,11),
Auxiliaries.getPixeledAABB( 5,12, 0, 11, 6, 2),
Auxiliaries.getPixeledAABB( 5,12,14, 11, 6,16),
};
final AxisAlignedBB[] north_aabbs = new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 5, 0, 5, 11, 1,11),
Auxiliaries.getPixeledAABB( 4, 1, 4, 12, 7,12),
Auxiliaries.getPixeledAABB( 2, 7, 2, 14,10,14),
Auxiliaries.getPixeledAABB( 0,10, 0, 16,16,16),
Auxiliaries.getPixeledAABB( 0, 4, 5, 2,10,11),
Auxiliaries.getPixeledAABB(14, 4, 5, 16,10,11),
Auxiliaries.getPixeledAABB( 5, 1, 0, 11, 7, 4),
Auxiliaries.getPixeledAABB( 5, 4,14, 11,10,16),
};
return new ArrayList<VoxelShape>(Arrays.asList(
Auxiliaries.getUnionShape(down_aabbs),
Auxiliaries.getUnionShape(up_aabbs),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(north_aabbs, Direction.NORTH, false)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(north_aabbs, Direction.SOUTH, false)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(north_aabbs, Direction.WEST, false)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(north_aabbs, Direction.EAST, false)),
VoxelShapes.fullCube(),
VoxelShapes.fullCube()
));
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "factory_hopper"));
public static final BlockDecorWasteIncinerator SMALL_WASTE_INCINERATOR = (BlockDecorWasteIncinerator)(new BlockDecorWasteIncinerator(
@ -438,46 +511,81 @@ public class ModContent
public static final BlockDecorMilker SMALL_MILKING_MACHINE = (BlockDecorMilker)(new BlockDecorMilker(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,13)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 1, 1,0, 15,14,10),
Auxiliaries.getPixeledAABB( 0,14,0, 16,16,13),
Auxiliaries.getPixeledAABB( 0, 0,0, 16, 1,13),
Auxiliaries.getPixeledAABB( 0, 1,1, 1,14,11),
Auxiliaries.getPixeledAABB(15, 1,1, 16,14,11)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_milking_machine"));
public static final BlockDecorTreeCutter SMALL_TREE_CUTTER = (BlockDecorTreeCutter)(new BlockDecorTreeCutter(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(0,0,0, 16,8,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB( 0,0, 0, 16,3,16),
Auxiliaries.getPixeledAABB( 0,3, 0, 3,8,16),
Auxiliaries.getPixeledAABB( 3,7, 0, 5,8,16),
Auxiliaries.getPixeledAABB(15,0, 0, 16,6,16),
Auxiliaries.getPixeledAABB( 0,0,13, 16,8,16),
Auxiliaries.getPixeledAABB( 5,6,12, 16,8,13),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_tree_cutter"));
public static final BlockDecorPipeValve STRAIGHT_CHECK_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_CHECK_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(4,4,0, 12,12,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(2,2, 0, 14,14, 2),
Auxiliaries.getPixeledAABB(2,2,14, 14,14,16),
Auxiliaries.getPixeledAABB(3,3, 5, 13,13,11),
Auxiliaries.getPixeledAABB(4,4, 2, 12,12,14),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_REDSTONE_CONTROLLED_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(4,4,0, 12,12,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(2,2, 0, 14,14, 2),
Auxiliaries.getPixeledAABB(2,2,14, 14,14,16),
Auxiliaries.getPixeledAABB(3,3, 5, 13,13,11),
Auxiliaries.getPixeledAABB(4,4, 2, 12,12,14),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve_redstone"));
public static final BlockDecorPipeValve STRAIGHT_REDSTONE_ANALOG_VALVE = (BlockDecorPipeValve)(new BlockDecorPipeValve(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockDecorPipeValve.CFG_REDSTONE_CONTROLLED_VALVE|BlockDecorPipeValve.CFG_ANALOG_VALVE,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(4,4,0, 12,12,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(2,2, 0, 14,14, 2),
Auxiliaries.getPixeledAABB(2,2,14, 14,14,16),
Auxiliaries.getPixeledAABB(3,3, 5, 13,13,11),
Auxiliaries.getPixeledAABB(4,4, 2, 12,12,14),
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "straight_pipe_valve_redstone_analog"));
public static final BlockDecorPassiveFluidAccumulator PASSIVE_FLUID_ACCUMULATOR = (BlockDecorPassiveFluidAccumulator)(new BlockDecorPassiveFluidAccumulator(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(3,3,0, 13,13, 1),
Auxiliaries.getPixeledAABB(0,0,1, 16,16,16)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "passive_fluid_accumulator"));
public static final BlockDecorFluidFunnel SMALL_FLUID_FUNNEL = (BlockDecorFluidFunnel)(new BlockDecorFluidFunnel(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL).func_226896_b_(),
Auxiliaries.getPixeledAABB(0,0,0, 16,16,16)
new AxisAlignedBB[]{
Auxiliaries.getPixeledAABB(0, 0,0, 16,14,16),
Auxiliaries.getPixeledAABB(1,14,1, 15,15,15),
Auxiliaries.getPixeledAABB(0,15,0, 16,16,16)
}
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "small_fluid_funnel"));
// -------------------------------------------------------------------------------------------------------------------
@ -526,7 +634,8 @@ public class ModContent
public static final BlockDecorFence STEEL_MESH_FENCE = (BlockDecorFence)(new BlockDecorFence(
BlockDecor.CFG_CUTOUT,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL)
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
1.5, 16, 0.25, 0, 16
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "steel_mesh_fence"));
// -------------------------------------------------------------------------------------------------------------------

View file

@ -20,6 +20,9 @@ import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.block.Block;
import java.util.ArrayList;
import java.util.function.Supplier;
public class BlockDecor extends StandardBlocks.BaseBlock implements IDecorBlock
{
@ -46,6 +49,9 @@ public class BlockDecor extends StandardBlocks.BaseBlock implements IDecorBlock
public BlockDecor(long conf, Block.Properties properties, VoxelShape voxel_shape)
{ super(conf, properties, voxel_shape); }
public BlockDecor(long conf, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(conf, properties, aabbs); }
public static class WaterLoggable extends StandardBlocks.WaterLoggable implements IStandardBlock, IWaterLoggable
{
public WaterLoggable(long config, Block.Properties properties)
@ -60,25 +66,49 @@ public class BlockDecor extends StandardBlocks.BaseBlock implements IDecorBlock
public static class Directed extends StandardBlocks.Directed implements IDecorBlock
{
public Directed(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public Directed(long config, Block.Properties properties, final AxisAlignedBB unrotatedAABB)
{ super(config, properties, unrotatedAABB); }
public Directed(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, properties, unrotatedAABBs); }
public Directed(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, properties, shape_supplier); }
}
public static class DirectedWaterLoggable extends StandardBlocks.DirectedWaterLoggable implements IDecorBlock,IWaterLoggable
{
public DirectedWaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config, properties, aabb); }
public DirectedWaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config, properties, aabbs); }
public DirectedWaterLoggable(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, properties, shape_supplier); }
}
public static class Horizontal extends StandardBlocks.Horizontal implements IDecorBlock
{
public Horizontal(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public Horizontal(long config, Block.Properties properties, final AxisAlignedBB unrotatedAABB)
{ super(config, properties, unrotatedAABB); }
public Horizontal(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, properties, unrotatedAABBs); }
public Horizontal(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, properties, shape_supplier); }
}
public static class HorizontalWaterLoggable extends StandardBlocks.HorizontalWaterLoggable implements IWaterLoggable
{
public HorizontalWaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config, properties, aabb); }
public HorizontalWaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config, properties, aabbs); }
public HorizontalWaterLoggable(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, properties, shape_supplier); }
}
}

View file

@ -44,8 +44,8 @@ public class BlockDecorBreaker extends BlockDecor.HorizontalWaterLoggable implem
{
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public BlockDecorBreaker(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public BlockDecorBreaker(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
@ -130,7 +130,7 @@ public class BlockDecorBreaker extends BlockDecor.HorizontalWaterLoggable implem
public static void on_config(int boost_energy_per_tick, int breaking_time_per_hardness, int min_breaking_time_ticks, boolean power_required)
{
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 4, 4096);
breaking_reluctance = MathHelper.clamp(breaking_time_per_hardness, 5, 50);
min_breaking_time = MathHelper.clamp(min_breaking_time_ticks, 10, 100);
requires_power = power_required;

View file

@ -42,8 +42,8 @@ public class BlockDecorChair extends BlockDecor.HorizontalWaterLoggable
ModEngineersDecor.logger().info("Config chairs: " + sitting_enabled + ", sit: " + sitting_probability, ", stand up: " + standup_probability);
}
public BlockDecorChair(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder.tickRandomly(), unrotatedAABB); }
public BlockDecorChair(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder.tickRandomly(), unrotatedAABBs); }
@Override
@SuppressWarnings("deprecation")

View file

@ -8,10 +8,10 @@
*/
package wile.engineersdecor.blocks;
import net.minecraft.item.crafting.*;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.inventory.container.*;
import net.minecraft.network.play.server.SSetSlotPacket;
@ -29,6 +29,7 @@ import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.*;
import net.minecraft.inventory.*;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.*;
@ -79,8 +80,8 @@ public class BlockDecorCraftingTable
public static final class CraftingTableBlock extends BlockDecor.HorizontalWaterLoggable implements IDecorBlock
{
public CraftingTableBlock(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public CraftingTableBlock(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
@Override
public boolean hasTileEntity(BlockState state)
@ -568,7 +569,7 @@ public class BlockDecorCraftingTable
if(nbt.contains("move-all")) {
for(int i=0; i < player.inventory.getSizeInventory(); ++i) {
final ItemStack stack = player.inventory.getStackInSlot(i);
if(!reference_stack.isItemEqual(stack)) continue;
if(!Inventories.areItemStacksIdentical(reference_stack, stack)) continue;
if(distribute_stack(player.inventory, i) == PlacementResult.UNCHANGED) break; // grid is full
}
}
@ -605,7 +606,7 @@ public class BlockDecorCraftingTable
boolean abort = false;
for(int i=0; (i < from_inventory.getSizeInventory()) && (!abort); ++i) {
final ItemStack stack = from_inventory.getStackInSlot(i);
if(!reference_stack.isItemEqual(stack)) continue;
if(Inventories.areItemStacksDifferent(reference_stack, stack)) continue;
ItemStack remaining = from_inventory.getStackInSlot(i);
for(SlotRange range:to_ranges) {
remaining = move_stack_to_inventory(remaining, range, false, 0);
@ -727,7 +728,7 @@ public class BlockDecorCraftingTable
for(SlotRange range: search_ranges) {
for(int i=0; i<range.inventory.getSizeInventory(); ++i) {
ItemStack stack = range.inventory.getStackInSlot(i);
if(stack.isItemEqual(match_stack)) return match_stack;
if(Inventories.areItemStacksIdentical(stack, match_stack)) return match_stack;
}
}
return not_found_value;
@ -786,7 +787,7 @@ public class BlockDecorCraftingTable
if(to_replace.isEmpty() || (!search_inventory(to_replace, ItemStack.EMPTY).isEmpty())) continue; // no replacement needed
for(int ingredient_index=0; ingredient_index<recipe.getIngredients().size(); ++ingredient_index) {
ItemStack[] match_stacks = recipe.getIngredients().get(ingredient_index).getMatchingStacks();
if(Arrays.stream(match_stacks).anyMatch(s->s.isItemEqual(to_replace))) {
if(Arrays.stream(match_stacks).anyMatch(s->Inventories.areItemStacksIdentical(s, to_replace))) {
replacement = search_inventory(match_stacks, to_replace);
changed = true;
break;
@ -935,7 +936,7 @@ public class BlockDecorCraftingTable
for(int i = slot_begin+1; i < slot_end-1; ++i) {
final ItemStack stack = inventory.getStackInSlot(i);
if(!stack.isEmpty()) continue;
if((!inventory.getStackInSlot(i+1).isItemEqual(mvstack)) && (!inventory.getStackInSlot(i-1).isItemEqual(mvstack))) continue;
if((Inventories.areItemStacksDifferent(inventory.getStackInSlot(i+1), mvstack)) && (Inventories.areItemStacksDifferent(inventory.getStackInSlot(i-1), mvstack))) continue;
int nmax = Math.min(limit_left, mvstack.getCount());
ItemStack placed = mvstack.copy();
placed.setCount(nmax);
@ -975,17 +976,14 @@ public class BlockDecorCraftingTable
int smallest_stack_index = -1;
for(int i = slot_begin; i < slot_end; ++i) {
final ItemStack stack = inventory.getStackInSlot(i);
if((!stack.isEmpty()) && (stack.isItemEqual(request_stack))) {
// Never automatically place stuff with nbt (except a few allowed like "Damage"),
// as this could be a full crate, a valuable tool item, etc. For these recipes
// the user has to place this item manually.
if((!stack.isEmpty()) && (Inventories.areItemStacksIdentical(stack, request_stack))) {
if(stack.hasTag()) {
final CompoundNBT nbt = stack.getTag();
int n = nbt.size();
if((n > 0) && (nbt.contains("Damage"))) --n;
if(n > 0) continue;
}
fetched_stack = stack.copy(); // copy exact stack with nbt and tool damage, otherwise we have an automagical repair of items.
fetched_stack = stack.copy();
fetched_stack.setCount(0);
int n = stack.getCount();
if((n < smallest_stack_size) || (smallest_stack_size <= 0)) {
@ -1096,12 +1094,12 @@ public class BlockDecorCraftingTable
for(int i=0; i<9; ++i) {
final ItemStack grid_stack = inventory_.getStackInSlot(i+CRAFTING_SLOTS_BEGIN);
final ItemStack refab_stack = to_refab.isEmpty() ? ItemStack.EMPTY : to_refab.get(i).copy();
if((!grid_stack.isEmpty()) && (grid_stack.isItemEqual(to_distribute))) {
if((!grid_stack.isEmpty()) && Inventories.areItemStacksIdentical(grid_stack, to_distribute)) {
matching_grid_stack_sizes[i] = grid_stack.getCount();
total_num_missing_stacks += grid_stack.getMaxStackSize()-grid_stack.getCount();
if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i];
if(min_matching_stack_size > matching_grid_stack_sizes[i]) min_matching_stack_size = matching_grid_stack_sizes[i];
} else if((!refab_stack.isEmpty()) && (refab_stack.isItemEqual(to_distribute))) {
} else if((!refab_stack.isEmpty()) && (Inventories.areItemStacksIdentical(refab_stack, to_distribute))) {
matching_grid_stack_sizes[i] = 0;
total_num_missing_stacks += grid_stack.getMaxStackSize();
if(max_matching_stack_size < matching_grid_stack_sizes[i]) max_matching_stack_size = matching_grid_stack_sizes[i];

View file

@ -10,6 +10,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.inventory.container.INamedContainerProvider;
@ -561,7 +562,7 @@ public class BlockDecorDropper extends BlockDecor.Directed implements IDecorBloc
int slot = drop_slot_index_;
for(int i=INPUT_SLOTS_FIRST; i<(INPUT_SLOTS_FIRST+INPUT_SLOTS_SIZE); ++i) {
final ItemStack inp_stack = stacks_.get(slot);
if(!inp_stack.isItemEqual(cmp_stack)) { slot = next_slot(slot); continue; }
if(Inventories.areItemStacksDifferent(inp_stack, cmp_stack)) { slot = next_slot(slot); continue; }
inventory_item_count += inp_stack.getCount();
if(inventory_item_count < cmp_stack_count) { slot = next_slot(slot); continue; }
filter_matches_[ci] = 2;
@ -626,7 +627,7 @@ public class BlockDecorDropper extends BlockDecor.Directed implements IDecorBloc
int ntoremove = drop_stacks[fi].getCount();
for(int i=INPUT_SLOTS_SIZE-1; (i>=0) && (ntoremove>0); --i) {
ItemStack stack = stacks_.get(i);
if(!stack.isItemEqual(drop_stacks[fi])) continue;
if(Inventories.areItemStacksDifferent(stack, drop_stacks[fi])) continue;
if(stack.getCount() <= ntoremove) {
ntoremove -= stack.getCount();
stacks_.set(i, ItemStack.EMPTY);

View file

@ -14,6 +14,9 @@ import net.minecraft.block.*;
public class BlockDecorFence extends StandardFenceBlock implements IDecorBlock
{
public BlockDecorFence(long config, Block.Properties builder)
{ super(config, builder); }
public BlockDecorFence(long config, Block.Properties properties)
{ super(config, properties); }
public BlockDecorFence(long config, Block.Properties properties, double pole_width, double pole_height, double side_width, double side_max_y, double side_min_y)
{ super(config, properties, pole_width, pole_height, side_width, side_max_y, side_min_y); }
}

View file

@ -47,7 +47,7 @@ public class BlockDecorFluidFunnel extends BlockDecor implements IDecorBlock
public static final int FILL_LEVEL_MAX = 3;
public static final IntegerProperty FILL_LEVEL = IntegerProperty.create("level", 0, FILL_LEVEL_MAX);
public BlockDecorFluidFunnel(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorFluidFunnel(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@ -142,7 +142,7 @@ public class BlockDecorFluidFunnel extends BlockDecor implements IDecorBlock
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, ICapabilityProvider
public static class BTileEntity extends TileEntity implements ITickableTileEntity, ICapabilityProvider, IFluidTank
{
public static final int TANK_CAPACITY = 3000;
public static final int TICK_INTERVAL = 10; // ca 500ms
@ -201,24 +201,8 @@ public class BlockDecorFluidFunnel extends BlockDecor implements IDecorBlock
@Override public int getTankCapacity(int tank) { return TANK_CAPACITY; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return true; }
@Override public int fill(FluidStack resource, FluidAction action) { return 0; }
@Override public FluidStack drain(FluidStack resource, FluidAction action)
{
if((resource==null) || (te.tank_.isEmpty())) return FluidStack.EMPTY;
return (!(te.tank_.isFluidEqual(resource))) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action);
}
@Override public FluidStack drain(int maxDrain, FluidAction action)
{
if(te.tank_.isEmpty()) return FluidStack.EMPTY;
FluidStack res = te.tank_.copy();
maxDrain = MathHelper.clamp(maxDrain ,0 , te.tank_.getAmount());
res.setAmount(maxDrain);
if(action != FluidAction.EXECUTE) return res;
te.tank_.setAmount(te.tank_.getAmount()-maxDrain);
if(te.tank_.getAmount() <= 0) te.tank_ = FluidStack.EMPTY;
return res;
}
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return te.drain(resource, action); }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return te.drain(maxDrain, action); }
}
private final LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> new OutputFluidHandler(this));
@ -230,6 +214,51 @@ public class BlockDecorFluidFunnel extends BlockDecor implements IDecorBlock
return super.getCapability(capability, facing);
}
// IFluidTank ------------------------------------------------------------------------------------------
@Override
@Nonnull
public FluidStack getFluid()
{ return tank_.copy(); }
@Override
public int getFluidAmount()
{ return tank_.getAmount(); }
@Override
public int getCapacity()
{ return TANK_CAPACITY; }
@Override
public boolean isFluidValid(FluidStack stack)
{ return true; }
@Override
public int fill(FluidStack resource, FluidAction action)
{ return 0; }
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action)
{
if((resource==null) || (tank_.isEmpty())) return FluidStack.EMPTY;
return (!(tank_.isFluidEqual(resource))) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action);
}
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action)
{
if(tank_.isEmpty()) return FluidStack.EMPTY;
FluidStack res = tank_.copy();
maxDrain = MathHelper.clamp(maxDrain ,0 , tank_.getAmount());
res.setAmount(maxDrain);
if(action != FluidAction.EXECUTE) return res;
tank_.setAmount(tank_.getAmount()-maxDrain);
if(tank_.getAmount() <= 0) tank_ = FluidStack.EMPTY;
return res;
}
// ITickableTileEntity --------------------------------------------------------------------------------
private IFluidState get_fluidstate(BlockPos pos)

View file

@ -11,6 +11,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ExtItems;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.tileentity.*;
import net.minecraft.inventory.container.*;
@ -67,11 +68,8 @@ public class BlockDecorFurnace extends BlockDecor.Horizontal
{
public static final BooleanProperty LIT = RedstoneTorchBlock.LIT;
public BlockDecorFurnace(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{
super(config, builder, unrotatedAABB);
setDefaultState(super.getDefaultState().with(LIT, false));
}
public BlockDecorFurnace(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABB)
{ super(config, properties, unrotatedAABB); setDefaultState(super.getDefaultState().with(LIT, false)); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
@ -215,7 +213,7 @@ public class BlockDecorFurnace extends BlockDecor.Horizontal
{
proc_speed_ = ((double)MathHelper.clamp(speed_percent, 10, 500)) / 100;
proc_fuel_efficiency_ = ((double) MathHelper.clamp(fuel_efficiency_percent, 10, 500)) / 100;
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 4, 4096);
ModEngineersDecor.logger().info("Config lab furnace speed:" + (proc_speed_*100) + "%, efficiency:" + (proc_fuel_efficiency_*100) + "%");
}
@ -350,7 +348,7 @@ public class BlockDecorFurnace extends BlockDecor.Horizontal
public void setInventorySlotContents(int index, ItemStack stack)
{
ItemStack slot_stack = stacks_.get(index);
boolean already_in_slot = (!stack.isEmpty()) && (stack.isItemEqual(slot_stack)) && (ItemStack.areItemStackTagsEqual(stack, slot_stack));
boolean already_in_slot = (!stack.isEmpty()) && (Inventories.areItemStacksIdentical(stack, slot_stack));
stacks_.set(index, stack);
if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit());
if((index == SMELTING_INPUT_SLOT_NO) && (!already_in_slot)) {
@ -624,7 +622,7 @@ public class BlockDecorFurnace extends BlockDecor.Horizontal
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
} else if(Inventories.areItemStacksDifferent(from, to)) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {

View file

@ -10,6 +10,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.inventory.container.*;
import net.minecraft.item.crafting.AbstractCookingRecipe;
@ -51,7 +52,6 @@ import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import com.mojang.blaze3d.systems.RenderSystem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Random;
@ -59,8 +59,8 @@ import java.util.Random;
public class BlockDecorFurnaceElectrical extends BlockDecorFurnace implements IDecorBlock
{
public BlockDecorFurnaceElectrical(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public BlockDecorFurnaceElectrical(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
@Override
@Nullable
@ -137,7 +137,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace implements ID
public static void on_config(int speed_percent, int standard_energy_per_tick, boolean with_automatic_inventory_pulling)
{
proc_speed_percent_ = MathHelper.clamp(speed_percent, 10, 500);
energy_consumption_ = MathHelper.clamp(standard_energy_per_tick, 10, 256) * HEAT_INCREMENT * proc_speed_percent_ / 100;
energy_consumption_ = MathHelper.clamp(standard_energy_per_tick, 4, 4096) * HEAT_INCREMENT * proc_speed_percent_ / 100;
transfer_energy_consumption_ = MathHelper.clamp(energy_consumption_ / 8, 8, HEAT_INCREMENT);
with_automatic_inventory_pulling_ = with_automatic_inventory_pulling;
ModEngineersDecor.logger().info("Config electrical furnace speed:" + proc_speed_percent_ + ", power consumption:" + energy_consumption_);
@ -514,7 +514,7 @@ public class BlockDecorFurnaceElectrical extends BlockDecorFurnace implements ID
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
} else if(Inventories.areItemStacksDifferent(from, to)) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {

View file

@ -10,6 +10,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.libmc.detail.Networking;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
@ -33,6 +34,7 @@ import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.util.*;
import net.minecraft.util.math.*;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.text.*;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
@ -48,12 +50,13 @@ import com.mojang.blaze3d.systems.RenderSystem;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
{
public BlockDecorHopper(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public BlockDecorHopper(long config, Block.Properties builder, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, builder, shape_supplier); }
@Override
@SuppressWarnings("deprecation")
@ -394,7 +397,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
// ISidedInventory --------------------------------------------------------------------------------------
LazyOptional<? extends IItemHandler>[] item_handlers = SidedInvWrapper.create(this, Direction.UP);
LazyOptional<? extends IItemHandler>[] item_handlers = SidedInvWrapper.create(this, Direction.UP, Direction.DOWN);
private static final int[] SIDED_INV_SLOTS;
static {
SIDED_INV_SLOTS = new int[NUM_OF_SLOTS];
@ -419,7 +422,10 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) {
if(facing == Direction.UP) return item_handlers[0].cast();
if(facing == Direction.DOWN) return item_handlers[1].cast();
}
}
return super.getCapability(capability, facing);
}
@ -437,7 +443,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
for(int i=0; i<stacks_.size(); ++i) {
final ItemStack slotstack = stacks_.get(i);
if((first_empty_slot < 0) && slotstack.isEmpty()) { first_empty_slot=i; continue; }
if(!stack.isItemEqual(slotstack)) continue;
if(Inventories.areItemStacksDifferent(stack, slotstack)) continue;
int nspace = slotstack.getMaxStackSize() - slotstack.getCount();
if(nspace <= 0) {
continue;
@ -490,7 +496,7 @@ public class BlockDecorHopper extends BlockDecor.Directed implements IDecorBlock
// First stack comletion insert run.
for(int i=0; i<ih.getSlots(); ++i) {
final ItemStack target_stack = ih.getStackInSlot(i);
if(!target_stack.isItemEqual(insert_stack)) continue;
if(Inventories.areItemStacksDifferent(target_stack, insert_stack)) continue;
insert_stack = ih.insertItem(i, insert_stack.copy(), false);
if(insert_stack.isEmpty()) break;
}

View file

@ -8,10 +8,10 @@
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.libmc.detail.Inventories;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.detail.ExtItems;
import wile.engineersdecor.detail.ItemHandling;
import net.minecraft.world.World;
import net.minecraft.world.IWorldReader;
import net.minecraft.world.IBlockReader;
@ -40,12 +40,12 @@ import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
import net.minecraftforge.fluids.IFluidTank;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
@ -58,8 +58,8 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
public static final BooleanProperty FILLED = BooleanProperty.create("filled");
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public BlockDecorMilker(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public BlockDecorMilker(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
@ -133,7 +133,7 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, IEnergyStorage, ICapabilityProvider
public static class BTileEntity extends TileEntity implements ITickableTileEntity, IEnergyStorage, IFluidTank, ICapabilityProvider
{
public static final int BUCKET_SIZE = 1000;
public static final int TICK_INTERVAL = 80;
@ -145,10 +145,11 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
public static final int MAX_ENERGY_TRANSFER = 512;
public static final int DEFAULT_ENERGY_CONSUMPTION = 0;
public static final int DEFAULT_MILKING_DELAY_PER_COW = 4000;
private static final FluidStack NO_MILK_FLUID = new FluidStack(Fluids.WATER, 0);
private static final Direction FLUID_TRANSFER_DIRECTRIONS[] = {Direction.DOWN,Direction.EAST,Direction.SOUTH,Direction.WEST,Direction.NORTH};
private enum MilkingState { IDLE, PICKED, COMING, POSITIONING, MILKING, LEAVING, WAITING }
private static FluidStack milk_fluid_ = new FluidStack(Fluids.WATER, 0);
private static FluidStack milk_fluid_ = NO_MILK_FLUID;
private static HashMap<ItemStack, ItemStack> milk_containers_ = new HashMap<>();
private static int energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
private static long min_milking_delay_per_cow_ticks = DEFAULT_MILKING_DELAY_PER_COW;
@ -163,7 +164,7 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
public static void on_config(int energy_consumption_per_tick, int min_milking_delay_per_cow)
{
energy_consumption = MathHelper.clamp(energy_consumption_per_tick, 0, 128);
energy_consumption = MathHelper.clamp(energy_consumption_per_tick, 0, 1024);
min_milking_delay_per_cow_ticks = MathHelper.clamp(min_milking_delay_per_cow, 1000, 24000);
{
Fluid milk = null; // FluidRe.getFluid("milk");
@ -257,7 +258,7 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
return n;
}
// IFluidHandler / IFluidTankProperties ---------------------------------------------------------------------
// IFluidHandler ---------------------------------------------------------------------------------------
private LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> (IFluidHandler)new BFluidHandler(this));
@ -266,24 +267,54 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
private final BTileEntity te;
BFluidHandler(BTileEntity te) { this.te = te; }
@Override public int getTanks() { return 1; }
@Override public FluidStack getFluidInTank(int tank) { return new FluidStack(milk_fluid_, te.fluid_level()); }
@Override public int getTankCapacity(int tank) { return TANK_CAPACITY; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return false; }
@Override public FluidStack getFluidInTank(int tank) { return te.getFluid(); }
@Override public int getTankCapacity(int tank) { return te.getCapacity(); }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return te.isFluidValid(stack); }
@Override public int fill(FluidStack resource, FluidAction action) { return 0; }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return te.drain(resource, action); }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return te.drain(maxDrain, action); }
}
@Override
public FluidStack drain(FluidStack resource, FluidAction action)
{ return (!resource.isFluidEqual(milk_fluid_)) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action); }
// IFluidTank ------------------------------------------------------------------------------------------
@Override
public FluidStack drain(int maxDrain, FluidAction action)
{
if(te.fluid_level() <= 0) return FluidStack.EMPTY;
FluidStack fs = milk_fluid_.copy();
fs.setAmount(Math.min(fs.getAmount(), te.fluid_level()));
if(action==FluidAction.EXECUTE) te.tank_level_ -= fs.getAmount();
return fs;
}
private boolean has_milk_fluid()
{ return !(NO_MILK_FLUID.isFluidEqual(milk_fluid_)); }
@Override
@Nonnull
public FluidStack getFluid()
{ return has_milk_fluid() ? (new FluidStack(milk_fluid_, fluid_level())) : (FluidStack.EMPTY); }
@Override
public int getFluidAmount()
{ return has_milk_fluid() ? fluid_level() : 0; }
@Override
public int getCapacity()
{ return TANK_CAPACITY; }
@Override
public boolean isFluidValid(FluidStack stack)
{ return has_milk_fluid() && stack.isFluidEqual(milk_fluid_); }
@Override
public int fill(FluidStack resource, FluidAction action)
{ return 0; }
@Override
@Nonnull
public FluidStack drain(FluidStack resource, FluidAction action)
{ return (!resource.isFluidEqual(milk_fluid_)) ? (FluidStack.EMPTY) : drain(resource.getAmount(), action); }
@Override
@Nonnull
public FluidStack drain(int maxDrain, FluidAction action)
{
if((!has_milk_fluid()) || (fluid_level() <= 0)) return FluidStack.EMPTY;
FluidStack fs = milk_fluid_.copy();
fs.setAmount(Math.min(fs.getAmount(), fluid_level()));
if(action==FluidAction.EXECUTE) tank_level_ -= fs.getAmount();
return fs;
}
// ICapabilityProvider ---------------------------------------------------------------------------
@ -292,7 +323,7 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if((capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && (!milk_fluid_.isEmpty())) {
if((capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && has_milk_fluid()) {
return fluid_handler_.cast();
} else if((capability == CapabilityEnergy.ENERGY) && (energy_consumption>0)) {
return energy_handler_.cast();
@ -309,21 +340,21 @@ public class BlockDecorMilker extends BlockDecor.Horizontal implements IDecorBlo
{} // println("Milker|" + s); may be enabled with config, for dev was println
private static ItemStack milk_filled_container_item(ItemStack stack)
{ return milk_containers_.entrySet().stream().filter(e->e.getKey().isItemEqual(stack)).map(Map.Entry::getValue).findFirst().orElse(ItemStack.EMPTY); }
{ return milk_containers_.entrySet().stream().filter(e->Inventories.areItemStacksIdentical(e.getKey(), stack)).map(Map.Entry::getValue).findFirst().orElse(ItemStack.EMPTY); }
private void fill_adjacent_inventory_item_containers(Direction block_facing)
{
// Check inventory existence, back to down is preferred, otherwise sort back into same inventory.
IItemHandler src = ItemHandling.itemhandler(world, pos.offset(block_facing), block_facing.getOpposite());
IItemHandler dst = ItemHandling.itemhandler(world, pos.down(), Direction.UP);
IItemHandler src = Inventories.itemhandler(world, pos.offset(block_facing), block_facing.getOpposite());
IItemHandler dst = Inventories.itemhandler(world, pos.down(), Direction.UP);
if(src==null) { src = dst; } else if(dst==null) { dst = src; }
if((src==null) || (dst==null)) return;
while((tank_level_ >= BUCKET_SIZE)) {
boolean inserted = false;
for(Entry<ItemStack,ItemStack> e:milk_containers_.entrySet()) {
if(ItemHandling.extract(src, e.getKey(), 1, true).isEmpty()) continue;
if(!ItemHandling.insert(dst, e.getValue().copy(), false).isEmpty()) continue;
ItemHandling.extract(src, e.getKey(), 1, false);
if(Inventories.extract(src, e.getKey(), 1, true).isEmpty()) continue;
if(!Inventories.insert(dst, e.getValue().copy(), false).isEmpty()) continue;
Inventories.extract(src, e.getKey(), 1, false);
tank_level_ -= BUCKET_SIZE;
inserted = true;
}

View file

@ -238,7 +238,7 @@ public class BlockDecorMineralSmelter extends BlockDecor.Horizontal implements I
public static void on_config(int energy_consumption, int heatup_per_second)
{
energy_consumption = MathHelper.clamp(energy_consumption, 32, 4096);
energy_consumption = MathHelper.clamp(energy_consumption, 8, 4096);
heatup_rate = MathHelper.clamp(heatup_per_second, 1, 5);
cooldown_rate = MathHelper.clamp(heatup_per_second/2, 1, 5);
ModEngineersDecor.logger().info("Config mineal smelter energy consumption:" + energy_consumption + "rf/t, heat-up rate: " + heatup_rate + "%/s.");

View file

@ -42,7 +42,7 @@ import javax.annotation.Nullable;
public class BlockDecorPassiveFluidAccumulator extends BlockDecor.Directed implements IDecorBlock
{
public BlockDecorPassiveFluidAccumulator(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorPassiveFluidAccumulator(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override

View file

@ -61,8 +61,8 @@ public class BlockDecorPipeValve extends BlockDecor.DirectedWaterLoggable implem
ModEngineersDecor.logger().info("Config pipe valve: maxflow:" + BTileEntity.fluid_maxflow_mb + "mb, redstone amp:" + BTileEntity.redstone_flow_slope_mb + "mb/sig");
}
public BlockDecorPipeValve(long config, int valve_config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); this.valve_config=valve_config;}
public BlockDecorPipeValve(long config, int valve_config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); this.valve_config = valve_config; }
private BlockState get_rsconnector_state(BlockState state, IWorld world, BlockPos pos, @Nullable BlockPos fromPos)
{

View file

@ -56,7 +56,7 @@ import java.util.List;
public class BlockDecorPlacer extends BlockDecor.Directed
{
public BlockDecorPlacer(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorPlacer(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override

View file

@ -17,7 +17,6 @@ import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.Direction;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.item.BlockItemUseContext;
import net.minecraft.state.IntegerProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.util.math.MathHelper;
@ -73,7 +72,7 @@ public class BlockDecorSolarPanel extends BlockDecor implements IDecorBlock
public static void on_config(int peak_power_per_tick)
{
peak_power_per_tick_ = peak_power_per_tick;
peak_power_per_tick_ = MathHelper.clamp(peak_power_per_tick, 2, 8192);
ModEngineersDecor.logger().info("Config small solar panel: Peak production:" + peak_power_per_tick_ + "/tick");
}

View file

@ -40,7 +40,7 @@ public class BlockDecorTreeCutter extends BlockDecor.Horizontal
{
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public BlockDecorTreeCutter(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public BlockDecorTreeCutter(long config, Block.Properties builder, final AxisAlignedBB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@ -99,7 +99,7 @@ public class BlockDecorTreeCutter extends BlockDecor.Horizontal
public static void on_config(int boost_energy_per_tick, int cutting_time_seconds, boolean power_required)
{
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 16, 512);
boost_energy_consumption = TICK_INTERVAL * MathHelper.clamp(boost_energy_per_tick, 4, 4096);
cutting_time_needed = 20 * MathHelper.clamp(cutting_time_seconds, 10, 240);
requires_power = power_required;
ModEngineersDecor.logger().info("Config tree cutter: Boost energy consumption:" + boost_energy_consumption + "rf/t" + (requires_power?" (power required for operation) ":"") + ", cutting time " + cutting_time_needed + "t." );

View file

@ -10,6 +10,7 @@ package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.libmc.detail.Inventories;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
@ -178,7 +179,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick)
{
energy_consumption = MathHelper.clamp(boost_energy_per_tick, 16, 512);
energy_consumption = MathHelper.clamp(boost_energy_per_tick, 4, 4096);
ModEngineersDecor.logger().info("Config waste incinerator boost energy consumption:" + energy_consumption);
}
@ -573,7 +574,7 @@ public class BlockDecorWasteIncinerator extends BlockDecor
stacks_.set(index_to, from.split(count));
} else if(to.getCount() >= to.getMaxStackSize()) {
changed = false;
} else if((!from.isItemEqual(to)) || (!ItemStack.areItemStackTagsEqual(from, to))) {
} else if(Inventories.areItemStacksDifferent(from, to)) {
changed = false;
} else {
if((to.getCount()+count) >= to.getMaxStackSize()) {

View file

@ -360,14 +360,14 @@ public class ModConfig
.comment("Defines, in percent, how fast the lab furnace smelts compared to " +
"a vanilla furnace. 100% means vanilla furnace speed, 150% means the " +
"lab furnace is faster. The value can be changed on-the-fly for tuning.")
.defineInRange("furnace_smelting_speed_percent", 130, 50, 500);
.defineInRange("furnace_smelting_speed_percent", 130, 50, 800);
furnace_fuel_efficiency_percent = builder
.translation(ModEngineersDecor.MODID + ".config.furnace_fuel_efficiency_percent")
.comment("Defines, in percent, how fuel efficient the lab furnace is, compared " +
"to a vanilla furnace. 100% means vanilla furnace consumiton, 200% means " +
"the lab furnace needs about half the fuel of a vanilla furnace, " +
"The value can be changed on-the-fly for tuning.")
.defineInRange("furnace_fuel_efficiency_percent", 100, 50, 250);
.defineInRange("furnace_fuel_efficiency_percent", 100, 50, 400);
furnace_boost_energy_consumption = builder
.translation(ModEngineersDecor.MODID + ".config.furnace_boost_energy_consumption")
.comment("Defines the energy consumption (per tick) for speeding up the smelting process. " +
@ -375,7 +375,7 @@ public class ModConfig
"of the lab furnace. The power source needs to be able to provide at least 4 times " +
"this consumption (fixed threshold value). The value can be changed on-the-fly for tuning. " +
"The default value corresponds to the IE heater consumption.")
.defineInRange("furnace_boost_energy_consumption", 24, 16, 256);
.defineInRange("furnace_boost_energy_consumption", 24, 2, 1024);
chair_mob_sitting_probability_percent = builder
.translation(ModEngineersDecor.MODID + ".config.chair_mob_sitting_probability_percent")
.comment("Defines, in percent, how high the probability is that a mob sits on a chair " +
@ -402,27 +402,27 @@ public class ModConfig
"That is technically the 'storage size' specified for blocks that want to fill " +
"fluids into the valve (the valve has no container and forward that to the output " +
"block), The value can be changed on-the-fly for tuning. ")
.defineInRange("pipevalve_max_flowrate", 1000, 1, 10000);
.defineInRange("pipevalve_max_flowrate", 1000, 1, 32000);
pipevalve_redstone_gain = builder
.translation(ModEngineersDecor.MODID + ".config.pipevalve_redstone_gain")
.comment("Defines how many millibuckets per redstone signal strength can be transferred per tick " +
"through the analog redstone controlled valves. Note: power 0 is always off, power 15 is always " +
"the max flow rate. Between power 1 and 14 this scaler will result in a flow = 'redstone slope' * 'current redstone power'. " +
"The value can be changed on-the-fly for tuning. ")
.defineInRange("pipevalve_redstone_gain", 20, 1, 10000);
.defineInRange("pipevalve_redstone_gain", 20, 1, 32000);
e_furnace_speed_percent = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_speed_percent")
.comment("Defines, in percent, how fast the electrical furnace smelts compared to " +
"a vanilla furnace. 100% means vanilla furnace speed, 150% means the " +
"electrical furnace is faster. The value can be changed on-the-fly for tuning.")
.defineInRange("e_furnace_speed_percent", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_SPEED_PERCENT, 50, 500);
.defineInRange("e_furnace_speed_percent", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_SPEED_PERCENT, 50, 800);
e_furnace_power_consumption = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_power_consumption")
.comment("Defines how much RF per tick the the electrical furnace consumed (average) for smelting. " +
"The feeders transferring items from/to adjacent have this consumption/8 for each stack transaction. " +
"The default value is only slightly higher than a furnace with an IE external heater (and no burning fuel inside)." +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("e_furnace_power_consumption", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 10, 256);
.defineInRange("e_furnace_power_consumption", BlockDecorFurnaceElectrical.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 8, 4096);
e_furnace_automatic_pulling = builder
.translation(ModEngineersDecor.MODID + ".config.e_furnace_automatic_pulling")
.comment("Defines if the electrical furnace automatically pulls items from an inventory at the input side." +
@ -434,12 +434,12 @@ public class ModConfig
"Note that the agerage power is much less, as no power is produced at all during the night, " +
"and the power curve is nonlinear rising/falling during the day. Bad weather conditions also " +
"decrease the production. The config value can be changed on-the-fly for tuning.")
.defineInRange("small_solar_panel_peak_production", BlockDecorSolarPanel.BTileEntity.DEFAULT_PEAK_POWER, 10, 256);
.defineInRange("small_solar_panel_peak_production", BlockDecorSolarPanel.BTileEntity.DEFAULT_PEAK_POWER, 2, 4096);
block_breaker_power_consumption = builder
.translation(ModEngineersDecor.MODID + ".config.block_breaker_power_consumption")
.comment("Defines how much RF power the Small Block Breaker requires to magnificently increase the processing speed. " +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("block_breaker_power_consumption", BlockDecorBreaker.BTileEntity.DEFAULT_BOOST_ENERGY, 16, 512);
.defineInRange("block_breaker_power_consumption", BlockDecorBreaker.BTileEntity.DEFAULT_BOOST_ENERGY, 4, 1024);
block_breaker_reluctance = builder
.translation(ModEngineersDecor.MODID + ".config.block_breaker_reluctance")
.comment("Defines how much time the Small Block Breaker needs per block hardness, " +
@ -460,7 +460,7 @@ public class ModConfig
.translation(ModEngineersDecor.MODID + ".config.tree_cuttter_energy_consumption")
.comment("Defines how much RF power the Small Tree Cutter requires to magnificently increase the processing speed. " +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("tree_cuttter_energy_consumption", BlockDecorTreeCutter.BTileEntity.DEFAULT_BOOST_ENERGY, 16, 512);
.defineInRange("tree_cuttter_energy_consumption", BlockDecorTreeCutter.BTileEntity.DEFAULT_BOOST_ENERGY, 4, 1024);
tree_cuttter_cutting_time_needed = builder
.translation(ModEngineersDecor.MODID + ".config.tree_cuttter_cutting_time_needed")
.comment("Defines how much time the Small Tree Cutter needs to cut a tree without RF power. " +
@ -477,7 +477,7 @@ public class ModConfig
"Note this is a permanent standby power, not only when the device does something. " +
"Use zero to disable energy dependency and energy handling of the machine. " +
"The config value can be changed on-the-fly for tuning.")
.defineInRange("milking_machine_energy_consumption", BlockDecorMilker.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 0, 128);
.defineInRange("milking_machine_energy_consumption", BlockDecorMilker.BTileEntity.DEFAULT_ENERGY_CONSUMPTION, 0, 1024);
milking_machine_milking_delay = builder
.translation(ModEngineersDecor.MODID + ".config.milking_machine_milking_delay")
.comment("Defines (for each individual cow) the minimum time between milking." )

View file

@ -13,6 +13,7 @@
package wile.engineersdecor.libmc.blocks;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.world.server.ServerWorld;
import wile.engineersdecor.libmc.detail.Auxiliaries;
import net.minecraft.block.*;
@ -43,9 +44,9 @@ import net.minecraft.util.*;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Supplier;
public class StandardBlocks
@ -92,6 +93,14 @@ public class StandardBlocks
public BaseBlock(long conf, Block.Properties properties, VoxelShape voxel_shape)
{ super(properties); config = conf; vshape = voxel_shape; }
public BaseBlock(long conf, Block.Properties properties, AxisAlignedBB[] aabbs)
{
super(properties); config = conf;
VoxelShape shape = VoxelShapes.empty();
for(AxisAlignedBB aabb:aabbs) shape = VoxelShapes.combine(shape, VoxelShapes.create(aabb), IBooleanFunction.OR);
vshape = shape;
}
///////////// --------------------------------------------------------------------------------------------------------
// 1.15 transition
@ -231,6 +240,9 @@ public class StandardBlocks
public WaterLoggable(long config, Block.Properties properties, VoxelShape voxel_shape)
{ super(config|CFG_WATERLOGGABLE, properties, voxel_shape); }
public WaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config|CFG_WATERLOGGABLE, properties, aabbs); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
@ -239,25 +251,35 @@ public class StandardBlocks
public static class Directed extends BaseBlock implements IStandardBlock
{
public static final DirectionProperty FACING = DirectionalBlock.FACING;
protected final ArrayList<VoxelShape> AABBs;
protected final ArrayList<VoxelShape> vshapes;
public Directed(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public Directed(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{
super(config, builder);
super(config, properties);
setDefaultState(stateContainer.getBaseState().with(FACING, Direction.UP));
final boolean is_horizontal = ((config & CFG_HORIZIONTAL)!=0);
AABBs = new ArrayList<VoxelShape>(Arrays.asList(
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.DOWN, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.UP, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.NORTH, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.SOUTH, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.WEST, is_horizontal)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.EAST, is_horizontal)),
VoxelShapes.create(unrotatedAABB),
VoxelShapes.create(unrotatedAABB)
));
vshapes = shape_supplier.get();
}
public Directed(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABBs)
{
this(config, properties, ()->{
final boolean is_horizontal = ((config & CFG_HORIZIONTAL)!=0);
return new ArrayList<VoxelShape>(Arrays.asList(
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.DOWN, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.UP, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.NORTH, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.SOUTH, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.WEST, is_horizontal)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.EAST, is_horizontal)),
VoxelShapes.fullCube(),
VoxelShapes.fullCube()
));
});
}
public Directed(long config, Block.Properties properties, final AxisAlignedBB unrotatedAABB)
{ this(config, properties, new AxisAlignedBB[]{unrotatedAABB}); }
@Override
public boolean canSpawnInBlock()
{ return false; }
@ -269,7 +291,7 @@ public class StandardBlocks
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs.get((state.get(FACING)).getIndex() & 0x7); }
{ return vshapes.get((state.get(FACING)).getIndex() & 0x7); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
@ -305,27 +327,37 @@ public class StandardBlocks
public static class Horizontal extends BaseBlock implements IStandardBlock
{
public static final DirectionProperty HORIZONTAL_FACING = HorizontalBlock.HORIZONTAL_FACING;
protected final ArrayList<VoxelShape> AABBs;
protected final ArrayList<VoxelShape> vshapes;
public Horizontal(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
public Horizontal(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{
super(config|CFG_HORIZIONTAL, builder, unrotatedAABB);
super(config|CFG_HORIZIONTAL, properties);
setDefaultState(stateContainer.getBaseState().with(HORIZONTAL_FACING, Direction.NORTH));
AABBs = new ArrayList<VoxelShape>(Arrays.asList(
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.DOWN, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.UP, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.NORTH, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.SOUTH, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.WEST, true)),
VoxelShapes.create(Auxiliaries.getRotatedAABB(unrotatedAABB, Direction.EAST, true)),
VoxelShapes.create(unrotatedAABB),
VoxelShapes.create(unrotatedAABB)
));
vshapes = shape_supplier.get();
}
public Horizontal(long config, Block.Properties properties, final AxisAlignedBB[] unrotatedAABBs)
{
this(config, properties, ()->{
return new ArrayList<VoxelShape>(Arrays.asList(
VoxelShapes.fullCube(),
VoxelShapes.fullCube(),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.NORTH, true)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.SOUTH, true)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.WEST, true)),
Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.EAST, true)),
VoxelShapes.fullCube(),
VoxelShapes.fullCube()
));
});
}
public Horizontal(long config, Block.Properties properties, final AxisAlignedBB unrotatedAABB)
{ this(config, properties, new AxisAlignedBB[]{unrotatedAABB}); }
@Override
public VoxelShape getShape(BlockState state, IBlockReader source, BlockPos pos, ISelectionContext selectionContext)
{ return AABBs.get((state.get(HORIZONTAL_FACING)).getIndex() & 0x7); }
{ return vshapes.get((state.get(HORIZONTAL_FACING)).getIndex() & 0x7); }
@Override
public VoxelShape getCollisionShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)
@ -368,6 +400,12 @@ public class StandardBlocks
public DirectedWaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config|CFG_WATERLOGGABLE, properties, aabb); }
public DirectedWaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config|CFG_WATERLOGGABLE, properties, aabbs); }
public DirectedWaterLoggable(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config|CFG_WATERLOGGABLE, properties, shape_supplier); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }
@ -378,6 +416,12 @@ public class StandardBlocks
public HorizontalWaterLoggable(long config, Block.Properties properties, AxisAlignedBB aabb)
{ super(config|CFG_WATERLOGGABLE|CFG_HORIZIONTAL, properties, aabb); }
public HorizontalWaterLoggable(long config, Block.Properties properties, AxisAlignedBB[] aabbs)
{ super(config|CFG_WATERLOGGABLE|CFG_HORIZIONTAL, properties, aabbs); }
public HorizontalWaterLoggable(long config, Block.Properties properties, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config|CFG_WATERLOGGABLE|CFG_HORIZIONTAL, properties, shape_supplier); }
@Override
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder)
{ super.fillStateContainer(builder); builder.add(WATERLOGGED); }

View file

@ -24,6 +24,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.text.ITextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@ -36,11 +37,15 @@ public class StandardFenceBlock extends WallBlock implements StandardBlocks.ISta
private final VoxelShape[] shape_voxels;
private final VoxelShape[] collision_shape_voxels;
public StandardFenceBlock(long config, Block.Properties builder)
public StandardFenceBlock(long config, Block.Properties properties)
{ this(config, properties, 1.5,16, 1.5, 0, 16); }
public StandardFenceBlock(long config, Block.Properties properties, double pole_width, double pole_height, double side_width, double side_max_y, double side_min_y)
{
super(builder);
this.shape_voxels = buildWallShapes(1.5f, 1.5f, 16f, 0f, 16f);
this.collision_shape_voxels = buildWallShapes(1.5f, 1.5f, 24f, 0f, 24f);
super(properties);
this.shape_voxels = buildShapes(pole_width, pole_height, side_width, side_max_y, side_min_y);
this.collision_shape_voxels = buildShapes(pole_width,24, pole_width, 0, 24);
}
@Override
@ -48,8 +53,36 @@ public class StandardFenceBlock extends WallBlock implements StandardBlocks.ISta
public void addInformation(ItemStack stack, @Nullable IBlockReader world, List<ITextComponent> tooltip, ITooltipFlag flag)
{ Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
protected VoxelShape[] buildWallShapes(float pole_width_x, float pole_width_z, float pole_height, float side_min_y, float side_max_y)
{ return super.makeShapes(pole_width_x, pole_width_z, pole_height, side_min_y, side_max_y); }
protected VoxelShape[] buildShapes(double pole_width, double pole_height, double side_width, double side_min_y, double side_max_y)
{
final double px0=8d-pole_width, px1=8d+pole_width, sx0=8d-side_width, sx1=8d+side_width;
VoxelShape vp = Block.makeCuboidShape(px0, 0, px0, px1, pole_height, px1);
VoxelShape vs1 = Block.makeCuboidShape(sx0, side_min_y, 0, sx1, side_max_y, sx1);
VoxelShape vs2 = Block.makeCuboidShape(sx0, side_min_y, sx0, sx1, side_max_y, 16);
VoxelShape vs3 = Block.makeCuboidShape(0, side_min_y, sx0, sx1, side_max_y, sx1);
VoxelShape vs4 = Block.makeCuboidShape(sx0, side_min_y, sx0, 16, side_max_y, sx1);
VoxelShape vs5 = VoxelShapes.or(vs1, vs4);
VoxelShape vs6 = VoxelShapes.or(vs2, vs3);
return new VoxelShape[] {
vp,
VoxelShapes.or(vp, vs2),
VoxelShapes.or(vp, vs3),
VoxelShapes.or(vp, vs6),
VoxelShapes.or(vp, vs1),
VoxelShapes.or(vs2, vs1),
VoxelShapes.or(vp, VoxelShapes.or(vs3, vs1)),
VoxelShapes.or(vp, VoxelShapes.or(vs6, vs1)),
VoxelShapes.or(vp, vs4),
VoxelShapes.or(vp, VoxelShapes.or(vs2, vs4)),
VoxelShapes.or(vs3, vs4),
VoxelShapes.or(vp, VoxelShapes.or(vs6, vs4)),
VoxelShapes.or(vp, vs5),
VoxelShapes.or(vp, VoxelShapes.or(vs2, vs5)),
VoxelShapes.or(vp, VoxelShapes.or(vs3, vs5)),
VoxelShapes.or(vp, VoxelShapes.or(vs6, vs5))
};
}
@Override
public VoxelShape getShape(BlockState state, IBlockReader world, BlockPos pos, ISelectionContext selectionContext)

View file

@ -13,6 +13,9 @@ import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.SharedConstants;
import net.minecraft.util.math.shapes.IBooleanFunction;
import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.world.IBlockReader;
@ -256,6 +259,20 @@ public class Auxiliaries
return bb;
}
public static final AxisAlignedBB[] getRotatedAABB(AxisAlignedBB[] bbs, Direction new_facing, boolean horizontal_rotation)
{
AxisAlignedBB[] transformed = new AxisAlignedBB[bbs.length];
for(int i=0; i<bbs.length; ++i) transformed[i] = getRotatedAABB(bbs[i], new_facing, horizontal_rotation);
return transformed;
}
public static final VoxelShape getUnionShape(AxisAlignedBB[] aabbs)
{
VoxelShape shape = VoxelShapes.empty();
for(AxisAlignedBB aabb: aabbs) shape = VoxelShapes.combine(shape, VoxelShapes.create(aabb), IBooleanFunction.OR);
return shape;
}
// -------------------------------------------------------------------------------------------------------------------
// JAR resource related
// -------------------------------------------------------------------------------------------------------------------

View file

@ -1,4 +1,12 @@
package wile.engineersdecor.detail;
/*
* @file Inventories.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* General inventory item handling functionality.
*/
package wile.engineersdecor.libmc.detail;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@ -12,13 +20,20 @@ import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.InvWrapper;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import javax.annotation.Nullable;
public class ItemHandling
public class Inventories
{
public static boolean areItemStacksIdentical(ItemStack a, ItemStack b)
{ return (a.getItem()==b.getItem()) && ItemStack.areItemStackTagsEqual(a, b); }
public static boolean areItemStacksDifferent(ItemStack a, ItemStack b)
{ return (a.getItem()!=b.getItem()) || (!ItemStack.areItemStackTagsEqual(a, b)); }
public static IItemHandler itemhandler(World world, BlockPos pos, @Nullable Direction side)
{
TileEntity te = world.getTileEntity(pos);
@ -56,9 +71,9 @@ public class ItemHandling
final ItemStack stack = inventory.getStackInSlot(i);
if(stack.isEmpty()) continue;
if(out_stack.isEmpty()) {
if((match!=null) && (!stack.isItemEqual(match))) continue;
if((match!=null) && Inventories.areItemStacksDifferent(stack, match)) continue;
out_stack = inventory.extractItem(i, amount, simulate);
} else if(stack.isItemEqual(out_stack)) {
} else if(Inventories.areItemStacksIdentical(stack, out_stack)) {
ItemStack es = inventory.extractItem(i, (amount-out_stack.getCount()), simulate);
out_stack.grow(es.getCount());
}
@ -67,4 +82,4 @@ public class ItemHandling
return out_stack;
}
}
}