1.12: Added Fluid Collection Funnel. Added missin config opt-outs. Added Config tweaks for Block Breaker and Tree Cutter (cffr#185). Fixed Block placer discarding metadata (issue #60). Fixed Block Breaker duping shulker boxes. Block Breaker model updated. 1.14: Block breaker model updated.

This commit is contained in:
stfwi 2019-11-08 21:11:08 +01:00
parent 7592c9d494
commit 6c4fbeff56
19 changed files with 639 additions and 511 deletions

View file

@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx8G
version_minecraft=1.12.2 version_minecraft=1.12.2
version_forge=14.23.5.2768 version_forge=14.23.5.2768
version_jei=4.10.0.198 version_jei=4.10.0.198
version_engineersdecor=1.0.15 version_engineersdecor=1.0.16-b1

View file

@ -1,6 +1,7 @@
{ {
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.12.2": { "1.12.2": {
"1.0.16-b1": "[A] Added Fluid Collection Funnel.\n[A] Added config opt-outs for Breaker, Placer, Fluid Funnel, Mineral Smelter.\n[A] Added configs tweaks for Small Block Breaker and Small Tree Cutter (cffr#185).\n[F] Fixed Block Placer discarding item metadata/variants while placing (issue #60).\n[F] Fixed Block Breaker duping empty shulker boxes, model updated.",
"1.0.15": "[R] Release based on v1.0.15-b2. Release-to-release changes: * Added Small Block Breaker * Small Tree Cutter fixes and compatability improved. * Crafting table compat fixes.\n[M] Small Tree Cutter log detection bug fixed (issue #59).\n[M] Small Tree Cutter supports Menril chopping (issue #54).", "1.0.15": "[R] Release based on v1.0.15-b2. Release-to-release changes: * Added Small Block Breaker * Small Tree Cutter fixes and compatability improved. * Crafting table compat fixes.\n[M] Small Tree Cutter log detection bug fixed (issue #59).\n[M] Small Tree Cutter supports Menril chopping (issue #54).",
"1.0.15-b2": "[A] Added Small Block Breaker\n[M] Crafting Table: Allowing NBT \"Damage\" mismatch only items that are declared damagable (issue #56).\n[M] Tree Cutter: Loosened the strict mod namespace requirement for Dynamic Trees log detection (issue #52) to enable checking DT compat mod log blocks.", "1.0.15-b2": "[A] Added Small Block Breaker\n[M] Crafting Table: Allowing NBT \"Damage\" mismatch only items that are declared damagable (issue #56).\n[M] Tree Cutter: Loosened the strict mod namespace requirement for Dynamic Trees log detection (issue #52) to enable checking DT compat mod log blocks.",
"1.0.15-b1": "[A] Added Floor Edge Light.\n[A] Added Factory Block Placer and Planter.", "1.0.15-b1": "[A] Added Floor Edge Light.\n[A] Added Factory Block Placer and Planter.",
@ -66,6 +67,6 @@
}, },
"promos": { "promos": {
"1.12.2-recommended": "1.0.15", "1.12.2-recommended": "1.0.15",
"1.12.2-latest": "1.0.15" "1.12.2-latest": "1.0.16-b1"
} }
} }

View file

@ -10,6 +10,12 @@ Mod sources for Minecraft version 1.12.2.
---- ----
## Version history ## Version history
- v1.0.16-b1 [A] Added Fluid Collection Funnel.
[A] Added config opt-outs for Breaker, Placer, Fluid Funnel, Mineral Smelter.
[A] Added configs tweaks for Small Block Breaker and Small Tree Cutter (cffr#185).
[F] Fixed Block Placer discarding item metadata/variants while placing (issue #60).
[F] Fixed Block Breaker duping empty shulker boxes, model updated.
------------------------------------------------------------------- -------------------------------------------------------------------
- v1.0.15 [R] Release based on v1.0.15-b2. Release-to-release changes: - v1.0.15 [R] Release based on v1.0.15-b2. Release-to-release changes:
* Added Small Block Breaker * Added Small Block Breaker

View file

@ -523,6 +523,7 @@ public class ModContent
SMALL_SOLAR_PANEL,SMALL_SOLAR_PANEL_TEI, SMALL_SOLAR_PANEL,SMALL_SOLAR_PANEL_TEI,
SMALL_MINERAL_SMELTER, SMALL_MINERAL_SMELTER_TEI, SMALL_MINERAL_SMELTER, SMALL_MINERAL_SMELTER_TEI,
STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE, STRAIGHT_PIPE_VALVE_TEI, STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE, STRAIGHT_PIPE_VALVE_TEI,
SMALL_FLUID_FUNNEL,SMALL_FLUID_FUNNEL_TEI,
PASSIVE_FLUID_ACCUMULATOR, PASSIVE_FLUID_ACCUMULATOR_TEI, PASSIVE_FLUID_ACCUMULATOR, PASSIVE_FLUID_ACCUMULATOR_TEI,
CLINKER_BRICK_BLOCK, CLINKER_BRICK_BLOCK,
CLINKER_BRICK_SLAB, CLINKER_BRICK_SLAB,
@ -578,7 +579,6 @@ public class ModContent
PANZERGLASS_SLAB, // @todo: check if another class is needed due to is_side_visible PANZERGLASS_SLAB, // @todo: check if another class is needed due to is_side_visible
TREATED_WOOD_FLOOR, // @todo: check if textures need improvement TREATED_WOOD_FLOOR, // @todo: check if textures need improvement
TEST_BLOCK,TEST_BLOCK_TEI, TEST_BLOCK,TEST_BLOCK_TEI,
SMALL_FLUID_FUNNEL,SMALL_FLUID_FUNNEL_TEI
}; };
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------

View file

@ -16,7 +16,6 @@ import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.SoundType; import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
@ -113,16 +112,19 @@ public class BlockDecorBreaker extends BlockDecorDirected
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY; private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY;
private static int breaking_reluctance = DEFAULT_BREAKING_RELUCTANCE; private static int breaking_reluctance = DEFAULT_BREAKING_RELUCTANCE;
private static int min_breaking_time = DEFAULT_MIN_BREAKING_TIME; private static int min_breaking_time = DEFAULT_MIN_BREAKING_TIME;
private static boolean requires_power = false;
private int tick_timer_; private int tick_timer_;
private int active_timer_;
private int proc_time_elapsed_; private int proc_time_elapsed_;
private int boost_energy_; private int boost_energy_;
public static void on_config(int boost_energy_per_tick, int breaking_time_per_hardness, int min_breaking_time_ticks) 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, 16, 512);
breaking_reluctance = MathHelper.clamp(breaking_time_per_hardness, 5, 50); breaking_reluctance = MathHelper.clamp(breaking_time_per_hardness, 5, 50);
min_breaking_time = MathHelper.clamp(min_breaking_time_ticks, 10, 100); min_breaking_time = MathHelper.clamp(min_breaking_time_ticks, 10, 100);
ModEngineersDecor.logger.info("Config block breaker: Boost energy consumption:" + boost_energy_consumption + "rf/t, reluctance=" + breaking_reluctance + "/hrdn, break time offset=" + min_breaking_time ); requires_power = power_required;
ModEngineersDecor.logger.info("Config block breaker: Boost energy consumption:" + (boost_energy_consumption/TICK_INTERVAL) + "rf/t, reluctance=" + breaking_reluctance + "t/hrdn, break time offset=" + min_breaking_time + "t");
} }
public BTileEntity() public BTileEntity()
@ -208,13 +210,12 @@ public class BlockDecorBreaker extends BlockDecorDirected
return true; return true;
} }
private boolean breakBlock(IBlockState state, BlockPos pos, World world) private static boolean breakBlock(IBlockState state, BlockPos pos, World world)
{ {
if(world.isRemote || world.restoringBlockSnapshots) return false; // retry next cycle if(world.isRemote || world.restoringBlockSnapshots) return false; // retry next cycle
NonNullList<ItemStack> drops = NonNullList.create(); final Block block = state.getBlock();
state.getBlock().getDrops(drops, world, pos, state, 0); block.dropBlockAsItem(world, pos, state, 0);
world.setBlockToAir(pos); world.setBlockToAir(pos);
for(ItemStack drop:drops) spawnAsEntity(world, pos, drop);
SoundType stype = state.getBlock().getSoundType(state, world, pos, null); SoundType stype = state.getBlock().getSoundType(state, world, pos, null);
if(stype != null) world.playSound(null, pos, stype.getPlaceSound(), SoundCategory.BLOCKS, stype.getVolume()*0.6f, stype.getPitch()); if(stype != null) world.playSound(null, pos, stype.getPlaceSound(), SoundCategory.BLOCKS, stype.getVolume()*0.6f, stype.getPitch());
return true; return true;
@ -252,14 +253,19 @@ public class BlockDecorBreaker extends BlockDecorDirected
tick_timer_ = IDLE_TICK_INTERVAL; tick_timer_ = IDLE_TICK_INTERVAL;
return; return;
} }
proc_time_elapsed_ += TICK_INTERVAL;
boolean active = true;
int time_needed = (int)(target_state.getBlockHardness(world, pos) * breaking_reluctance) + min_breaking_time; int time_needed = (int)(target_state.getBlockHardness(world, pos) * breaking_reluctance) + min_breaking_time;
if(boost_energy_ >= boost_energy_consumption) { if(boost_energy_ >= boost_energy_consumption) {
boost_energy_ = 0; boost_energy_ = 0;
proc_time_elapsed_ += TICK_INTERVAL * BOOST_FACTOR; proc_time_elapsed_ += TICK_INTERVAL * (1+BOOST_FACTOR);
time_needed += min_breaking_time * (3*BOOST_FACTOR/5); time_needed += min_breaking_time * (3*BOOST_FACTOR/5);
active_timer_ = 2;
} else if(!requires_power) {
proc_time_elapsed_ += TICK_INTERVAL;
active_timer_ = 1024;
} else if(active_timer_ > 0) {
--active_timer_;
} }
boolean active = (active_timer_ > 0);
time_needed = MathHelper.clamp(time_needed, min_breaking_time, MAX_BREAKING_TIME); time_needed = MathHelper.clamp(time_needed, min_breaking_time, MAX_BREAKING_TIME);
if(proc_time_elapsed_ >= time_needed) { if(proc_time_elapsed_ >= time_needed) {
proc_time_elapsed_ = 0; proc_time_elapsed_ = 0;

View file

@ -24,6 +24,7 @@ import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.entity.Entity;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.item.*; import net.minecraft.item.*;
@ -343,10 +344,12 @@ public class BlockDecorPlacer extends BlockDecorDirected
/// ///
public static final int LOGIC_INVERTED = 0x01; public static final int LOGIC_INVERTED = 0x01;
public static final int LOGIC_CONTINUOUS = 0x02; public static final int LOGIC_CONTINUOUS = 0x02;
public static final int DEFAULT_LOGIC = LOGIC_INVERTED|LOGIC_CONTINUOUS;
/// ///
private boolean block_power_signal_ = false; private boolean block_power_signal_ = false;
private boolean block_power_updated_ = false; private boolean block_power_updated_ = false;
private int logic_ = LOGIC_INVERTED|LOGIC_CONTINUOUS; private int logic_ = DEFAULT_LOGIC;
private int current_slot_index_ = 0; private int current_slot_index_ = 0;
private int tick_timer_ = 0; private int tick_timer_ = 0;
protected NonNullList<ItemStack> stacks_; protected NonNullList<ItemStack> stacks_;
@ -375,15 +378,16 @@ public class BlockDecorPlacer extends BlockDecorDirected
while(stacks_.size() < NUM_OF_SLOTS) stacks_.add(ItemStack.EMPTY); while(stacks_.size() < NUM_OF_SLOTS) stacks_.add(ItemStack.EMPTY);
block_power_signal_ = nbt.getBoolean("powered"); block_power_signal_ = nbt.getBoolean("powered");
current_slot_index_ = nbt.getInteger("act_slot_index"); current_slot_index_ = nbt.getInteger("act_slot_index");
logic_ = nbt.getInteger("logic"); logic_ = nbt.hasKey("logic") ? nbt.getInteger("logic") : DEFAULT_LOGIC;
} }
protected void writenbt(NBTTagCompound nbt, boolean update_packet) protected void writenbt(NBTTagCompound nbt, boolean update_packet)
{ {
ItemStackHelper.saveAllItems(nbt, stacks_); boolean stacks_not_empty = stacks_.stream().anyMatch(s->!s.isEmpty());
nbt.setBoolean("powered", block_power_signal_); if(stacks_not_empty) ItemStackHelper.saveAllItems(nbt, stacks_);
nbt.setInteger("act_slot_index", current_slot_index_); if(block_power_signal_) nbt.setBoolean("powered", block_power_signal_);
nbt.setInteger("logic", logic_); if(stacks_not_empty) nbt.setInteger("act_slot_index", current_slot_index_);
if(logic_ != DEFAULT_LOGIC) nbt.setInteger("logic", logic_);
} }
public void block_updated() public void block_updated()
@ -571,11 +575,8 @@ public class BlockDecorPlacer extends BlockDecorDirected
private boolean spit_out(EnumFacing facing) private boolean spit_out(EnumFacing facing)
{ {
ItemStack stack = stacks_.get(current_slot_index_); ItemStack drop = stacks_.get(current_slot_index_).copy();
ItemStack drop = stack.copy(); stacks_.set(current_slot_index_, ItemStack.EMPTY);
stack.shrink(1);
stacks_.set(current_slot_index_, stack);
drop.setCount(1);
for(int i=0; i<8; ++i) { for(int i=0; i<8; ++i) {
BlockPos p = pos.offset(facing, i); BlockPos p = pos.offset(facing, i);
if(!world.isAirBlock(p)) continue; if(!world.isAirBlock(p)) continue;
@ -586,6 +587,63 @@ public class BlockDecorPlacer extends BlockDecorDirected
return true; return true;
} }
private static boolean place_item(ItemStack stack, EntityPlayer placer, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
{
if((stack.isEmpty()) || (!(stack.getItem() instanceof ItemBlock))) return false;
ItemBlock item = (ItemBlock)(stack.getItem());
Block block = world.getBlockState(pos).getBlock();
if(!block.isReplaceable(world, pos)) pos = pos.offset(facing);
if(!world.mayPlace(item.getBlock(), pos, true, facing, (Entity)null)) return false;
int meta = item.getMetadata(stack.getMetadata());
final IBlockState state = item.getBlock().getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer, hand);
if(!item.placeBlockAt(stack, placer, world, pos, facing, hitX, hitY, hitZ, state)) return false;
final IBlockState soundstate = world.getBlockState(pos);
final SoundType stype = soundstate.getBlock().getSoundType(soundstate, world, pos, placer);
world.playSound(placer, pos, stype.getPlaceSound(), SoundCategory.BLOCKS, (stype.getVolume()+1f)/8, stype.getPitch()*1.1f);
return true;
}
private boolean try_plant(BlockPos pos, final EnumFacing facing, final ItemStack stack, final Block block)
{
Item item = stack.getItem();
if(world.isAirBlock(pos)) {
// plant here, block below has to be valid soil.
final IBlockState soilstate = world.getBlockState(pos.down());
if(!soilstate.getBlock().canSustainPlant(soilstate, world, pos.down(), EnumFacing.UP, (IPlantable)block)) {
// Not the right soil for this plant.
return spit_out(facing);
}
} else {
// adjacent block is the soil, plant above if the soil is valid.
final IBlockState soilstate = world.getBlockState(pos);
if(soilstate.getBlock() == block) {
// The plant is already planted from the case above, it's not the assumed soil but the planted plant.
return false;
} else if(!world.isAirBlock(pos.up())) {
// If this is the soil an air block is needed above, if that is blocked we can't plant.
return false;
} else if(!soilstate.getBlock().canSustainPlant(soilstate, world, pos, EnumFacing.UP, (IPlantable)block)) {
// Would be space above, but it's not the right soil for the plant.
return spit_out(facing);
} else {
// Ok, plant above.
pos = pos.up();
}
}
try {
//println("PLANT " + stack + " --> " + block + " at " + pos.subtract(getPos()) + "( item=" + item + ")");
final FakePlayer placer = net.minecraftforge.common.util.FakePlayerFactory.getMinecraft((net.minecraft.world.WorldServer)world);
if((placer==null) || (!place_item(stack, placer, world, pos, EnumHand.MAIN_HAND, EnumFacing.DOWN, 0.5f, 0f, 0.5f))) return spit_out(facing);
stack.shrink(1);
stacks_.set(current_slot_index_, stack);
return true;
} catch(Throwable e) {
ModEngineersDecor.logger.error("Exception while trying to plant " + e);
world.setBlockToAir(pos);
return spit_out(facing);
}
}
private boolean try_place(EnumFacing facing) private boolean try_place(EnumFacing facing)
{ {
if(world.isRemote) return false; if(world.isRemote) return false;
@ -599,83 +657,39 @@ public class BlockDecorPlacer extends BlockDecorDirected
current_slot_index_ = next_slot(current_slot_index_); current_slot_index_ = next_slot(current_slot_index_);
} }
if(current_stack.isEmpty()) { current_slot_index_ = 0; return false; } if(current_stack.isEmpty()) { current_slot_index_ = 0; return false; }
boolean no_space = false;
final Item item = current_stack.getItem(); final Item item = current_stack.getItem();
Block block = (item instanceof IPlantable) ? (((IPlantable)item).getPlant(world, pos).getBlock()) : Block.getBlockFromItem(item); final Block block = Block.getBlockFromItem(item);
if(block == Blocks.AIR) { if(block == Blocks.AIR) return (item!=null) && spit_out(facing); // Item not accepted
if(item != null) { if(world.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(placement_pos)).size() > 0) {
return spit_out(facing); // Item not accepted return false;
} else {
// try next slot
}
} else if(block instanceof IPlantable) {
if(world.isAirBlock(placement_pos)) {
// plant here, block below has to be valid soil.
IBlockState soilstate = world.getBlockState(placement_pos.down());
if(!soilstate.getBlock().canSustainPlant(soilstate, world, pos, EnumFacing.UP, (IPlantable)block)) {
block = Blocks.AIR;
}
} else {
// adjacent block is the soil, plant above if the soil is valid.
IBlockState soilstate = world.getBlockState(placement_pos);
if(soilstate.getBlock() == block) {
// The plant is already planted from the case above.
block = Blocks.AIR;
no_space = true;
} else if(!world.isAirBlock(placement_pos.up())) {
// If this is the soil an air block is needed above, if that is blocked we can't plant.
block = Blocks.AIR;
no_space = true;
} else if(!soilstate.getBlock().canSustainPlant(soilstate, world, pos, EnumFacing.UP, (IPlantable)block)) {
// Would be space above, but it's not the right soil for the plant.
block = Blocks.AIR;
} else {
// Ok, plant above.
placement_pos = placement_pos.up();
}
}
} else if(!world.getBlockState(placement_pos).getBlock().isReplaceable(world, placement_pos)) {
block = Blocks.AIR;
no_space = true;
} }
// System.out.println("PLACE " + current_stack + " --> " + block + " at " + placement_pos.subtract(pos) + "( item=" + item + ")"); if((block instanceof IPlantable) || (item instanceof IPlantable)) try_plant(placement_pos, facing, current_stack, block);
if(block != Blocks.AIR) {
try { if(world.getBlockState(placement_pos).getBlock().isReplaceable(world, placement_pos)) {
final FakePlayer placer = net.minecraftforge.common.util.FakePlayerFactory.getMinecraft((net.minecraft.world.WorldServer)world); if(item instanceof ItemBlock) {
final IBlockState placement_state = (placer==null) ? (block.getDefaultState()) : (block.getStateForPlacement(world, placement_pos, EnumFacing.DOWN,0.5f,0.5f,0f, 0, placer, EnumHand.MAIN_HAND)); try {
if(placement_state == null) { final FakePlayer placer = net.minecraftforge.common.util.FakePlayerFactory.getMinecraft((net.minecraft.world.WorldServer)world);
return spit_out(facing); //println("PLACE ITEMBLOCK" + current_stack + " --> " + block + " at " + placement_pos.subtract(pos) + "( item=" + item + ")");
} else if(item instanceof ItemBlock) {
ItemStack placement_stack = current_stack.copy(); ItemStack placement_stack = current_stack.copy();
placement_stack.setCount(1); placement_stack.setCount(1);
((ItemBlock)item).placeBlockAt(placement_stack, placer, world, placement_pos, EnumFacing.DOWN, 0.5f,0.5f,0f, placement_state); if((placer==null) || (!place_item(placement_stack, placer, world, placement_pos, EnumHand.MAIN_HAND, EnumFacing.DOWN, 0.6f, 0f, 0.5f))) return spit_out(facing);
SoundType stype = block.getSoundType(placement_state, world, pos, null); current_stack.shrink(1);
if(stype != null) world.playSound(null, placement_pos, stype.getPlaceSound(), SoundCategory.BLOCKS, stype.getVolume()*0.6f, stype.getPitch()); stacks_.set(current_slot_index_, current_stack);
} else { return true;
if(world.setBlockState(placement_pos, placement_state, 1|2|8)) { } catch(Throwable e) {
SoundType stype = block.getSoundType(placement_state, world, pos, null); // The block really needs a player or other issues happened during placement.
if(stype != null) world.playSound(null, placement_pos, stype.getPlaceSound(), SoundCategory.BLOCKS, stype.getVolume()*0.6f, stype.getPitch()); // A hard crash should not be fired here, instead spit out the item to indicated that this
} // block is not compatible.
ModEngineersDecor.logger.error("Exception while trying to place " + e);
world.setBlockToAir(placement_pos);
return spit_out(facing);
} }
current_stack.shrink(1); } else {
stacks_.set(current_slot_index_, current_stack); // No idea if this is a particulary good idea, as getBlockFromITem
return true; //println("SPIT NON ITEMBLOCK" + current_stack + " --> " + block + " at " + placement_pos.subtract(pos) + "( item=" + item + ")");
} catch(Throwable e) {
// The block really needs a player or other issues happened during placement.
// A hard crash should not be fired here, instead spit out the item to indicated that this
// block is not compatible.
System.out.println("Exception while trying to place " + e);
world.setBlockToAir(placement_pos);
return spit_out(facing); return spit_out(facing);
} }
} }
if((!no_space) && (!current_stack.isEmpty())) {
// There is space, but the current plant cannot be planted there, so try next.
for(int i=0; i<NUM_OF_SLOTS; ++i) {
current_slot_index_ = next_slot(current_slot_index_);
if(!stacks_.get(current_slot_index_).isEmpty()) break;
}
}
return false; return false;
} }

View file

@ -96,18 +96,22 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
public static final int TICK_INTERVAL = 5; public static final int TICK_INTERVAL = 5;
public static final int BOOST_FACTOR = 6; public static final int BOOST_FACTOR = 6;
public static final int DEFAULT_BOOST_ENERGY = 64; public static final int DEFAULT_BOOST_ENERGY = 64;
public static final int DEFAULT_CUTTING_TIME_NEEDED = 20 * 60; // 60 secs, so that people don't come to the bright idea to carry one with them. public static final int DEFAULT_CUTTING_TIME_NEEDED = 60; // 60 secs, so that people don't come to the bright idea to carry one with them.
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY; private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY;
private static int cutting_time_needed = DEFAULT_CUTTING_TIME_NEEDED; private static int cutting_time_needed = 20 * DEFAULT_CUTTING_TIME_NEEDED;
private static boolean requires_power = false;
private int tick_timer_; private int tick_timer_;
private int active_timer_;
private int proc_time_elapsed_; // small, not saved in nbt. private int proc_time_elapsed_; // small, not saved in nbt.
private int boost_energy_; // small, not saved in nbt. private int boost_energy_; // small, not saved in nbt.
public static void on_config(int boost_energy_per_tick) 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, 16, 512);
ModEngineersDecor.logger.info("Config tree cutter: Boost energy consumption:" + boost_energy_consumption + "rf/t"); 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." );
} }
public BTileEntity() public BTileEntity()
@ -188,15 +192,24 @@ public class BlockDecorTreeCutter extends BlockDecorDirectedHorizontal
if(!TreeCutting.canChop(tree_state) || (world.isBlockPowered(pos))) { if(!TreeCutting.canChop(tree_state) || (world.isBlockPowered(pos))) {
if(device_state.getValue(ACTIVE)) world.setBlockState(pos, device_state.withProperty(ACTIVE, false), 1|2); if(device_state.getValue(ACTIVE)) world.setBlockState(pos, device_state.withProperty(ACTIVE, false), 1|2);
proc_time_elapsed_ = 0; proc_time_elapsed_ = 0;
active_timer_ = 0;
tick_timer_ = IDLE_TICK_INTERVAL; tick_timer_ = IDLE_TICK_INTERVAL;
return; return;
} }
proc_time_elapsed_ += TICK_INTERVAL; proc_time_elapsed_ += TICK_INTERVAL;
if(boost_energy_ >= boost_energy_consumption) { boost_energy_ = 0; proc_time_elapsed_ += TICK_INTERVAL*BOOST_FACTOR; } if(boost_energy_ >= boost_energy_consumption) {
boolean active = true; boost_energy_ = 0;
proc_time_elapsed_ += TICK_INTERVAL*BOOST_FACTOR;
active_timer_ = 2;
} else if(!requires_power) {
active_timer_ = 1024;
} else if(active_timer_ > 0) {
--active_timer_;
}
boolean active = (active_timer_ > 0);
if(proc_time_elapsed_ >= cutting_time_needed) { if(proc_time_elapsed_ >= cutting_time_needed) {
proc_time_elapsed_ = 0; proc_time_elapsed_ = 0;
TreeCutting.chopTree(world, tree_state, tree_pos, 512, false); TreeCutting.chopTree(world, tree_state, tree_pos, 2048, false);
world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SoundEvents.BLOCK_WOOD_BREAK, SoundCategory.BLOCKS, 1.0f, 1.0f); world.playSound(null, pos.getX(), pos.getY(), pos.getZ(), SoundEvents.BLOCK_WOOD_BREAK, SoundCategory.BLOCKS, 1.0f, 1.0f);
active = false; active = false;
} }

View file

@ -20,6 +20,7 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.client.event.ConfigChangedEvent;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -52,6 +53,14 @@ public class ModConfig
@Config.RequiresMcRestart @Config.RequiresMcRestart
public String includes = ""; public String includes = "";
@Config.Comment({"Disable CTRL-SHIFT item tooltip display."})
@Config.Name("Without tooltips")
public boolean without_tooltips = false;
@Config.Comment({"Disable all tile entity special renderers."})
@Config.Name("Without TESRs")
public boolean without_tesrs = false;
@Config.Comment({"Disable clinker bricks and derived blocks."}) @Config.Comment({"Disable clinker bricks and derived blocks."})
@Config.Name("Without clinker bricks") @Config.Name("Without clinker bricks")
@Config.RequiresMcRestart @Config.RequiresMcRestart
@ -87,20 +96,10 @@ public class ModConfig
@Config.RequiresMcRestart @Config.RequiresMcRestart
public boolean without_panzer_glass = false; public boolean without_panzer_glass = false;
@Config.Comment({"Disable treated wood crafting table."}) @Config.Comment({"Disable ladders"})
@Config.Name("Without crafting table") @Config.Name("Without ladders")
@Config.RequiresMcRestart @Config.RequiresMcRestart
public boolean without_crafting_table = false; public boolean without_ladders = false;
@Config.Comment({"Disable small lab furnace."})
@Config.Name("Without lab furnace")
@Config.RequiresMcRestart
public boolean without_lab_furnace = false;
@Config.Comment({"Disable small electrical pass-through furnace."})
@Config.Name("Without electrical furnace")
@Config.RequiresMcRestart
public boolean without_electrical_furnace = false;
@Config.Comment({"Disable treated wood table, stool, windowsill, etc."}) @Config.Comment({"Disable treated wood table, stool, windowsill, etc."})
@Config.Name("Without tr. wood furniture") @Config.Name("Without tr. wood furniture")
@ -117,26 +116,50 @@ public class ModConfig
@Config.RequiresMcRestart @Config.RequiresMcRestart
public boolean without_light_sources = false; public boolean without_light_sources = false;
@Config.Comment({"Disable ladders"}) @Config.Comment({"Disable horizontal half-block slab."})
@Config.Name("Without ladders") @Config.Name("Without slabs")
@Config.RequiresMcRestart @Config.RequiresMcRestart
public boolean without_ladders = false; public boolean without_slabs = false;
@Config.Comment({"Disable possibility to sit on stools and chairs."}) @Config.Comment({"Disable stackable 1/8 block slices."})
@Config.Name("Without chair sitting") @Config.Name("Without slab slices")
public boolean without_chair_sitting = false; @Config.RequiresMcRestart
public boolean without_halfslabs = false;
@Config.Comment({"Disable that mobs will sit on chairs and stools."}) @Config.Comment({"Disable poles of any material."})
@Config.Name("Without chair mob sitting") @Config.Name("Without poles")
public boolean without_mob_chair_sitting = false; @Config.RequiresMcRestart
public boolean without_poles = false;
@Config.Comment({"Disable the speed boost of ladders in this mod."}) @Config.Comment({"Disable horizontal supports like the double-T support."})
@Config.Name("Without ladder speed boost") @Config.Name("Without h. supports")
public boolean without_ladder_speed_boost = false; @Config.RequiresMcRestart
public boolean without_hsupports = false;
@Config.Comment({"Disable history refabrication feature of the treated wood crafting table."}) @Config.Comment({"Disable decorative sign plates (caution, hazards, etc)."})
@Config.Name("Without crafting table history") @Config.Name("Without signs")
public boolean without_crafting_table_history = false; @Config.RequiresMcRestart
public boolean without_sign_plates = false;
@Config.Comment({"Disable the Floor Grating."})
@Config.Name("Without floor gratings")
@Config.RequiresMcRestart
public boolean without_floor_grating = false;
@Config.Comment({"Disable treated wood crafting table."})
@Config.Name("Without crafting table")
@Config.RequiresMcRestart
public boolean without_crafting_table = false;
@Config.Comment({"Disable small lab furnace."})
@Config.Name("Without lab furnace")
@Config.RequiresMcRestart
public boolean without_lab_furnace = false;
@Config.Comment({"Disable small electrical pass-through furnace."})
@Config.Name("Without electrical furnace")
@Config.RequiresMcRestart
public boolean without_electrical_furnace = false;
@Config.Comment({"Disable check valve, and redstone controlled valves."}) @Config.Comment({"Disable check valve, and redstone controlled valves."})
@Config.Name("Without valves") @Config.Name("Without valves")
@ -153,11 +176,6 @@ public class ModConfig
@Config.RequiresMcRestart @Config.RequiresMcRestart
public boolean without_waste_incinerator = false; public boolean without_waste_incinerator = false;
@Config.Comment({"Disable decorative sign plates (caution, hazards, etc)."})
@Config.Name("Without signs")
@Config.RequiresMcRestart
public boolean without_sign_plates = false;
@Config.Comment({"Disable the factory dropper."}) @Config.Comment({"Disable the factory dropper."})
@Config.Name("Without factory dropper") @Config.Name("Without factory dropper")
@Config.RequiresMcRestart @Config.RequiresMcRestart
@ -169,42 +187,49 @@ public class ModConfig
public boolean without_factory_hopper = false; public boolean without_factory_hopper = false;
@Config.Comment({"Disable the Factory Block Placer."}) @Config.Comment({"Disable the Factory Block Placer."})
@Config.Name("Without factory placer") @Config.Name("Without block placer")
@Config.RequiresMcRestart @Config.RequiresMcRestart
public boolean without_factory_placer = false; public boolean without_factory_placer = false;
@Config.Comment({"Disable horizontal half-block slab."}) @Config.Comment({"Disable the Small Block Breaker."})
@Config.Name("Without slabs") @Config.Name("Without block breaker")
@Config.RequiresMcRestart @Config.RequiresMcRestart
public boolean without_slabs = false; public boolean without_block_breaker = false;
@Config.Comment({"Disable stackable 1/8 block slices."}) @Config.Comment({"Disable the Small Solar Panel."})
@Config.Name("Without slab slices") @Config.Name("Without solar panel")
@Config.RequiresMcRestart @Config.RequiresMcRestart
public boolean without_halfslabs = false; public boolean without_solar_panel = false;
@Config.Comment({"Disable directly picking up layers from slabs and slab " + @Config.Comment({"Disable the Small Fluid Collection Funnel."})
"slices by left clicking while looking up/down."}) @Config.Name("Without fluid collector")
@Config.RequiresMcRestart
public boolean without_fluid_funnel = false;
@Config.Comment({"Disable the Small Mineral Smelter."})
@Config.Name("Without mineral smelter")
@Config.RequiresMcRestart
public boolean without_mineral_smelter = false;
@Config.Comment({"Disable directly picking up layers from slabs and slab slices by left clicking while looking up/down."})
@Config.Name("Without slab pickup") @Config.Name("Without slab pickup")
public boolean without_direct_slab_pickup = false; public boolean without_direct_slab_pickup = false;
@Config.Comment({"Disable poles of any material."}) @Config.Comment({"Disable possibility to sit on stools and chairs."})
@Config.Name("Without poles") @Config.Name("Without chair sitting")
@Config.RequiresMcRestart public boolean without_chair_sitting = false;
public boolean without_poles = false;
@Config.Comment({"Disable horizontal supports like the double-T support."}) @Config.Comment({"Disable that mobs will sit on chairs and stools."})
@Config.Name("Without h. supports") @Config.Name("Without chair mob sitting")
@Config.RequiresMcRestart public boolean without_mob_chair_sitting = false;
public boolean without_hsupports = false;
@Config.Comment({"Disable CTRL-SHIFT item tooltip display."}) @Config.Comment({"Disable the speed boost of ladders in this mod."})
@Config.Name("Without tooltips") @Config.Name("Without ladder speed boost")
public boolean without_tooltips = false; public boolean without_ladder_speed_boost = false;
@Config.Comment({"Disable all tile entity special renderers."}) @Config.Comment({"Disable history refabrication feature of the treated wood crafting table."})
@Config.Name("Without TESRs") @Config.Name("Without crafting table history")
public boolean without_tesrs = false; public boolean without_crafting_table_history = false;
} }
@Config.Comment({ @Config.Comment({
@ -346,6 +371,51 @@ public class ModConfig
@Config.Name("Solar panel: Peak power") @Config.Name("Solar panel: Peak power")
@Config.RangeInt(min=5, max=128) @Config.RangeInt(min=5, max=128)
public int solar_panel_peak_power = BlockDecorSolarPanel.BTileEntity.DEFAULT_PEAK_POWER; public int solar_panel_peak_power = BlockDecorSolarPanel.BTileEntity.DEFAULT_PEAK_POWER;
@Config.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."
})
@Config.Name("Block Breaker: Power consumption")
@Config.RangeInt(min=16, max=512)
public int block_breaker_power_consumption = BlockDecorBreaker.BTileEntity.DEFAULT_BOOST_ENERGY;
@Config.Comment({
"Defines how much time the Small Block Breaker needs per block hardness, " +
"means: 'reluctance' * hardness + min_time, you change the 'reluctance' here." +
"The unit is ticks/hardness. " +
"The config value can be changed on-the-fly for tuning."
})
@Config.Name("Block Breaker: Breaking reluctance")
@Config.RangeInt(min=5, max=50)
public int block_breaker_reluctance = BlockDecorBreaker.BTileEntity.DEFAULT_BREAKING_RELUCTANCE;
@Config.Comment({
"Defines how much time the Small Block Breaker needs at least, better said it's an offset: " +
"'reluctance' * hardness + min_time, you change the 'min_time' here, value " +
"in ticks." +
"The config value can be changed on-the-fly for tuning."
})
@Config.Name("Block Breaker: Min breaking time")
@Config.RangeInt(min=10, max=100)
public int block_breaker_min_breaking_time = BlockDecorBreaker.BTileEntity.DEFAULT_MIN_BREAKING_TIME;
@Config.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."
})
@Config.Name("Tree Cutter: Power consumption")
@Config.RangeInt(min=16, max=512)
public int tree_cuttter_energy_consumption = BlockDecorTreeCutter.BTileEntity.DEFAULT_BOOST_ENERGY;
@Config.Comment({
"Defines how much time the Small Tree Cutter needs to cut a tree without RF power. " +
"The value is in seconds. With energy it is 6 times faster. " +
"The config value can be changed on-the-fly for tuning."
})
@Config.Name("Tree Cutter: Cutting time")
@Config.RangeInt(min=10, max=240)
public int tree_cuttter_cutting_time_needed = BlockDecorTreeCutter.BTileEntity.DEFAULT_CUTTING_TIME_NEEDED;
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -409,6 +479,11 @@ public class ModConfig
excludes_.clear(); excludes_.clear();
} }
// Early non-opt out type based evaluation // Early non-opt out type based evaluation
if(block instanceof BlockDecorHalfSlab) return optout.without_halfslabs;
if(block instanceof BlockDecorLadder) return optout.without_ladders;
if(block instanceof BlockDecorWindow) return optout.without_windows;
if(block instanceof BlockDecorHorizontalSupport) return optout.without_hsupports;
if(block instanceof BlockDecorFloorGrating) return optout.without_floor_grating;
if(block instanceof BlockDecorCraftingTable) return optout.without_crafting_table; if(block instanceof BlockDecorCraftingTable) return optout.without_crafting_table;
if(block instanceof BlockDecorFurnaceElectrical) return optout.without_electrical_furnace; if(block instanceof BlockDecorFurnaceElectrical) return optout.without_electrical_furnace;
if((block instanceof BlockDecorFurnace) && (!(block instanceof BlockDecorFurnaceElectrical))) return optout.without_lab_furnace; if((block instanceof BlockDecorFurnace) && (!(block instanceof BlockDecorFurnaceElectrical))) return optout.without_lab_furnace;
@ -417,11 +492,12 @@ public class ModConfig
if(block instanceof BlockDecorDropper) return optout.without_factory_dropper; if(block instanceof BlockDecorDropper) return optout.without_factory_dropper;
if(block instanceof BlockDecorHopper) return optout.without_factory_hopper; if(block instanceof BlockDecorHopper) return optout.without_factory_hopper;
if(block instanceof BlockDecorPlacer) return optout.without_factory_placer; if(block instanceof BlockDecorPlacer) return optout.without_factory_placer;
if(block instanceof BlockDecorHalfSlab) return optout.without_halfslabs; if(block instanceof BlockDecorBreaker) return optout.without_block_breaker;
if(block instanceof BlockDecorLadder) return optout.without_ladders; if(block instanceof BlockDecorSolarPanel) return optout.without_solar_panel;
if(block instanceof BlockDecorWindow) return optout.without_windows; if(block instanceof BlockDecorFluidFunnel) return optout.without_fluid_funnel;
if(block instanceof BlockDecorMineralSmelter) return optout.without_mineral_smelter;
if(block instanceof BlockDecorPipeValve) return optout.without_valves; if(block instanceof BlockDecorPipeValve) return optout.without_valves;
if(block instanceof BlockDecorHorizontalSupport) return optout.without_hsupports;
// Type based evaluation where later filters may match, too // Type based evaluation where later filters may match, too
if(optout.without_slabs && (block instanceof BlockDecorSlab)) return true; if(optout.without_slabs && (block instanceof BlockDecorSlab)) return true;
if(optout.without_stairs && (block instanceof BlockDecorStairs)) return true; if(optout.without_stairs && (block instanceof BlockDecorStairs)) return true;
@ -461,6 +537,8 @@ public class ModConfig
BlockDecorPipeValve.on_config(tweaks.pipevalve_max_flowrate, tweaks.pipevalve_redstone_slope); BlockDecorPipeValve.on_config(tweaks.pipevalve_max_flowrate, tweaks.pipevalve_redstone_slope);
BlockDecorFurnaceElectrical.BTileEntity.on_config(tweaks.e_furnace_speed_percent, tweaks.e_furnace_power_consumption); BlockDecorFurnaceElectrical.BTileEntity.on_config(tweaks.e_furnace_speed_percent, tweaks.e_furnace_power_consumption);
BlockDecorSolarPanel.BTileEntity.on_config(tweaks.solar_panel_peak_power); BlockDecorSolarPanel.BTileEntity.on_config(tweaks.solar_panel_peak_power);
BlockDecorBreaker.BTileEntity.on_config(tweaks.block_breaker_power_consumption, tweaks.block_breaker_reluctance, tweaks.block_breaker_min_breaking_time, false);
BlockDecorTreeCutter.BTileEntity.on_config(tweaks.tree_cuttter_energy_consumption, tweaks.tree_cuttter_cutting_time_needed, false);
{ {
optout.includes = optout.includes.toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", ""); optout.includes = optout.includes.toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", "");
if(!optout.includes.isEmpty()) ModEngineersDecor.logger.info("Pattern includes: '" + optout.includes + "'"); if(!optout.includes.isEmpty()) ModEngineersDecor.logger.info("Pattern includes: '" + optout.includes + "'");

View file

@ -138,7 +138,7 @@ public class TreeCutting
final int dx = Math.abs(pos.getX()-start.getX()); final int dx = Math.abs(pos.getX()-start.getX());
final int dz = Math.abs(pos.getZ()-start.getZ()); final int dz = Math.abs(pos.getZ()-start.getZ());
if(dy > max_cutting_radius) dy = max_cutting_radius; if(dy > max_cutting_radius) dy = max_cutting_radius;
if((dx >= dy+3) || (dz >= dy+3)) return true; if((dx >= dy+4) || (dz >= dy+4)) return true;
return false; return false;
} }
@ -152,60 +152,61 @@ public class TreeCutting
{ {
if((Compat.canChop(broken_state))) return Compat.chop(world, broken_state, startPos, max_blocks_to_break, without_target_block); if((Compat.canChop(broken_state))) return Compat.chop(world, broken_state, startPos, max_blocks_to_break, without_target_block);
if(!BlockCategories.isLog(broken_state)) return 0; if(!BlockCategories.isLog(broken_state)) return 0;
final long ymin = startPos.getY();
final long max_leaf_distance = 6;
Set<BlockPos> checked = new HashSet<BlockPos>(); Set<BlockPos> checked = new HashSet<BlockPos>();
ArrayList<BlockPos> to_break = new ArrayList<BlockPos>(); ArrayList<BlockPos> to_break = new ArrayList<BlockPos>();
ArrayList<BlockPos> to_decay = new ArrayList<BlockPos>(); ArrayList<BlockPos> to_decay = new ArrayList<BlockPos>();
checked.add(startPos);
// Initial simple layer-up search of same logs. This forms the base corpus, and only leaves and
// leaf-enclosed logs attached to this corpus may be broken/decayed.
{ {
LinkedList<BlockPos> queue = new LinkedList<BlockPos>(); LinkedList<BlockPos> queue = new LinkedList<BlockPos>();
LinkedList<BlockPos> upqueue = new LinkedList<BlockPos>();
queue.add(startPos); queue.add(startPos);
int cutlevel = 0;
int steps_left = max_log_tracing_steps; int steps_left = max_log_tracing_steps;
IBlockState tracked_leaves_state = null; IBlockState tracked_leaves_state = null;
while(!queue.isEmpty() && (--steps_left >= 0)) { while(!queue.isEmpty() && (--steps_left >= 0) && (to_break.size()<max_blocks_to_break)) {
final BlockPos pos = queue.removeFirst(); final BlockPos pos = queue.removeFirst();
if(checked.contains(pos)) continue;
checked.add(pos);
if(too_far(startPos, pos)) continue;
// Vertical search // Vertical search
final BlockPos uppos = pos.up(); final BlockPos uppos = pos.up();
if(too_far(startPos, uppos)) { checked.add(uppos); continue; }
final IBlockState upstate = world.getBlockState(uppos); final IBlockState upstate = world.getBlockState(uppos);
if(!checked.contains(uppos)) { if(BlockCategories.isSameLog(upstate, broken_state)) {
checked.add(uppos); queue.add(uppos);
if(BlockCategories.isSameLog(upstate, broken_state)) { to_break.add(uppos);
// Up is log steps_left = max_log_tracing_steps;
upqueue.add(uppos); } else {
to_break.add(uppos); boolean isleaf = BlockCategories.isLeaves(upstate);
steps_left = max_log_tracing_steps; if(isleaf || world.isAirBlock(uppos) || (upstate.getBlock() instanceof BlockVine)) {
} else { if(isleaf) {
boolean isleaf = BlockCategories.isLeaves(upstate); if(tracked_leaves_state==null) {
if(isleaf || world.isAirBlock(uppos) || (upstate.getBlock() instanceof BlockVine)) { tracked_leaves_state=upstate;
if(isleaf) { to_decay.add(uppos);
if(tracked_leaves_state==null) { queue.add(uppos);
tracked_leaves_state=upstate; } else if(BlockCategories.isSameLeaves(upstate, tracked_leaves_state)) {
to_decay.add(uppos); to_decay.add(uppos);
} else if(BlockCategories.isSameLeaves(upstate, tracked_leaves_state)) { queue.add(uppos);
to_decay.add(uppos); } else {
} checked.add(uppos); // no block of interest
} }
// Up is air, check adjacent for diagonal up (e.g. Accacia) } else {
for(Vec3i v:hoffsets) { checked.add(uppos);
final BlockPos p = uppos.add(v); }
if(checked.contains(p)) continue; // Up is air, check adjacent for diagonal up (e.g. Accacia)
checked.add(p); for(Vec3i v:hoffsets) {
final IBlockState st = world.getBlockState(p); final BlockPos p = uppos.add(v);
final Block bl = st.getBlock(); final IBlockState st = world.getBlockState(p);
if(BlockCategories.isSameLog(st, broken_state)) { if(BlockCategories.isSameLog(st, broken_state)) {
queue.add(p); queue.add(p);
to_break.add(p); to_break.add(p);
} else if(BlockCategories.isLeaves(st)) { } else if(BlockCategories.isLeaves(st)) {
if((tracked_leaves_state==null) || (BlockCategories.isSameLeaves(st, tracked_leaves_state))) { if(tracked_leaves_state==null) {
to_decay.add(p); tracked_leaves_state=st;
} to_decay.add(p);
} else if(BlockCategories.isSameLeaves(st, tracked_leaves_state)) {
to_decay.add(p);
} else {
checked.add(uppos);
} }
} else {
checked.add(uppos);
} }
} }
} }
@ -214,63 +215,63 @@ public class TreeCutting
for(Vec3i v:hoffsets) { for(Vec3i v:hoffsets) {
final BlockPos p = pos.add(v); final BlockPos p = pos.add(v);
if(checked.contains(p)) continue; if(checked.contains(p)) continue;
checked.add(p);
final IBlockState st = world.getBlockState(p); final IBlockState st = world.getBlockState(p);
final Block bl = st.getBlock();
if(BlockCategories.isSameLog(st, broken_state)) { if(BlockCategories.isSameLog(st, broken_state)) {
queue.add(p); queue.add(p);
to_break.add(p); to_break.add(p);
} else if(BlockCategories.isLeaves(st)) { } else if(BlockCategories.isLeaves(st)) {
if((tracked_leaves_state==null) || (BlockCategories.isSameLeaves(st, tracked_leaves_state))) { if((tracked_leaves_state==null) || (BlockCategories.isSameLeaves(st, tracked_leaves_state))) {
to_decay.add(p); to_decay.add(p);
} else {
checked.add(p);
} }
} else {
checked.add(p);
} }
} }
if(queue.isEmpty() && (!upqueue.isEmpty())) { }
queue = upqueue; }
upqueue = new LinkedList<BlockPos>(); // Determine lose logs between the leafs
++cutlevel; {
for(BlockPos pos:to_decay) {
int distance = 2;
to_break.addAll(findBlocksAround(world, pos, broken_state, checked, distance));
}
if(!to_decay.isEmpty()) {
final IBlockState leaf_type_state = world.getBlockState(to_decay.get(0));
final ArrayList<BlockPos> leafs = to_decay;
to_decay = new ArrayList<BlockPos>();
for(BlockPos pos:leafs) {
int dist = 3;
to_decay.add(pos);
to_decay.addAll(findBlocksAround(world, pos, leaf_type_state, checked, dist));
} }
} }
} }
// Break blocks
{ {
// Determine lose logs between the leafs if(without_target_block) {
checked.remove(startPos);
} else {
to_break.add(startPos);
}
int num_broken = 0;
Collections.reverse(to_break);
for(BlockPos pos:to_break) {
if(++num_broken > max_blocks_to_break) break;
IBlockState state = world.getBlockState(pos);
world.setBlockToAir(pos);
state.getBlock().dropBlockAsItem(world, pos, state, 0);
}
for(BlockPos pos:to_decay) { for(BlockPos pos:to_decay) {
int dist = 1; if(++num_broken > max_blocks_to_break) break;
to_break.addAll(findBlocksAround(world, pos, broken_state, checked, dist)); IBlockState state = world.getBlockState(pos);
world.setBlockToAir(pos);
state.getBlock().dropBlockAsItem(world, pos, state, 0);
} }
} }
if(!to_decay.isEmpty()) { // And the bill.
final IBlockState leaf_type_state = world.getBlockState(to_decay.get(0));
final ArrayList<BlockPos> leafs = to_decay;
to_decay = new ArrayList<BlockPos>();
for(BlockPos pos:leafs) {
int dist = 2;
to_decay.add(pos);
to_decay.addAll(findBlocksAround(world, pos, leaf_type_state, checked, dist));
}
}
if(without_target_block) {
checked.remove(startPos);
} else {
to_break.add(startPos);
}
int num_broken = 0;
Collections.reverse(to_break);
for(BlockPos pos:to_break) {
if(++num_broken > max_blocks_to_break) break;
IBlockState state = world.getBlockState(pos);
world.setBlockToAir(pos);
state.getBlock().dropBlockAsItem(world, pos, state, 0);
}
for(BlockPos pos:to_decay) {
if(++num_broken > max_blocks_to_break) break;
IBlockState state = world.getBlockState(pos);
world.setBlockToAir(pos);
state.getBlock().dropBlockAsItem(world, pos, state, 0);
}
{ {
// And now the bill.
return MathHelper.clamp(((to_break.size()*6/5)+(to_decay.size()/10)-1), 1, 65535); return MathHelper.clamp(((to_break.size()*6/5)+(to_decay.size()/10)-1), 1, 65535);
} }
} }

View file

@ -128,22 +128,22 @@
} }
}, },
{ {
"from": [4, 9.5, -2], "from": [4, 9.5, 0],
"to": [5, 10.5, -0.5], "to": [5, 10.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [12, 2.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [12, 2.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [11, 5.5, 12, 6.5], "texture": "#sh"}, "north": {"uv": [11, 5.5, 12, 6.5], "texture": "#sh"},
"east": {"uv": [16, 5.5, 16, 6.5], "texture": "#sh"}, "east": {"uv": [15.5, 5.5, 16, 6.5], "texture": "#sh"},
"south": {"uv": [4, 5.5, 5, 6.5], "texture": "#sh"}, "south": {"uv": [4, 5.5, 5, 6.5], "texture": "#sh"},
"west": {"uv": [0, 5.5, 0, 6.5], "texture": "#sh"}, "west": {"uv": [0, 5.5, 0.5, 6.5], "texture": "#sh"},
"up": {"uv": [4, 0, 5, 0], "texture": "#sh"}, "up": {"uv": [4, 0, 5, 0.5], "texture": "#sh"},
"down": {"uv": [4, 16, 5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [4, 15.5, 5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [3, 7, 0.5], "from": [3, 7, 1.5],
"to": [3.5, 9, 7], "to": [3.5, 9, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [2.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [2.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [12.5, 7, 13, 9], "texture": "#sh"}, "north": {"uv": [12.5, 7, 13, 9], "texture": "#sh"},
"east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"}, "east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"},
@ -154,9 +154,9 @@
} }
}, },
{ {
"from": [2.5, 6, -0.5], "from": [2.5, 6, 0.5],
"to": [6.5, 10, 0.5], "to": [6.5, 10, 1.5],
"rotation": {"angle": 0, "axis": "y", "origin": [12.5, 1, 6.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [12.5, 1, 7.5]},
"faces": { "faces": {
"north": {"uv": [11, 11, 15, 15], "texture": "#sh"}, "north": {"uv": [11, 11, 15, 15], "texture": "#sh"},
"east": {"uv": [15.5, 6, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 10], "texture": "#sh"},
@ -167,113 +167,113 @@
} }
}, },
{ {
"from": [2.5, 9, -2], "from": [2.5, 9, 0],
"to": [3.5, 10, -0.5], "to": [3.5, 10, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [10.5, 2, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [10.5, 2, 6.5]},
"faces": { "faces": {
"north": {"uv": [12.5, 6, 13.5, 7], "texture": "#sh"}, "north": {"uv": [12.5, 6, 13.5, 7], "texture": "#sh"},
"east": {"uv": [16, 6, 16, 7], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 7], "texture": "#sh"},
"south": {"uv": [2.5, 6, 3.5, 7], "texture": "#sh"}, "south": {"uv": [2.5, 6, 3.5, 7], "texture": "#sh"},
"west": {"uv": [0, 6, 0, 7], "texture": "#sh"}, "west": {"uv": [0, 6, 0.5, 7], "texture": "#sh"},
"up": {"uv": [3, 2, 4, 3], "texture": "#sh"}, "up": {"uv": [2.5, 0, 3.5, 0.5], "texture": "#sh"},
"down": {"uv": [2.5, 16, 3.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [2.5, 15.5, 3.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [2, 7.5, -2], "from": [2, 7.5, 0],
"to": [3, 8.5, -0.5], "to": [3, 8.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [10, 0.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [10, 0.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [13, 7.5, 14, 8.5], "texture": "#sh"}, "north": {"uv": [13, 7.5, 14, 8.5], "texture": "#sh"},
"east": {"uv": [16, 7.5, 16, 8.5], "texture": "#sh"}, "east": {"uv": [15.5, 7.5, 16, 8.5], "texture": "#sh"},
"south": {"uv": [2, 7.5, 3, 8.5], "texture": "#sh"}, "south": {"uv": [2, 7.5, 3, 8.5], "texture": "#sh"},
"west": {"uv": [0, 7.5, 0, 8.5], "texture": "#sh"}, "west": {"uv": [0, 7.5, 0.5, 8.5], "texture": "#sh"},
"up": {"uv": [2, 0, 3, 0], "texture": "#sh"}, "up": {"uv": [2, 0, 3, 0.5], "texture": "#sh"},
"down": {"uv": [2, 16, 3, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [2, 15.5, 3, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [2.5, 6, -2], "from": [2.5, 6, 0],
"to": [3.5, 7, -0.5], "to": [3.5, 7, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [10.5, -1, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [10.5, -1, 6.5]},
"faces": { "faces": {
"north": {"uv": [12.5, 9, 13.5, 10], "texture": "#sh"}, "north": {"uv": [12.5, 9, 13.5, 10], "texture": "#sh"},
"east": {"uv": [16, 9, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 9, 16, 10], "texture": "#sh"},
"south": {"uv": [2.5, 9, 3.5, 10], "texture": "#sh"}, "south": {"uv": [2.5, 9, 3.5, 10], "texture": "#sh"},
"west": {"uv": [0, 9, 0, 10], "texture": "#sh"}, "west": {"uv": [0, 9, 0.5, 10], "texture": "#sh"},
"up": {"uv": [2.5, 0, 3.5, 0], "texture": "#sh"}, "up": {"uv": [2.5, 0, 3.5, 0.5], "texture": "#sh"},
"down": {"uv": [2.5, 16, 3.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [2.5, 15.5, 3.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [4, 5.5, -2], "from": [4, 5.5, 0],
"to": [5, 6.5, -0.5], "to": [5, 6.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [12, -1.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [12, -1.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [11, 9.5, 12, 10.5], "texture": "#sh"}, "north": {"uv": [11, 9.5, 12, 10.5], "texture": "#sh"},
"east": {"uv": [16, 9.5, 16, 10.5], "texture": "#sh"}, "east": {"uv": [15.5, 9.5, 16, 10.5], "texture": "#sh"},
"south": {"uv": [4, 9.5, 5, 10.5], "texture": "#sh"}, "south": {"uv": [4, 9.5, 5, 10.5], "texture": "#sh"},
"west": {"uv": [0, 9.5, 0, 10.5], "texture": "#sh"}, "west": {"uv": [0, 9.5, 0.5, 10.5], "texture": "#sh"},
"up": {"uv": [4, 0, 5, 0], "texture": "#sh"}, "up": {"uv": [4, 0, 5, 0.5], "texture": "#sh"},
"down": {"uv": [4, 16, 5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [4, 15.5, 5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [5.5, 6, -2], "from": [5.5, 6, 0],
"to": [6.5, 7, -0.5], "to": [6.5, 7, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [13.5, -1, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [13.5, -1, 6.5]},
"faces": { "faces": {
"north": {"uv": [9.5, 9, 10.5, 10], "texture": "#sh"}, "north": {"uv": [9.5, 9, 10.5, 10], "texture": "#sh"},
"east": {"uv": [16, 9, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 9, 16, 10], "texture": "#sh"},
"south": {"uv": [5.5, 9, 6.5, 10], "texture": "#sh"}, "south": {"uv": [5.5, 9, 6.5, 10], "texture": "#sh"},
"west": {"uv": [0, 9, 0, 10], "texture": "#sh"}, "west": {"uv": [0, 9, 0.5, 10], "texture": "#sh"},
"up": {"uv": [5.5, 0, 6.5, 0], "texture": "#sh"}, "up": {"uv": [5.5, 0, 6.5, 0.5], "texture": "#sh"},
"down": {"uv": [5.5, 16, 6.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [5.5, 15.5, 6.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [5.5, 9, -2], "from": [5.5, 9, 0],
"to": [6.5, 10, -0.5], "to": [6.5, 10, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [13.5, 2, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [13.5, 2, 6.5]},
"faces": { "faces": {
"north": {"uv": [9.5, 6, 10.5, 7], "texture": "#sh"}, "north": {"uv": [9.5, 6, 10.5, 7], "texture": "#sh"},
"east": {"uv": [16, 6, 16, 7], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 7], "texture": "#sh"},
"south": {"uv": [5.5, 6, 6.5, 7], "texture": "#sh"}, "south": {"uv": [5.5, 6, 6.5, 7], "texture": "#sh"},
"west": {"uv": [0, 6, 0, 7], "texture": "#sh"}, "west": {"uv": [0, 6, 0.5, 7], "texture": "#sh"},
"up": {"uv": [5.5, 0, 6.5, 0], "texture": "#sh"}, "up": {"uv": [5.5, 0, 6.5, 0.5], "texture": "#sh"},
"down": {"uv": [5.5, 16, 6.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [5.5, 15.5, 6.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [6, 7.5, -2], "from": [6, 7.5, 0],
"to": [7, 8.5, -0.5], "to": [7, 8.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [14, 0.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [14, 0.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [9, 7.5, 10, 8.5], "texture": "#sh"}, "north": {"uv": [9, 7.5, 10, 8.5], "texture": "#sh"},
"east": {"uv": [16, 7.5, 16, 8.5], "texture": "#sh"}, "east": {"uv": [15.5, 7.5, 16, 8.5], "texture": "#sh"},
"south": {"uv": [6, 7.5, 7, 8.5], "texture": "#sh"}, "south": {"uv": [6, 7.5, 7, 8.5], "texture": "#sh"},
"west": {"uv": [0, 7.5, 0, 8.5], "texture": "#sh"}, "west": {"uv": [0, 7.5, 0.5, 8.5], "texture": "#sh"},
"up": {"uv": [6, 0, 7, 0], "texture": "#sh"}, "up": {"uv": [6, 0, 7, 0.5], "texture": "#sh"},
"down": {"uv": [6, 16, 7, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [6, 15.5, 7, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [5.5, 7, 0.5], "from": [5.5, 7, 1.5],
"to": [6, 9, 7], "to": [6, 9, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [5.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [5.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [10, 7, 10.5, 9], "texture": "#sh"}, "north": {"uv": [10, 7, 10.5, 9], "texture": "#sh"},
"east": {"uv": [8, 7, 14.5, 9], "texture": "#sh"}, "east": {"uv": [8, 7, 14.5, 9], "texture": "#sh"},
"south": {"uv": [5.5, 7, 6, 9], "texture": "#sh"}, "south": {"uv": [5.5, 7, 6, 9], "texture": "#sh"},
"west": {"uv": [0.5, 7, 7, 9], "texture": "#sh"}, "west": {"uv": [0.5, 7, 7, 9], "texture": "#sh"},
"up": {"uv": [5, 2, 11.5, 2.5], "texture": "#sh"}, "up": {"uv": [5, 2, 11.5, 2.5], "rotation": 90, "texture": "#sh"},
"down": {"uv": [5.5, 9, 6, 15.5], "rotation": 270, "texture": "#sh"} "down": {"uv": [5.5, 9, 6, 15.5], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [3.5, 6.5, 0.5], "from": [3.5, 6.5, 1.5],
"to": [5.5, 9.5, 7], "to": [5.5, 9.5, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [4.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [4.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [10.5, 6.5, 12.5, 9.5], "texture": "#sh"}, "north": {"uv": [10.5, 6.5, 12.5, 9.5], "texture": "#sh"},
"east": {"uv": [9, 6.5, 15.5, 9.5], "texture": "#sh"}, "east": {"uv": [9, 6.5, 15.5, 9.5], "texture": "#sh"},
@ -284,9 +284,9 @@
} }
}, },
{ {
"from": [12.5, 7, 0.5], "from": [12.5, 7, 1.5],
"to": [13, 9, 7], "to": [13, 9, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [12.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [12.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [3, 7, 3.5, 9], "texture": "#sh"}, "north": {"uv": [3, 7, 3.5, 9], "texture": "#sh"},
"east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"}, "east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"},
@ -297,9 +297,9 @@
} }
}, },
{ {
"from": [10.5, 6.5, 0.5], "from": [10.5, 6.5, 1.5],
"to": [12.5, 9.5, 7], "to": [12.5, 9.5, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [11.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [11.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [3.5, 6.5, 5.5, 9.5], "texture": "#sh"}, "north": {"uv": [3.5, 6.5, 5.5, 9.5], "texture": "#sh"},
"east": {"uv": [9, 6.5, 15.5, 9.5], "texture": "#sh"}, "east": {"uv": [9, 6.5, 15.5, 9.5], "texture": "#sh"},
@ -310,9 +310,9 @@
} }
}, },
{ {
"from": [10, 7, 0.5], "from": [10, 7, 1.5],
"to": [10.5, 9, 7], "to": [10.5, 9, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [9.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [9.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [5.5, 7, 6, 9], "texture": "#sh"}, "north": {"uv": [5.5, 7, 6, 9], "texture": "#sh"},
"east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"}, "east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"},
@ -323,9 +323,9 @@
} }
}, },
{ {
"from": [9.5, 6, -0.5], "from": [9.5, 6, 0.5],
"to": [13.5, 10, 0.5], "to": [13.5, 10, 1.5],
"rotation": {"angle": 0, "axis": "y", "origin": [19.5, 1, 6.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [19.5, 1, 7.5]},
"faces": { "faces": {
"north": {"uv": [10, 12, 14, 16], "texture": "#sh"}, "north": {"uv": [10, 12, 14, 16], "texture": "#sh"},
"east": {"uv": [15.5, 6, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 10], "texture": "#sh"},
@ -336,107 +336,107 @@
} }
}, },
{ {
"from": [12.5, 9, -2], "from": [12.5, 9, 0],
"to": [13.5, 10, -0.5], "to": [13.5, 10, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [20.5, 2, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [20.5, 2, 6.5]},
"faces": { "faces": {
"north": {"uv": [2.5, 6, 3.5, 7], "texture": "#sh"}, "north": {"uv": [2.5, 6, 3.5, 7], "texture": "#sh"},
"east": {"uv": [16, 6, 16, 7], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 7], "texture": "#sh"},
"south": {"uv": [12.5, 6, 13.5, 7], "texture": "#sh"}, "south": {"uv": [12.5, 6, 13.5, 7], "texture": "#sh"},
"west": {"uv": [0, 6, 0, 7], "texture": "#sh"}, "west": {"uv": [0, 6, 0.5, 7], "texture": "#sh"},
"up": {"uv": [12.5, 0, 13.5, 0], "texture": "#sh"}, "up": {"uv": [12.5, 0, 13.5, 0.5], "texture": "#sh"},
"down": {"uv": [12.5, 16, 13.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [12.5, 15.5, 13.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [11, 9.5, -2], "from": [11, 9.5, 0],
"to": [12, 10.5, -0.5], "to": [12, 10.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [19, 2.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [19, 2.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [4, 5.5, 5, 6.5], "texture": "#sh"}, "north": {"uv": [4, 5.5, 5, 6.5], "texture": "#sh"},
"east": {"uv": [16, 5.5, 16, 6.5], "texture": "#sh"}, "east": {"uv": [15.5, 5.5, 16, 6.5], "texture": "#sh"},
"south": {"uv": [11, 5.5, 12, 6.5], "texture": "#sh"}, "south": {"uv": [11, 5.5, 12, 6.5], "texture": "#sh"},
"west": {"uv": [0, 5.5, 0, 6.5], "texture": "#sh"}, "west": {"uv": [0, 5.5, 0.5, 6.5], "texture": "#sh"},
"up": {"uv": [11, 0, 12, 0], "texture": "#sh"}, "up": {"uv": [11, 0, 12, 0.5], "texture": "#sh"},
"down": {"uv": [11, 16, 12, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [11, 15.5, 12, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [9.5, 9, -2], "from": [9.5, 9, 0],
"to": [10.5, 10, -0.5], "to": [10.5, 10, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [17.5, 2, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [17.5, 2, 6.5]},
"faces": { "faces": {
"north": {"uv": [5.5, 6, 6.5, 7], "texture": "#sh"}, "north": {"uv": [5.5, 6, 6.5, 7], "texture": "#sh"},
"east": {"uv": [16, 6, 16, 7], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 7], "texture": "#sh"},
"south": {"uv": [9.5, 6, 10.5, 7], "texture": "#sh"}, "south": {"uv": [9.5, 6, 10.5, 7], "texture": "#sh"},
"west": {"uv": [0, 6, 0, 7], "texture": "#sh"}, "west": {"uv": [0, 6, 0.5, 7], "texture": "#sh"},
"up": {"uv": [9.5, 0, 10.5, 0], "texture": "#sh"}, "up": {"uv": [9.5, 0, 10.5, 0.5], "texture": "#sh"},
"down": {"uv": [9.5, 16, 10.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [9.5, 15.5, 10.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [9, 7.5, -2], "from": [9, 7.5, 0],
"to": [10, 8.5, -0.5], "to": [10, 8.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [17, 0.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [17, 0.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [6, 7.5, 7, 8.5], "texture": "#sh"}, "north": {"uv": [6, 7.5, 7, 8.5], "texture": "#sh"},
"east": {"uv": [16, 7.5, 16, 8.5], "texture": "#sh"}, "east": {"uv": [15.5, 7.5, 16, 8.5], "texture": "#sh"},
"south": {"uv": [9, 7.5, 10, 8.5], "texture": "#sh"}, "south": {"uv": [9, 7.5, 10, 8.5], "texture": "#sh"},
"west": {"uv": [0, 7.5, 0, 8.5], "texture": "#sh"}, "west": {"uv": [0, 7.5, 0.5, 8.5], "texture": "#sh"},
"up": {"uv": [9, 0, 10, 0], "texture": "#sh"}, "up": {"uv": [9, 0, 10, 0.5], "texture": "#sh"},
"down": {"uv": [9, 16, 10, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [9, 15.5, 10, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [9.5, 6, -2], "from": [9.5, 6, 0],
"to": [10.5, 7, -0.5], "to": [10.5, 7, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [17.5, -1, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [17.5, -1, 6.5]},
"faces": { "faces": {
"north": {"uv": [5.5, 9, 6.5, 10], "texture": "#sh"}, "north": {"uv": [5.5, 9, 6.5, 10], "texture": "#sh"},
"east": {"uv": [16, 9, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 9, 16, 10], "texture": "#sh"},
"south": {"uv": [9.5, 9, 10.5, 10], "texture": "#sh"}, "south": {"uv": [9.5, 9, 10.5, 10], "texture": "#sh"},
"west": {"uv": [0, 9, 0, 10], "texture": "#sh"}, "west": {"uv": [0, 9, 0.5, 10], "texture": "#sh"},
"up": {"uv": [9.5, 0, 10.5, 0], "texture": "#sh"}, "up": {"uv": [9.5, 0, 10.5, 0.5], "texture": "#sh"},
"down": {"uv": [9.5, 16, 10.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [9.5, 15.5, 10.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [11, 5.5, -2], "from": [11, 5.5, 0],
"to": [12, 6.5, -0.5], "to": [12, 6.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [19, -1.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [19, -1.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [4, 9.5, 5, 10.5], "texture": "#sh"}, "north": {"uv": [4, 9.5, 5, 10.5], "texture": "#sh"},
"east": {"uv": [16, 9.5, 16, 10.5], "texture": "#sh"}, "east": {"uv": [15.5, 9.5, 16, 10.5], "texture": "#sh"},
"south": {"uv": [11, 9.5, 12, 10.5], "texture": "#sh"}, "south": {"uv": [11, 9.5, 12, 10.5], "texture": "#sh"},
"west": {"uv": [0, 9.5, 0, 10.5], "texture": "#sh"}, "west": {"uv": [0, 9.5, 0.5, 10.5], "texture": "#sh"},
"up": {"uv": [11, 0, 12, 0], "texture": "#sh"}, "up": {"uv": [11, 0, 12, 0.5], "texture": "#sh"},
"down": {"uv": [11, 16, 12, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [11, 15.5, 12, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [12.5, 6, -2], "from": [12.5, 6, 0],
"to": [13.5, 7, -0.5], "to": [13.5, 7, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [20.5, -1, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [20.5, -1, 6.5]},
"faces": { "faces": {
"north": {"uv": [2.5, 9, 3.5, 10], "texture": "#sh"}, "north": {"uv": [2.5, 9, 3.5, 10], "texture": "#sh"},
"east": {"uv": [16, 9, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 9, 16, 10], "texture": "#sh"},
"south": {"uv": [12.5, 9, 13.5, 10], "texture": "#sh"}, "south": {"uv": [12.5, 9, 13.5, 10], "texture": "#sh"},
"west": {"uv": [0, 9, 0, 10], "texture": "#sh"}, "west": {"uv": [0, 9, 0.5, 10], "texture": "#sh"},
"up": {"uv": [12.5, 0, 13.5, 0], "texture": "#sh"}, "up": {"uv": [12.5, 0, 13.5, 0.5], "texture": "#sh"},
"down": {"uv": [12.5, 16, 13.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [12.5, 15.5, 13.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [13, 7.5, -2], "from": [13, 7.5, 0],
"to": [14, 8.5, -0.5], "to": [14, 8.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [21, 0.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [21, 0.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [2, 7.5, 3, 8.5], "texture": "#sh"}, "north": {"uv": [2, 7.5, 3, 8.5], "texture": "#sh"},
"east": {"uv": [16, 7.5, 16, 8.5], "texture": "#sh"}, "east": {"uv": [15.5, 7.5, 16, 8.5], "texture": "#sh"},
"south": {"uv": [13, 7.5, 14, 8.5], "texture": "#sh"}, "south": {"uv": [13, 7.5, 14, 8.5], "texture": "#sh"},
"west": {"uv": [0, 7.5, 0, 8.5], "texture": "#sh"}, "west": {"uv": [0, 7.5, 0.5, 8.5], "texture": "#sh"},
"up": {"uv": [13, 0, 14, 0], "texture": "#sh"}, "up": {"uv": [13, 0, 14, 0.5], "texture": "#sh"},
"down": {"uv": [13, 16, 14, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [13, 15.5, 14, 16], "rotation": 270, "texture": "#sh"}
} }
} }
], ],

View file

@ -2,7 +2,7 @@
org.gradle.daemon=false org.gradle.daemon=false
org.gradle.jvmargs=-Xmx8G org.gradle.jvmargs=-Xmx8G
version_minecraft=1.14.4 version_minecraft=1.14.4
version_forge_minecraft=1.14.4-28.1.68 version_forge_minecraft=1.14.4-28.1.79
version_fml_mappings=20190719-1.14.3 version_fml_mappings=20190719-1.14.3
version_jei=1.14.4:6.0.0.10 version_jei=1.14.4:6.0.0.10
version_engineersdecor=1.0.15-b4 version_engineersdecor=1.0.16-b2

View file

@ -1,9 +1,10 @@
{ {
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.14.4": { "1.14.4": {
"1.0.16-b1": "[U] Updated to Forge 1.14.4-28.1.79/20190719-1.14.3.\n[A] Added Fluid Collection Funnel.",
"1.0.15-b3": "[A] Added Small Block Breaker.\n[M] Mineral Smelter fluid handler/transfer added.", "1.0.15-b3": "[A] Added Small Block Breaker.\n[M] Mineral Smelter fluid handler/transfer added.",
"1.0.15-b2": "[!] Forge version requirement set to 1.14.4-28.1.68 or higher.\n[A] Added Factory Block Placer and Planter.\n[A] Added Small Tree Cutter.", "1.0.15-b2": "[!] Forge version requirement set to 1.14.4-28.1.68 or higher.\n[A] Added Factory Block Placer and Planter.\n[A] Added Small Tree Cutter.",
"1.0.15-b1": "[A] Added Floor Edge Light.\n[U] Updated to Forge1.14.4-28.1.68/20190719-1.14.3.", "1.0.15-b1": "[A] Added Floor Edge Light.\n[U] Updated to Forge 1.14.4-28.1.68/20190719-1.14.3.",
"1.0.14-b1": "[U] Updated to Forge 1.14.4-28.1.40/20190719-1.14.3.\n[A] Factory Hopper added (configurable hopper and item collector).\n[M] Switched to integrated loot table generation.\n[M] Lang file zh_cn updated (scikirbypoke, PR#53).", "1.0.14-b1": "[U] Updated to Forge 1.14.4-28.1.40/20190719-1.14.3.\n[A] Factory Hopper added (configurable hopper and item collector).\n[M] Switched to integrated loot table generation.\n[M] Lang file zh_cn updated (scikirbypoke, PR#53).",
"1.0.13-b2": "[A] Added Steel Mesh Fence.\n[A] Added Broad Window Sill.", "1.0.13-b2": "[A] Added Steel Mesh Fence.\n[A] Added Broad Window Sill.",
"1.0.12-b3": "[U] Updated to Forge 1.14.4-28.1.10/20190719-1.14.3.\n[A] Crafting Table: Added recipe collision resolver, also applies to crafting history refabrication.\n[A] Crafting Table: Added rendering of placed items on the top surface of the table.\n[A] Waterlogging of non-full-blocks added.", "1.0.12-b3": "[U] Updated to Forge 1.14.4-28.1.10/20190719-1.14.3.\n[A] Crafting Table: Added recipe collision resolver, also applies to crafting history refabrication.\n[A] Crafting Table: Added rendering of placed items on the top surface of the table.\n[A] Waterlogging of non-full-blocks added.",
@ -30,6 +31,6 @@
}, },
"promos": { "promos": {
"1.14.4-recommended": "", "1.14.4-recommended": "",
"1.14.4-latest": "1.0.15-b3" "1.14.4-latest": "1.0.16-b1"
} }
} }

View file

@ -11,7 +11,10 @@ Mod sources for Minecraft version 1.14.4.
## Version history ## Version history
~ v1.0.15-b4 [A] Added Fluid Collection Funnel. ~ v1.0.16-b2 [F] Fixed Small Block Breaker active model updated.
- v1.0.16-b1 [U] Updated to Forge 1.14.4-28.1.79/20190719-1.14.3.
[A] Added Fluid Collection Funnel.
- v1.0.15-b3 [A] Added Small Block Breaker. - v1.0.15-b3 [A] Added Small Block Breaker.
[M] Mineral Smelter fluid handler/transfer added. [M] Mineral Smelter fluid handler/transfer added.
@ -21,7 +24,7 @@ Mod sources for Minecraft version 1.14.4.
[A] Added Small Tree Cutter. [A] Added Small Tree Cutter.
- v1.0.15-b1 [A] Added Floor Edge Light. - v1.0.15-b1 [A] Added Floor Edge Light.
[U] Updated to Forge1.14.4-28.1.68/20190719-1.14.3. [U] Updated to Forge 1.14.4-28.1.68/20190719-1.14.3.
- v1.0.14-b1 [U] Updated to Forge 1.14.4-28.1.40/20190719-1.14.3. - v1.0.14-b1 [U] Updated to Forge 1.14.4-28.1.40/20190719-1.14.3.
[A] Factory Hopper added (configurable hopper and item collector). [A] Factory Hopper added (configurable hopper and item collector).

View file

@ -128,22 +128,22 @@
} }
}, },
{ {
"from": [4, 9.5, -2], "from": [4, 9.5, 0],
"to": [5, 10.5, -0.5], "to": [5, 10.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [12, 2.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [12, 2.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [11, 5.5, 12, 6.5], "texture": "#sh"}, "north": {"uv": [11, 5.5, 12, 6.5], "texture": "#sh"},
"east": {"uv": [16, 5.5, 16, 6.5], "texture": "#sh"}, "east": {"uv": [15.5, 5.5, 16, 6.5], "texture": "#sh"},
"south": {"uv": [4, 5.5, 5, 6.5], "texture": "#sh"}, "south": {"uv": [4, 5.5, 5, 6.5], "texture": "#sh"},
"west": {"uv": [0, 5.5, 0, 6.5], "texture": "#sh"}, "west": {"uv": [0, 5.5, 0.5, 6.5], "texture": "#sh"},
"up": {"uv": [4, 0, 5, 0], "texture": "#sh"}, "up": {"uv": [4, 0, 5, 0.5], "texture": "#sh"},
"down": {"uv": [4, 16, 5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [4, 15.5, 5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [3, 7, 0.5], "from": [3, 7, 1.5],
"to": [3.5, 9, 7], "to": [3.5, 9, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [2.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [2.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [12.5, 7, 13, 9], "texture": "#sh"}, "north": {"uv": [12.5, 7, 13, 9], "texture": "#sh"},
"east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"}, "east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"},
@ -154,9 +154,9 @@
} }
}, },
{ {
"from": [2.5, 6, -0.5], "from": [2.5, 6, 0.5],
"to": [6.5, 10, 0.5], "to": [6.5, 10, 1.5],
"rotation": {"angle": 0, "axis": "y", "origin": [12.5, 1, 6.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [12.5, 1, 7.5]},
"faces": { "faces": {
"north": {"uv": [11, 11, 15, 15], "texture": "#sh"}, "north": {"uv": [11, 11, 15, 15], "texture": "#sh"},
"east": {"uv": [15.5, 6, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 10], "texture": "#sh"},
@ -167,113 +167,113 @@
} }
}, },
{ {
"from": [2.5, 9, -2], "from": [2.5, 9, 0],
"to": [3.5, 10, -0.5], "to": [3.5, 10, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [10.5, 2, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [10.5, 2, 6.5]},
"faces": { "faces": {
"north": {"uv": [12.5, 6, 13.5, 7], "texture": "#sh"}, "north": {"uv": [12.5, 6, 13.5, 7], "texture": "#sh"},
"east": {"uv": [16, 6, 16, 7], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 7], "texture": "#sh"},
"south": {"uv": [2.5, 6, 3.5, 7], "texture": "#sh"}, "south": {"uv": [2.5, 6, 3.5, 7], "texture": "#sh"},
"west": {"uv": [0, 6, 0, 7], "texture": "#sh"}, "west": {"uv": [0, 6, 0.5, 7], "texture": "#sh"},
"up": {"uv": [3, 2, 4, 3], "texture": "#sh"}, "up": {"uv": [2.5, 0, 3.5, 0.5], "texture": "#sh"},
"down": {"uv": [2.5, 16, 3.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [2.5, 15.5, 3.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [2, 7.5, -2], "from": [2, 7.5, 0],
"to": [3, 8.5, -0.5], "to": [3, 8.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [10, 0.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [10, 0.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [13, 7.5, 14, 8.5], "texture": "#sh"}, "north": {"uv": [13, 7.5, 14, 8.5], "texture": "#sh"},
"east": {"uv": [16, 7.5, 16, 8.5], "texture": "#sh"}, "east": {"uv": [15.5, 7.5, 16, 8.5], "texture": "#sh"},
"south": {"uv": [2, 7.5, 3, 8.5], "texture": "#sh"}, "south": {"uv": [2, 7.5, 3, 8.5], "texture": "#sh"},
"west": {"uv": [0, 7.5, 0, 8.5], "texture": "#sh"}, "west": {"uv": [0, 7.5, 0.5, 8.5], "texture": "#sh"},
"up": {"uv": [2, 0, 3, 0], "texture": "#sh"}, "up": {"uv": [2, 0, 3, 0.5], "texture": "#sh"},
"down": {"uv": [2, 16, 3, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [2, 15.5, 3, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [2.5, 6, -2], "from": [2.5, 6, 0],
"to": [3.5, 7, -0.5], "to": [3.5, 7, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [10.5, -1, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [10.5, -1, 6.5]},
"faces": { "faces": {
"north": {"uv": [12.5, 9, 13.5, 10], "texture": "#sh"}, "north": {"uv": [12.5, 9, 13.5, 10], "texture": "#sh"},
"east": {"uv": [16, 9, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 9, 16, 10], "texture": "#sh"},
"south": {"uv": [2.5, 9, 3.5, 10], "texture": "#sh"}, "south": {"uv": [2.5, 9, 3.5, 10], "texture": "#sh"},
"west": {"uv": [0, 9, 0, 10], "texture": "#sh"}, "west": {"uv": [0, 9, 0.5, 10], "texture": "#sh"},
"up": {"uv": [2.5, 0, 3.5, 0], "texture": "#sh"}, "up": {"uv": [2.5, 0, 3.5, 0.5], "texture": "#sh"},
"down": {"uv": [2.5, 16, 3.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [2.5, 15.5, 3.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [4, 5.5, -2], "from": [4, 5.5, 0],
"to": [5, 6.5, -0.5], "to": [5, 6.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [12, -1.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [12, -1.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [11, 9.5, 12, 10.5], "texture": "#sh"}, "north": {"uv": [11, 9.5, 12, 10.5], "texture": "#sh"},
"east": {"uv": [16, 9.5, 16, 10.5], "texture": "#sh"}, "east": {"uv": [15.5, 9.5, 16, 10.5], "texture": "#sh"},
"south": {"uv": [4, 9.5, 5, 10.5], "texture": "#sh"}, "south": {"uv": [4, 9.5, 5, 10.5], "texture": "#sh"},
"west": {"uv": [0, 9.5, 0, 10.5], "texture": "#sh"}, "west": {"uv": [0, 9.5, 0.5, 10.5], "texture": "#sh"},
"up": {"uv": [4, 0, 5, 0], "texture": "#sh"}, "up": {"uv": [4, 0, 5, 0.5], "texture": "#sh"},
"down": {"uv": [4, 16, 5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [4, 15.5, 5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [5.5, 6, -2], "from": [5.5, 6, 0],
"to": [6.5, 7, -0.5], "to": [6.5, 7, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [13.5, -1, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [13.5, -1, 6.5]},
"faces": { "faces": {
"north": {"uv": [9.5, 9, 10.5, 10], "texture": "#sh"}, "north": {"uv": [9.5, 9, 10.5, 10], "texture": "#sh"},
"east": {"uv": [16, 9, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 9, 16, 10], "texture": "#sh"},
"south": {"uv": [5.5, 9, 6.5, 10], "texture": "#sh"}, "south": {"uv": [5.5, 9, 6.5, 10], "texture": "#sh"},
"west": {"uv": [0, 9, 0, 10], "texture": "#sh"}, "west": {"uv": [0, 9, 0.5, 10], "texture": "#sh"},
"up": {"uv": [5.5, 0, 6.5, 0], "texture": "#sh"}, "up": {"uv": [5.5, 0, 6.5, 0.5], "texture": "#sh"},
"down": {"uv": [5.5, 16, 6.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [5.5, 15.5, 6.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [5.5, 9, -2], "from": [5.5, 9, 0],
"to": [6.5, 10, -0.5], "to": [6.5, 10, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [13.5, 2, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [13.5, 2, 6.5]},
"faces": { "faces": {
"north": {"uv": [9.5, 6, 10.5, 7], "texture": "#sh"}, "north": {"uv": [9.5, 6, 10.5, 7], "texture": "#sh"},
"east": {"uv": [16, 6, 16, 7], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 7], "texture": "#sh"},
"south": {"uv": [5.5, 6, 6.5, 7], "texture": "#sh"}, "south": {"uv": [5.5, 6, 6.5, 7], "texture": "#sh"},
"west": {"uv": [0, 6, 0, 7], "texture": "#sh"}, "west": {"uv": [0, 6, 0.5, 7], "texture": "#sh"},
"up": {"uv": [5.5, 0, 6.5, 0], "texture": "#sh"}, "up": {"uv": [5.5, 0, 6.5, 0.5], "texture": "#sh"},
"down": {"uv": [5.5, 16, 6.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [5.5, 15.5, 6.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [6, 7.5, -2], "from": [6, 7.5, 0],
"to": [7, 8.5, -0.5], "to": [7, 8.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [14, 0.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [14, 0.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [9, 7.5, 10, 8.5], "texture": "#sh"}, "north": {"uv": [9, 7.5, 10, 8.5], "texture": "#sh"},
"east": {"uv": [16, 7.5, 16, 8.5], "texture": "#sh"}, "east": {"uv": [15.5, 7.5, 16, 8.5], "texture": "#sh"},
"south": {"uv": [6, 7.5, 7, 8.5], "texture": "#sh"}, "south": {"uv": [6, 7.5, 7, 8.5], "texture": "#sh"},
"west": {"uv": [0, 7.5, 0, 8.5], "texture": "#sh"}, "west": {"uv": [0, 7.5, 0.5, 8.5], "texture": "#sh"},
"up": {"uv": [6, 0, 7, 0], "texture": "#sh"}, "up": {"uv": [6, 0, 7, 0.5], "texture": "#sh"},
"down": {"uv": [6, 16, 7, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [6, 15.5, 7, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [5.5, 7, 0.5], "from": [5.5, 7, 1.5],
"to": [6, 9, 7], "to": [6, 9, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [5.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [5.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [10, 7, 10.5, 9], "texture": "#sh"}, "north": {"uv": [10, 7, 10.5, 9], "texture": "#sh"},
"east": {"uv": [8, 7, 14.5, 9], "texture": "#sh"}, "east": {"uv": [8, 7, 14.5, 9], "texture": "#sh"},
"south": {"uv": [5.5, 7, 6, 9], "texture": "#sh"}, "south": {"uv": [5.5, 7, 6, 9], "texture": "#sh"},
"west": {"uv": [0.5, 7, 7, 9], "texture": "#sh"}, "west": {"uv": [0.5, 7, 7, 9], "texture": "#sh"},
"up": {"uv": [5, 2, 11.5, 2.5], "texture": "#sh"}, "up": {"uv": [5, 2, 11.5, 2.5], "rotation": 90, "texture": "#sh"},
"down": {"uv": [5.5, 9, 6, 15.5], "rotation": 270, "texture": "#sh"} "down": {"uv": [5.5, 9, 6, 15.5], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [3.5, 6.5, 0.5], "from": [3.5, 6.5, 1.5],
"to": [5.5, 9.5, 7], "to": [5.5, 9.5, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [4.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [4.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [10.5, 6.5, 12.5, 9.5], "texture": "#sh"}, "north": {"uv": [10.5, 6.5, 12.5, 9.5], "texture": "#sh"},
"east": {"uv": [9, 6.5, 15.5, 9.5], "texture": "#sh"}, "east": {"uv": [9, 6.5, 15.5, 9.5], "texture": "#sh"},
@ -284,9 +284,9 @@
} }
}, },
{ {
"from": [12.5, 7, 0.5], "from": [12.5, 7, 1.5],
"to": [13, 9, 7], "to": [13, 9, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [12.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [12.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [3, 7, 3.5, 9], "texture": "#sh"}, "north": {"uv": [3, 7, 3.5, 9], "texture": "#sh"},
"east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"}, "east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"},
@ -297,9 +297,9 @@
} }
}, },
{ {
"from": [10.5, 6.5, 0.5], "from": [10.5, 6.5, 1.5],
"to": [12.5, 9.5, 7], "to": [12.5, 9.5, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [11.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [11.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [3.5, 6.5, 5.5, 9.5], "texture": "#sh"}, "north": {"uv": [3.5, 6.5, 5.5, 9.5], "texture": "#sh"},
"east": {"uv": [9, 6.5, 15.5, 9.5], "texture": "#sh"}, "east": {"uv": [9, 6.5, 15.5, 9.5], "texture": "#sh"},
@ -310,9 +310,9 @@
} }
}, },
{ {
"from": [10, 7, 0.5], "from": [10, 7, 1.5],
"to": [10.5, 9, 7], "to": [10.5, 9, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [9.5, 1, 5]}, "rotation": {"angle": 0, "axis": "y", "origin": [9.5, 1, 6]},
"faces": { "faces": {
"north": {"uv": [5.5, 7, 6, 9], "texture": "#sh"}, "north": {"uv": [5.5, 7, 6, 9], "texture": "#sh"},
"east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"}, "east": {"uv": [9, 7, 15.5, 9], "texture": "#sh"},
@ -323,9 +323,9 @@
} }
}, },
{ {
"from": [9.5, 6, -0.5], "from": [9.5, 6, 0.5],
"to": [13.5, 10, 0.5], "to": [13.5, 10, 1.5],
"rotation": {"angle": 0, "axis": "y", "origin": [19.5, 1, 6.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [19.5, 1, 7.5]},
"faces": { "faces": {
"north": {"uv": [10, 12, 14, 16], "texture": "#sh"}, "north": {"uv": [10, 12, 14, 16], "texture": "#sh"},
"east": {"uv": [15.5, 6, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 10], "texture": "#sh"},
@ -336,107 +336,107 @@
} }
}, },
{ {
"from": [12.5, 9, -2], "from": [12.5, 9, 0],
"to": [13.5, 10, -0.5], "to": [13.5, 10, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [20.5, 2, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [20.5, 2, 6.5]},
"faces": { "faces": {
"north": {"uv": [2.5, 6, 3.5, 7], "texture": "#sh"}, "north": {"uv": [2.5, 6, 3.5, 7], "texture": "#sh"},
"east": {"uv": [16, 6, 16, 7], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 7], "texture": "#sh"},
"south": {"uv": [12.5, 6, 13.5, 7], "texture": "#sh"}, "south": {"uv": [12.5, 6, 13.5, 7], "texture": "#sh"},
"west": {"uv": [0, 6, 0, 7], "texture": "#sh"}, "west": {"uv": [0, 6, 0.5, 7], "texture": "#sh"},
"up": {"uv": [12.5, 0, 13.5, 0], "texture": "#sh"}, "up": {"uv": [12.5, 0, 13.5, 0.5], "texture": "#sh"},
"down": {"uv": [12.5, 16, 13.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [12.5, 15.5, 13.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [11, 9.5, -2], "from": [11, 9.5, 0],
"to": [12, 10.5, -0.5], "to": [12, 10.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [19, 2.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [19, 2.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [4, 5.5, 5, 6.5], "texture": "#sh"}, "north": {"uv": [4, 5.5, 5, 6.5], "texture": "#sh"},
"east": {"uv": [16, 5.5, 16, 6.5], "texture": "#sh"}, "east": {"uv": [15.5, 5.5, 16, 6.5], "texture": "#sh"},
"south": {"uv": [11, 5.5, 12, 6.5], "texture": "#sh"}, "south": {"uv": [11, 5.5, 12, 6.5], "texture": "#sh"},
"west": {"uv": [0, 5.5, 0, 6.5], "texture": "#sh"}, "west": {"uv": [0, 5.5, 0.5, 6.5], "texture": "#sh"},
"up": {"uv": [11, 0, 12, 0], "texture": "#sh"}, "up": {"uv": [11, 0, 12, 0.5], "texture": "#sh"},
"down": {"uv": [11, 16, 12, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [11, 15.5, 12, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [9.5, 9, -2], "from": [9.5, 9, 0],
"to": [10.5, 10, -0.5], "to": [10.5, 10, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [17.5, 2, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [17.5, 2, 6.5]},
"faces": { "faces": {
"north": {"uv": [5.5, 6, 6.5, 7], "texture": "#sh"}, "north": {"uv": [5.5, 6, 6.5, 7], "texture": "#sh"},
"east": {"uv": [16, 6, 16, 7], "texture": "#sh"}, "east": {"uv": [15.5, 6, 16, 7], "texture": "#sh"},
"south": {"uv": [9.5, 6, 10.5, 7], "texture": "#sh"}, "south": {"uv": [9.5, 6, 10.5, 7], "texture": "#sh"},
"west": {"uv": [0, 6, 0, 7], "texture": "#sh"}, "west": {"uv": [0, 6, 0.5, 7], "texture": "#sh"},
"up": {"uv": [9.5, 0, 10.5, 0], "texture": "#sh"}, "up": {"uv": [9.5, 0, 10.5, 0.5], "texture": "#sh"},
"down": {"uv": [9.5, 16, 10.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [9.5, 15.5, 10.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [9, 7.5, -2], "from": [9, 7.5, 0],
"to": [10, 8.5, -0.5], "to": [10, 8.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [17, 0.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [17, 0.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [6, 7.5, 7, 8.5], "texture": "#sh"}, "north": {"uv": [6, 7.5, 7, 8.5], "texture": "#sh"},
"east": {"uv": [16, 7.5, 16, 8.5], "texture": "#sh"}, "east": {"uv": [15.5, 7.5, 16, 8.5], "texture": "#sh"},
"south": {"uv": [9, 7.5, 10, 8.5], "texture": "#sh"}, "south": {"uv": [9, 7.5, 10, 8.5], "texture": "#sh"},
"west": {"uv": [0, 7.5, 0, 8.5], "texture": "#sh"}, "west": {"uv": [0, 7.5, 0.5, 8.5], "texture": "#sh"},
"up": {"uv": [9, 0, 10, 0], "texture": "#sh"}, "up": {"uv": [9, 0, 10, 0.5], "texture": "#sh"},
"down": {"uv": [9, 16, 10, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [9, 15.5, 10, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [9.5, 6, -2], "from": [9.5, 6, 0],
"to": [10.5, 7, -0.5], "to": [10.5, 7, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [17.5, -1, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [17.5, -1, 6.5]},
"faces": { "faces": {
"north": {"uv": [5.5, 9, 6.5, 10], "texture": "#sh"}, "north": {"uv": [5.5, 9, 6.5, 10], "texture": "#sh"},
"east": {"uv": [16, 9, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 9, 16, 10], "texture": "#sh"},
"south": {"uv": [9.5, 9, 10.5, 10], "texture": "#sh"}, "south": {"uv": [9.5, 9, 10.5, 10], "texture": "#sh"},
"west": {"uv": [0, 9, 0, 10], "texture": "#sh"}, "west": {"uv": [0, 9, 0.5, 10], "texture": "#sh"},
"up": {"uv": [9.5, 0, 10.5, 0], "texture": "#sh"}, "up": {"uv": [9.5, 0, 10.5, 0.5], "texture": "#sh"},
"down": {"uv": [9.5, 16, 10.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [9.5, 15.5, 10.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [11, 5.5, -2], "from": [11, 5.5, 0],
"to": [12, 6.5, -0.5], "to": [12, 6.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [19, -1.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [19, -1.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [4, 9.5, 5, 10.5], "texture": "#sh"}, "north": {"uv": [4, 9.5, 5, 10.5], "texture": "#sh"},
"east": {"uv": [16, 9.5, 16, 10.5], "texture": "#sh"}, "east": {"uv": [15.5, 9.5, 16, 10.5], "texture": "#sh"},
"south": {"uv": [11, 9.5, 12, 10.5], "texture": "#sh"}, "south": {"uv": [11, 9.5, 12, 10.5], "texture": "#sh"},
"west": {"uv": [0, 9.5, 0, 10.5], "texture": "#sh"}, "west": {"uv": [0, 9.5, 0.5, 10.5], "texture": "#sh"},
"up": {"uv": [11, 0, 12, 0], "texture": "#sh"}, "up": {"uv": [11, 0, 12, 0.5], "texture": "#sh"},
"down": {"uv": [11, 16, 12, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [11, 15.5, 12, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [12.5, 6, -2], "from": [12.5, 6, 0],
"to": [13.5, 7, -0.5], "to": [13.5, 7, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [20.5, -1, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [20.5, -1, 6.5]},
"faces": { "faces": {
"north": {"uv": [2.5, 9, 3.5, 10], "texture": "#sh"}, "north": {"uv": [2.5, 9, 3.5, 10], "texture": "#sh"},
"east": {"uv": [16, 9, 16, 10], "texture": "#sh"}, "east": {"uv": [15.5, 9, 16, 10], "texture": "#sh"},
"south": {"uv": [12.5, 9, 13.5, 10], "texture": "#sh"}, "south": {"uv": [12.5, 9, 13.5, 10], "texture": "#sh"},
"west": {"uv": [0, 9, 0, 10], "texture": "#sh"}, "west": {"uv": [0, 9, 0.5, 10], "texture": "#sh"},
"up": {"uv": [12.5, 0, 13.5, 0], "texture": "#sh"}, "up": {"uv": [12.5, 0, 13.5, 0.5], "texture": "#sh"},
"down": {"uv": [12.5, 16, 13.5, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [12.5, 15.5, 13.5, 16], "rotation": 270, "texture": "#sh"}
} }
}, },
{ {
"from": [13, 7.5, -2], "from": [13, 7.5, 0],
"to": [14, 8.5, -0.5], "to": [14, 8.5, 0.5],
"rotation": {"angle": 0, "axis": "y", "origin": [21, 0.5, 5.5]}, "rotation": {"angle": 0, "axis": "y", "origin": [21, 0.5, 6.5]},
"faces": { "faces": {
"north": {"uv": [2, 7.5, 3, 8.5], "texture": "#sh"}, "north": {"uv": [2, 7.5, 3, 8.5], "texture": "#sh"},
"east": {"uv": [16, 7.5, 16, 8.5], "texture": "#sh"}, "east": {"uv": [15.5, 7.5, 16, 8.5], "texture": "#sh"},
"south": {"uv": [13, 7.5, 14, 8.5], "texture": "#sh"}, "south": {"uv": [13, 7.5, 14, 8.5], "texture": "#sh"},
"west": {"uv": [0, 7.5, 0, 8.5], "texture": "#sh"}, "west": {"uv": [0, 7.5, 0.5, 8.5], "texture": "#sh"},
"up": {"uv": [13, 0, 14, 0], "texture": "#sh"}, "up": {"uv": [13, 0, 14, 0.5], "texture": "#sh"},
"down": {"uv": [13, 16, 14, 16], "rotation": 270, "texture": "#sh"} "down": {"uv": [13, 15.5, 14, 16], "rotation": 270, "texture": "#sh"}
} }
} }
], ],

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 KiB

View file

@ -25,3 +25,6 @@
![](engineers-decor-small-solar-panel.png) ![](engineers-decor-small-solar-panel.png)
![](engineers-decor-small-tree-cutter.png) ![](engineers-decor-small-tree-cutter.png)
![](engineers-decor-mesh-fence.png) ![](engineers-decor-mesh-fence.png)
![](engineers-decor-factory-block-placer.png)
![](engineers-decor-small-block-breaker.png)
![](engineers-decor-small-fluid-collection-funnel.png)

View file

@ -2,11 +2,12 @@
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/", "homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"promos": { "promos": {
"1.12.2-recommended": "1.0.15", "1.12.2-recommended": "1.0.15",
"1.12.2-latest": "1.0.15", "1.12.2-latest": "1.0.16-b1",
"1.14.4-recommended": "", "1.14.4-recommended": "",
"1.14.4-latest": "1.0.15-b3" "1.14.4-latest": "1.0.16-b1"
}, },
"1.12.2": { "1.12.2": {
"1.0.16-b1": "[A] Added Fluid Collection Funnel.\n[A] Added config opt-outs for Breaker, Placer, Fluid Funnel, Mineral Smelter.\n[A] Added configs tweaks for Small Block Breaker and Small Tree Cutter (cffr#185).\n[F] Fixed Block Placer discarding item metadata/variants while placing (issue #60).\n[F] Fixed Block Breaker duping empty shulker boxes, model updated.",
"1.0.15": "[R] Release based on v1.0.15-b2. Release-to-release changes: * Added Small Block Breaker * Small Tree Cutter fixes and compatability improved. * Crafting table compat fixes.\n[M] Small Tree Cutter log detection bug fixed (issue #59).\n[M] Small Tree Cutter supports Menril chopping (issue #54).", "1.0.15": "[R] Release based on v1.0.15-b2. Release-to-release changes: * Added Small Block Breaker * Small Tree Cutter fixes and compatability improved. * Crafting table compat fixes.\n[M] Small Tree Cutter log detection bug fixed (issue #59).\n[M] Small Tree Cutter supports Menril chopping (issue #54).",
"1.0.15-b2": "[A] Added Small Block Breaker\n[M] Crafting Table: Allowing NBT \"Damage\" mismatch only items that are declared damagable (issue #56).\n[M] Tree Cutter: Loosened the strict mod namespace requirement for Dynamic Trees log detection (issue #52) to enable checking DT compat mod log blocks.", "1.0.15-b2": "[A] Added Small Block Breaker\n[M] Crafting Table: Allowing NBT \"Damage\" mismatch only items that are declared damagable (issue #56).\n[M] Tree Cutter: Loosened the strict mod namespace requirement for Dynamic Trees log detection (issue #52) to enable checking DT compat mod log blocks.",
"1.0.15-b1": "[A] Added Floor Edge Light.\n[A] Added Factory Block Placer and Planter.", "1.0.15-b1": "[A] Added Floor Edge Light.\n[A] Added Factory Block Placer and Planter.",
@ -71,9 +72,10 @@
"1.0.0-b1": "[A] Initial structure.\n[A] Added clinker bricks and clinker brick stairs.\n[A] Added slag bricks and slag brick stairs.\n[A] Added metal rung ladder.\n[A] Added staggered metal steps ladder.\n[A] Added treated wood ladder.\n[A] Added treated wood pole.\n[A] Added treated wood table." "1.0.0-b1": "[A] Initial structure.\n[A] Added clinker bricks and clinker brick stairs.\n[A] Added slag bricks and slag brick stairs.\n[A] Added metal rung ladder.\n[A] Added staggered metal steps ladder.\n[A] Added treated wood ladder.\n[A] Added treated wood pole.\n[A] Added treated wood table."
}, },
"1.14.4": { "1.14.4": {
"1.0.16-b1": "[U] Updated to Forge 1.14.4-28.1.79/20190719-1.14.3.\n[A] Added Fluid Collection Funnel.",
"1.0.15-b3": "[A] Added Small Block Breaker.\n[M] Mineral Smelter fluid handler/transfer added.", "1.0.15-b3": "[A] Added Small Block Breaker.\n[M] Mineral Smelter fluid handler/transfer added.",
"1.0.15-b2": "[!] Forge version requirement set to 1.14.4-28.1.68 or higher.\n[A] Added Factory Block Placer and Planter.\n[A] Added Small Tree Cutter.", "1.0.15-b2": "[!] Forge version requirement set to 1.14.4-28.1.68 or higher.\n[A] Added Factory Block Placer and Planter.\n[A] Added Small Tree Cutter.",
"1.0.15-b1": "[A] Added Floor Edge Light.\n[U] Updated to Forge1.14.4-28.1.68/20190719-1.14.3.", "1.0.15-b1": "[A] Added Floor Edge Light.\n[U] Updated to Forge 1.14.4-28.1.68/20190719-1.14.3.",
"1.0.14-b1": "[U] Updated to Forge 1.14.4-28.1.40/20190719-1.14.3.\n[A] Factory Hopper added (configurable hopper and item collector).\n[M] Switched to integrated loot table generation.\n[M] Lang file zh_cn updated (scikirbypoke, PR#53).", "1.0.14-b1": "[U] Updated to Forge 1.14.4-28.1.40/20190719-1.14.3.\n[A] Factory Hopper added (configurable hopper and item collector).\n[M] Switched to integrated loot table generation.\n[M] Lang file zh_cn updated (scikirbypoke, PR#53).",
"1.0.13-b2": "[A] Added Steel Mesh Fence.\n[A] Added Broad Window Sill.", "1.0.13-b2": "[A] Added Steel Mesh Fence.\n[A] Added Broad Window Sill.",
"1.0.12-b3": "[U] Updated to Forge 1.14.4-28.1.10/20190719-1.14.3.\n[A] Crafting Table: Added recipe collision resolver, also applies to crafting history refabrication.\n[A] Crafting Table: Added rendering of placed items on the top surface of the table.\n[A] Waterlogging of non-full-blocks added.", "1.0.12-b3": "[U] Updated to Forge 1.14.4-28.1.10/20190719-1.14.3.\n[A] Crafting Table: Added recipe collision resolver, also applies to crafting history refabrication.\n[A] Crafting Table: Added rendering of placed items on the top surface of the table.\n[A] Waterlogging of non-full-blocks added.",