Experimental Factory Hopper implementation. Lang file updates.

This commit is contained in:
stfwi 2019-10-12 10:21:28 +02:00
parent caabf5fe94
commit 97ae2c3af1
42 changed files with 3902 additions and 381 deletions

View file

@ -2,7 +2,7 @@
org.gradle.daemon=false
org.gradle.jvmargs=-Xmx8G
version_minecraft=1.14.4
version_forge_minecraft=1.14.4-28.1.31
version_forge_minecraft=1.14.4-28.1.44
version_fml_mappings=20190719-1.14.3
version_jei=1.14.4:6.0.0.10
version_engineersdecor=1.0.13-b3

View file

@ -11,8 +11,10 @@ Mod sources for Minecraft version 1.14.4.
## Version history
~ v1.0.13-b3 [U] Updated to Forge 1.14.4-28.1.31/20190719-1.14.3.
~ v1.0.13-b3 [U] Updated to Forge 1.14.4-28.1.40/20190719-1.14.3.
[A] Factory Hopper added (configurable hopper and item collector).
[M] Switched to integrated loot table generation.
[M] Lang file zh_cn updated (scikirbypoke, PR#53).
- v1.0.13-b2 [A] Added Steel Mesh Fence.
[A] Added Broad Window Sill.

View file

@ -362,6 +362,12 @@ public class ModContent
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,15)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "factory_dropper"));
public static final BlockDecorHopper FACTORY_HOPPER = (BlockDecorHopper)(new BlockDecorHopper(
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_FACING_PLACEMENT|BlockDecor.CFG_OPPOSITE_PLACEMENT|BlockDecor.CFG_REDSTONE_CONTROLLED,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,16)
)).setRegistryName(new ResourceLocation(ModEngineersDecor.MODID, "factory_hopper"));
public static final BlockDecorWasteIncinerator SMALL_WASTE_INCINERATOR = (BlockDecorWasteIncinerator)(new BlockDecorWasteIncinerator(
BlockDecor.CFG_DEFAULT|BlockDecor.CFG_ELECTRICAL,
Block.Properties.create(Material.IRON, MaterialColor.IRON).hardnessAndResistance(2f, 15f).sound(SoundType.METAL),
@ -523,6 +529,7 @@ public class ModContent
};
private static final Block devBlocks[] = {
FACTORY_HOPPER,
STRAIGHT_CHECK_VALVE,
STRAIGHT_REDSTONE_VALVE,
STRAIGHT_REDSTONE_ANALOG_VALVE,
@ -553,6 +560,11 @@ public class ModContent
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_factory_dropper");
public static final TileEntityType<?> TET_FACTORY_HOPPER = TileEntityType.Builder
.create(BlockDecorHopper.BTileEntity::new, FACTORY_HOPPER)
.build(null)
.setRegistryName(ModEngineersDecor.MODID, "te_factory_hopper");
public static final TileEntityType<?> TET_WASTE_INCINERATOR = TileEntityType.Builder
.create(BlockDecorWasteIncinerator.BTileEntity::new, SMALL_WASTE_INCINERATOR)
.build(null)
@ -583,6 +595,7 @@ public class ModContent
TET_TREATED_WOOD_CRAFTING_TABLE,
TET_SMALL_LAB_FURNACE,
TET_FACTORY_DROPPER,
TET_FACTORY_HOPPER,
TET_SMALL_ELECTRICAL_FURNACE,
TET_WASTE_INCINERATOR,
TET_STRAIGHT_PIPE_VALVE,
@ -614,6 +627,7 @@ public class ModContent
public static final ContainerType<BlockDecorCraftingTable.BContainer> CT_TREATED_WOOD_CRAFTING_TABLE;
public static final ContainerType<BlockDecorDropper.BContainer> CT_FACTORY_DROPPER;
public static final ContainerType<BlockDecorHopper.BContainer> CT_FACTORY_HOPPER;
public static final ContainerType<BlockDecorFurnace.BContainer> CT_SMALL_LAB_FURNACE;
public static final ContainerType<BlockDecorFurnaceElectrical.BContainer> CT_SMALL_ELECTRICAL_FURNACE;
public static final ContainerType<BlockDecorWasteIncinerator.BContainer> CT_WASTE_INCINERATOR;
@ -623,6 +637,8 @@ public class ModContent
CT_TREATED_WOOD_CRAFTING_TABLE.setRegistryName(ModEngineersDecor.MODID,"ct_treated_wood_crafting_table");
CT_FACTORY_DROPPER = (new ContainerType<BlockDecorDropper.BContainer>(BlockDecorDropper.BContainer::new));
CT_FACTORY_DROPPER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_dropper");
CT_FACTORY_HOPPER = (new ContainerType<BlockDecorHopper.BContainer>(BlockDecorHopper.BContainer::new));
CT_FACTORY_HOPPER.setRegistryName(ModEngineersDecor.MODID,"ct_factory_hopper");
CT_SMALL_LAB_FURNACE = (new ContainerType<BlockDecorFurnace.BContainer>(BlockDecorFurnace.BContainer::new));
CT_SMALL_LAB_FURNACE.setRegistryName(ModEngineersDecor.MODID,"ct_small_lab_furnace");
CT_SMALL_ELECTRICAL_FURNACE = (new ContainerType<BlockDecorFurnaceElectrical.BContainer>(BlockDecorFurnaceElectrical.BContainer::new));
@ -635,6 +651,7 @@ public class ModContent
private static final ContainerType<?> container_types[] = {
CT_TREATED_WOOD_CRAFTING_TABLE,
CT_FACTORY_DROPPER,
CT_FACTORY_HOPPER,
CT_SMALL_LAB_FURNACE,
CT_SMALL_ELECTRICAL_FURNACE,
CT_WASTE_INCINERATOR
@ -716,6 +733,7 @@ public class ModContent
{
ScreenManager.registerFactory(CT_TREATED_WOOD_CRAFTING_TABLE, BlockDecorCraftingTable.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_DROPPER, BlockDecorDropper.BGui::new);
ScreenManager.registerFactory(CT_FACTORY_HOPPER, BlockDecorHopper.BGui::new);
ScreenManager.registerFactory(CT_SMALL_LAB_FURNACE, BlockDecorFurnace.BGui::new);
ScreenManager.registerFactory(CT_SMALL_ELECTRICAL_FURNACE, BlockDecorFurnaceElectrical.BGui::new);
ScreenManager.registerFactory(CT_WASTE_INCINERATOR, BlockDecorWasteIncinerator.BGui::new);

View file

@ -164,6 +164,21 @@ public class BlockDecorDropper extends BlockDecorDirected
((BTileEntity)te).block_updated();
}
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------

View file

@ -8,6 +8,7 @@
*/
package wile.engineersdecor.blocks;
import net.minecraftforge.common.ForgeHooks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.ExtItems;
@ -671,9 +672,8 @@ public class BlockDecorFurnace extends BlockDecorDirected
public static int getFuelBurntime(World world, ItemStack stack)
{
if(stack.isEmpty()) return 0;
Item item = stack.getItem();
int t = stack.getBurnTime();
return net.minecraftforge.event.ForgeEventFactory.getItemBurnTime(stack, (t>=0) ? t : AbstractFurnaceTileEntity.getBurnTimes().getOrDefault(item, 0));
int t = ForgeHooks.getBurnTime(stack);
return (t<0) ? 0 : t;
}
public static boolean isFuel(World world, ItemStack stack)

View file

@ -0,0 +1,879 @@
/*
* @file BlockDecorHopper.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Hopper, factory automation suitable.
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.detail.Networking;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.HopperBlock;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityType;
import net.minecraft.tileentity.HopperTileEntity;
import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.item.*;
import net.minecraft.inventory.*;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.inventory.container.Container;
import net.minecraft.inventory.container.Slot;
import net.minecraft.util.*;
import net.minecraft.util.math.*;
import net.minecraft.util.text.*;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.client.gui.screen.inventory.ContainerScreen;
import net.minecraftforge.fml.network.NetworkHooks;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.wrapper.SidedInvWrapper;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler;
import com.mojang.blaze3d.platform.GlStateManager;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class BlockDecorHopper extends BlockDecorDirected
{
public BlockDecorHopper(long config, Block.Properties builder, final AxisAlignedBB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
@Override
@SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getComparatorInputOverride(BlockState blockState, World world, BlockPos pos)
{ return Container.calcRedstone(world.getTileEntity(pos)); }
@Override
public boolean hasTileEntity(BlockState state)
{ return true; }
@Override
@Nullable
public TileEntity createTileEntity(BlockState state, IBlockReader world)
{ return new BlockDecorHopper.BTileEntity(); }
@Override
public void onBlockPlacedBy(World world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
if(world.isRemote) return;
if((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundNBT te_nbt = stack.getTag().getCompound("tedata");
if(te_nbt.isEmpty()) return;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).readnbt(te_nbt, false);
((BTileEntity)te).reset_rtstate();
((BTileEntity)te).markDirty();
}
@Override
public boolean hasDynamicDropList()
{ return true; }
@Override
public List<ItemStack> dropList(BlockState state, World world, BlockPos pos, boolean explosion)
{
final List<ItemStack> stacks = new ArrayList<ItemStack>();
if(world.isRemote) return stacks;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return stacks;
if(!explosion) {
ItemStack stack = new ItemStack(this, 1);
CompoundNBT te_nbt = ((BTileEntity)te).clear_getnbt();
if(!te_nbt.isEmpty()) {
CompoundNBT nbt = new CompoundNBT();
nbt.put("tedata", te_nbt);
stack.setTag(nbt);
}
stacks.add(stack);
} else {
for(ItemStack stack: ((BTileEntity)te).stacks_) {
if(!stack.isEmpty()) stacks.add(stack);
}
((BTileEntity)te).reset_rtstate();
}
return stacks;
}
@Override
@SuppressWarnings("deprecation")
public boolean onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockRayTraceResult rayTraceResult)
{
if(world.isRemote) return true;
final TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return true;
if((!(player instanceof ServerPlayerEntity) && (!(player instanceof FakePlayer)))) return true;
NetworkHooks.openGui((ServerPlayerEntity)player,(INamedContainerProvider)te);
return true;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, World world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
if(!(world instanceof World) || (((World) world).isRemote)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).block_updated();
}
@Override
public void onFallenUpon(World world, BlockPos pos, Entity entity, float fallDistance)
{
super.onFallenUpon(world, pos, entity, fallDistance);
if(!(entity instanceof ItemEntity)) return;
TileEntity te = world.getTileEntity(pos);
if(!(te instanceof BTileEntity)) return;
((BTileEntity)te).collection_timer_ = 0;
}
@Override
@SuppressWarnings("deprecation")
public boolean canProvidePower(BlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
@Override
@SuppressWarnings("deprecation")
public int getStrongPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side)
{ return 0; }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickableTileEntity, INameable, IInventory, INamedContainerProvider, ISidedInventory
{
public static final int NUM_OF_FIELDS = 7;
public static final int TICK_INTERVAL = 10;
public static final int COLLECTION_INTERVAL = 50;
public static final int NUM_OF_SLOTS = 18;
public static final int MAX_TRANSFER_COUNT = 32;
public static final int MAX_COLLECTION_RANGE = 4;
public static final int PERIOD_OFFSET = 10;
///
public static final int LOGIC_INVERTED = 0x01;
public static final int LOGIC_CONTINUOUS = 0x02;
///
private boolean block_power_signal_ = false;
private boolean block_power_updated_ = false;
private int collection_timer_ = 0;
private int delay_timer_ = 0;
private int transfer_count_ = 1;
private int logic_ = LOGIC_INVERTED|LOGIC_CONTINUOUS;
private int transfer_period_ = 0;
private int collection_range_ = 0;
private int current_slot_index_ = 0;
private int tick_timer_ = 0;
protected NonNullList<ItemStack> stacks_;
public static void on_config(int cooldown_ticks)
{
// ModEngineersDecor.logger.info("Config factory hopper:");
}
public BTileEntity()
{
this(ModContent.TET_FACTORY_HOPPER);
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
reset_rtstate();
}
public BTileEntity(TileEntityType<?> te_type)
{
super(te_type);
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
reset_rtstate();
}
public void reset_rtstate()
{
block_power_signal_ = false;
block_power_updated_ = false;
}
public CompoundNBT clear_getnbt()
{
CompoundNBT nbt = new CompoundNBT();
block_power_signal_ = false;
writenbt(nbt, false);
for(int i=0; i<stacks_.size(); ++i) stacks_.set(i, ItemStack.EMPTY);
reset_rtstate();
block_power_updated_ = false;
return nbt;
}
public void readnbt(CompoundNBT nbt, boolean update_packet)
{
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
ItemStackHelper.loadAllItems(nbt, stacks_);
while(stacks_.size() < NUM_OF_SLOTS) stacks_.add(ItemStack.EMPTY);
block_power_signal_ = nbt.getBoolean("powered");
current_slot_index_ = nbt.getInt("act_slot_index");
transfer_count_ = MathHelper.clamp(nbt.getInt("xsize"), 1, MAX_TRANSFER_COUNT);
logic_ = nbt.getInt("logic");
transfer_period_ = nbt.getInt("period");
collection_range_ = nbt.getInt("range");
}
protected void writenbt(CompoundNBT nbt, boolean update_packet)
{
ItemStackHelper.saveAllItems(nbt, stacks_);
nbt.putBoolean("powered", block_power_signal_);
nbt.putInt("act_slot_index", current_slot_index_);
nbt.putInt("xsize", transfer_count_);
nbt.putInt("logic", logic_);
nbt.putInt("period", transfer_period_);
nbt.putInt("range", collection_range_);
}
public void block_updated()
{
// RS power check, both edges
boolean powered = world.isBlockPowered(pos);
if(block_power_signal_ != powered) block_power_updated_ = true;
block_power_signal_ = powered;
tick_timer_ = 1;
}
public boolean is_input_slot(int index)
{ return (index >= 0) && (index < NUM_OF_SLOTS); }
// TileEntity --------------------------------------------------------------------------------------------
@Override
public void read(CompoundNBT nbt)
{ super.read(nbt); readnbt(nbt, false); }
@Override
public CompoundNBT write(CompoundNBT nbt)
{ super.write(nbt); writenbt(nbt, false); return nbt; }
// INamable ----------------------------------------------------------------------------------------------
@Override
public ITextComponent getName()
{ final Block block=getBlockState().getBlock(); return new StringTextComponent((block!=null) ? block.getTranslationKey() : "Factory Hopper"); }
@Override
public boolean hasCustomName()
{ return false; }
@Override
public ITextComponent getCustomName()
{ return getName(); }
// INamedContainerProvider ------------------------------------------------------------------------------
@Override
public ITextComponent getDisplayName()
{ return INameable.super.getDisplayName(); }
@Override
public Container createMenu(int id, PlayerInventory inventory, PlayerEntity player )
{ return new BContainer(id, inventory, this, IWorldPosCallable.of(world, pos), fields); }
// IInventory --------------------------------------------------------------------------------------------
@Override
public int getSizeInventory()
{ return stacks_.size(); }
@Override
public boolean isEmpty()
{ for(ItemStack stack: stacks_) { if(!stack.isEmpty()) return false; } return true; }
@Override
public ItemStack getStackInSlot(int index)
{ return (index < stacks_.size()) ? stacks_.get(index) : ItemStack.EMPTY; }
@Override
public ItemStack decrStackSize(int index, int count)
{ return ItemStackHelper.getAndSplit(stacks_, index, count); }
@Override
public ItemStack removeStackFromSlot(int index)
{ return ItemStackHelper.getAndRemove(stacks_, index); }
@Override
public void setInventorySlotContents(int index, ItemStack stack)
{
stacks_.set(index, stack);
if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit());
if(tick_timer_ > 8) tick_timer_ = 8;
markDirty();
}
@Override
public int getInventoryStackLimit()
{ return 64; }
@Override
public void markDirty()
{ super.markDirty(); }
@Override
public boolean isUsableByPlayer(PlayerEntity player)
{ return getPos().distanceSq(player.getPosition()) < 36; }
@Override
public void openInventory(PlayerEntity player)
{}
@Override
public void closeInventory(PlayerEntity player)
{ markDirty(); }
@Override
public boolean isItemValidForSlot(int index, ItemStack stack)
{ return true; }
@Override
public void clear()
{ stacks_.clear(); }
// Fields -----------------------------------------------------------------------------------------------
protected final IIntArray fields = new IntArray(BTileEntity.NUM_OF_FIELDS)
{
@Override
public int get(int id)
{
switch(id) {
case 0: return collection_range_;
case 1: return transfer_count_;
case 2: return logic_;
case 3: return transfer_period_;
case 4: return delay_timer_;
case 5: return block_power_signal_ ? 1 : 0;
case 6: return current_slot_index_;
default: return 0;
}
}
@Override
public void set(int id, int value)
{
switch(id) {
case 0: collection_range_ = MathHelper.clamp(value,0, MAX_COLLECTION_RANGE); return;
case 1: transfer_count_ = MathHelper.clamp(value,1, MAX_TRANSFER_COUNT); return;
case 2: logic_ = value; return;
case 3: transfer_period_ = MathHelper.clamp(value,0, 100); return;
case 4: delay_timer_ = MathHelper.clamp(value,0, 400); return;
case 5: block_power_signal_ = (value != 0); return;
case 6: current_slot_index_ = MathHelper.clamp(value, 0, NUM_OF_SLOTS-1); return;
default: return;
}
}
};
// ISidedInventory --------------------------------------------------------------------------------------
LazyOptional<? extends IItemHandler>[] item_handlers = SidedInvWrapper.create(this, Direction.UP);
private static final int[] SIDED_INV_SLOTS;
static {
SIDED_INV_SLOTS = new int[NUM_OF_SLOTS];
for(int i=0; i<NUM_OF_SLOTS; ++i) SIDED_INV_SLOTS[i] = i;
}
@Override
public int[] getSlotsForFace(Direction side)
{ return SIDED_INV_SLOTS; }
@Override
public boolean canInsertItem(int index, ItemStack stack, Direction direction)
{ return is_input_slot(index) && isItemValidForSlot(index, stack); }
@Override
public boolean canExtractItem(int index, ItemStack stack, Direction direction)
{ return (direction != Direction.UP); }
// Capability export ------------------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(!this.removed && (facing != null)) {
if(capability==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return item_handlers[0].cast();
}
return super.getCapability(capability, facing);
}
// ITickable and aux methods ---------------------------------------------------------------------
private static int next_slot(int i)
{ return (i<NUM_OF_SLOTS-1) ? (i+1) : 0; }
private int try_insert_into_hopper(final ItemStack stack)
{
final int max_to_insert = stack.getCount();
int n_to_insert = max_to_insert;
int first_empty_slot = -1;
for(int i=0; i<stacks_.size(); ++i) {
final ItemStack slotstack = stacks_.get(i);
if((first_empty_slot < 0) && slotstack.isEmpty()) { first_empty_slot=i; continue; }
if(!stack.isItemEqual(slotstack)) continue;
int nspace = slotstack.getMaxStackSize() - slotstack.getCount();
if(nspace <= 0) {
continue;
} else if(nspace >= n_to_insert) {
slotstack.grow(n_to_insert);
n_to_insert = 0;
break;
} else {
slotstack.grow(nspace);
n_to_insert -= nspace;
}
}
if((n_to_insert > 0) && (first_empty_slot >= 0)) {
ItemStack new_stack = stack.copy();
new_stack.setCount(n_to_insert);
stacks_.set(first_empty_slot, new_stack);
n_to_insert = 0;
}
return max_to_insert - n_to_insert;
}
private boolean try_insert(Direction facing)
{
ItemStack current_stack = ItemStack.EMPTY;
for(int i=0; i<NUM_OF_SLOTS; ++i) {
if(current_slot_index_ >= NUM_OF_SLOTS) current_slot_index_ = 0;
current_stack = stacks_.get(current_slot_index_);
if(!current_stack.isEmpty()) break;
current_slot_index_ = next_slot(current_slot_index_);
}
if(current_stack.isEmpty()) {
current_slot_index_ = 0;
return false;
}
final TileEntity te = world.getTileEntity(pos.offset(facing));
if(te == null) { delay_timer_ = TICK_INTERVAL+2; return false; } // no reason to recalculate this all the time if there is nothere to insert.
final IItemHandler ih = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, facing.getOpposite()).orElse(null);
if(ih == null) { delay_timer_ = TICK_INTERVAL+2; return false; }
if(te instanceof HopperTileEntity) {
Direction f = world.getBlockState(pos.offset(facing)).get(HopperBlock.FACING);
if(f==facing.getOpposite()) return false; // no back transfer
} else if(te instanceof BTileEntity) {
Direction f = world.getBlockState(pos.offset(facing)).get(FACING);
if(f==facing.getOpposite()) return false;
}
ItemStack insert_stack = current_stack.copy();
if(insert_stack.getCount() > transfer_count_) insert_stack.setCount(transfer_count_);
final int initial_insert_stack_size = insert_stack.getCount();
int first_empty_slot_index = -1;
if((ih == null) || ih.getSlots() <= 0) return false;
for(int i=0; i<ih.getSlots(); ++i) {
if(!ih.isItemValid(i, insert_stack)) continue;
final ItemStack target_stack = ih.getStackInSlot(i);
if((first_empty_slot_index < 0) && target_stack.isEmpty()) first_empty_slot_index = i;
if(!target_stack.isItemEqual(insert_stack)) continue;
insert_stack = ih.insertItem(i, insert_stack.copy(), false);
if(insert_stack.isEmpty()) break;
}
if((first_empty_slot_index >= 0) && (!insert_stack.isEmpty())) {
insert_stack = ih.insertItem(first_empty_slot_index, insert_stack.copy(), false);
}
final int num_inserted = initial_insert_stack_size-insert_stack.getCount();
if(num_inserted > 0) {
current_stack.shrink(num_inserted);
stacks_.set(current_slot_index_, current_stack);
}
if(!insert_stack.isEmpty()) current_slot_index_ = next_slot(current_slot_index_);
if(num_inserted == 0) {
delay_timer_ += transfer_period_ * 2;
return false;
} else {
return true;
}
}
private boolean try_item_handler_extract(final IItemHandler ih)
{
final int end = ih.getSlots();
int n_to_extract = transfer_count_;
for(int i=0; i<end; ++i) {
if(ih.getStackInSlot(i).isEmpty()) continue;
ItemStack stack = ih.extractItem(i, n_to_extract, true);
if(stack.isEmpty()) continue;
int n_accepted = try_insert_into_hopper(stack);
if(n_accepted > 0) {
ItemStack test = ih.extractItem(i, n_accepted, false);
n_to_extract -= n_accepted;
if(n_to_extract <= 0) break;
}
}
return (n_to_extract < transfer_count_);
}
private boolean try_inventory_extract(final IInventory inv)
{
final int end = inv.getSizeInventory();
int n_to_extract = transfer_count_;
for(int i=0; i<end; ++i) {
ItemStack stack = inv.getStackInSlot(i).copy();
if(stack.isEmpty()) continue;
int n_accepted = try_insert_into_hopper(stack);
if(n_accepted > 0) {
stack.shrink(n_accepted);
n_to_extract -= n_accepted;
if(stack.isEmpty()) stack = ItemStack.EMPTY;
inv.setInventorySlotContents(i, stack);
if(n_to_extract <= 0) break;
}
}
if(n_to_extract < transfer_count_) {
inv.markDirty();
return true;
} else {
return false;
}
}
private boolean try_collect(Direction facing)
{
AxisAlignedBB collection_volume;
Vec3d rpos;
if(facing==EnumFacing.UP) {
rpos = new Vec3d(0.5+pos.getX(),1.5+pos.getY(),0.5+pos.getZ());
collection_volume = (new AxisAlignedBB(pos.up())).grow(0.1+collection_range_, 0.5, 0.1+collection_range_);
} else {
rpos = new Vec3d(0.5+pos.getX(),-1.5+pos.getY(),0.5+pos.getZ());
collection_volume = (new AxisAlignedBB(pos.down())).grow(0.1+collection_range_, 0.5, 0.1+collection_range_);
}
final List<ItemEntity> items = world.getEntitiesWithinAABB(ItemEntity.class, collection_volume);
if(items.size() <= 0) return false;
final int max_to_collect = 3;
int n_collected = 0;
for(ItemEntity ie:items) {
if((!ie.onGround) || (ie.cannotPickup() && ie.getDistanceSq(rpos)>=0.7)) continue;
ItemStack stack = ie.getItem();
int n_accepted = try_insert_into_hopper(stack);
if(n_accepted <= 0) continue;
if(n_accepted == stack.getCount()) {
ie.remove();
} else {
stack.shrink(n_accepted);
}
if(++n_collected >= max_to_collect) break;
}
return (n_collected > 0);
}
@Override
public void tick()
{
// Tick cycle pre-conditions
if(world.isRemote) return;
if((delay_timer_ > 0) && ((--delay_timer_) == 0)) markDirty();
if(--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
// Cycle init
boolean dirty = block_power_updated_;
final boolean rssignal = ((logic_ & LOGIC_INVERTED)!=0)==(!block_power_signal_);
final boolean pulse_mode = ((logic_ & LOGIC_CONTINUOUS)==0);
boolean trigger = (rssignal && ((block_power_updated_) || (!pulse_mode)));
final BlockState state = world.getBlockState(pos);
if(state == null) { block_power_signal_= false; return; }
final Direction hopper_facing = state.get(FACING);
// Trigger edge detection for next cycle
{
boolean tr = world.isBlockPowered(pos);
block_power_updated_ = (block_power_signal_ != tr);
block_power_signal_ = tr;
if(block_power_updated_) dirty = true;
}
// Collection
if(rssignal || pulse_mode) {
Direction hopper_input_facing = (hopper_facing==Direction.UP) ? Direction.DOWN : Direction.UP;
TileEntity te = world.getTileEntity(pos.offset(hopper_input_facing));
final IItemHandler ih = (te==null) ? (null) : (te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY, hopper_input_facing.getOpposite()).orElse(null));
if((ih != null) || (te instanceof ISidedInventory)) {
// IItemHandler pulling
if((ih != null)) {
if(try_item_handler_extract(ih)) dirty = true;
} else {
if(try_inventory_extract((IInventory)te)) dirty = true;
}
} else if((collection_timer_ -= TICK_INTERVAL) <= 0) {
// Ranged collection
collection_timer_ = COLLECTION_INTERVAL;
if(try_collect(hopper_input_facing)) dirty = true;
}
}
// Insertion
if(trigger && (delay_timer_ <= 0)) {
delay_timer_ = PERIOD_OFFSET + transfer_period_ * 2;
if(try_insert(hopper_facing)) dirty = true;
}
if(dirty) markDirty();
if(trigger && (tick_timer_ > TICK_INTERVAL)) tick_timer_ = TICK_INTERVAL;
}
}
//--------------------------------------------------------------------------------------------------------------------
// container
//--------------------------------------------------------------------------------------------------------------------
public static class BContainer extends Container implements Networking.INetworkSynchronisableContainer
{
private static final int PLAYER_INV_START_SLOTNO = BTileEntity.NUM_OF_SLOTS;
private final PlayerEntity player_;
private final IInventory inventory_;
private final IWorldPosCallable wpc_;
private final IIntArray fields_;
public final int field(int index) { return fields_.get(index); }
public BContainer(int cid, PlayerInventory player_inventory)
{ this(cid, player_inventory, new Inventory(BTileEntity.NUM_OF_SLOTS), IWorldPosCallable.DUMMY, new IntArray(BTileEntity.NUM_OF_FIELDS)); }
private BContainer(int cid, PlayerInventory player_inventory, IInventory block_inventory, IWorldPosCallable wpc, IIntArray fields)
{
super(ModContent.CT_FACTORY_HOPPER, cid);
fields_ = fields;
wpc_ = wpc;
player_ = player_inventory.player;
inventory_ = block_inventory;
int i=-1;
// input slots (stacks 0 to 17)
for(int y=0; y<3; ++y) {
for(int x=0; x<6; ++x) {
int xpos = 11+x*18, ypos = 9+y*17;
addSlot(new Slot(inventory_, ++i, xpos, ypos));
}
}
// player slots
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x, 8+x*18, 129)); // player slots: 0..8
}
for(int y=0; y<3; ++y) {
for(int x=0; x<9; ++x) {
addSlot(new Slot(player_inventory, x+y*9+9, 8+x*18, 71+y*18)); // player slots: 9..35
}
}
this.trackIntArray(fields_); // === Add reference holders
}
@Override
public boolean canInteractWith(PlayerEntity player)
{ return inventory_.isUsableByPlayer(player); }
@Override
public ItemStack transferStackInSlot(PlayerEntity player, int index)
{
Slot slot = getSlot(index);
if((slot==null) || (!slot.getHasStack())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getStack();
ItemStack transferred = slot_stack.copy();
if((index>=0) && (index<PLAYER_INV_START_SLOTNO)) {
// Device slots
if(!mergeItemStack(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
} else if((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO+36)) {
// Player slot
if(!mergeItemStack(slot_stack, 0, BTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY;
} else {
// invalid slot
return ItemStack.EMPTY;
}
if(slot_stack.isEmpty()) {
slot.putStack(ItemStack.EMPTY);
} else {
slot.onSlotChanged();
}
if(slot_stack.getCount() == transferred.getCount()) return ItemStack.EMPTY;
slot.onTake(player, slot_stack);
return transferred;
}
// INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundNBT nbt)
{ Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt); }
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{
CompoundNBT nbt = new CompoundNBT();
nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(windowId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundNBT nbt)
{}
@Override
public void onClientPacketReceived(int windowId, PlayerEntity player, CompoundNBT nbt)
{
if(!(inventory_ instanceof BTileEntity)) return;
BTileEntity te = (BTileEntity)inventory_;
if(nbt.contains("xsize")) te.transfer_count_ = MathHelper.clamp(nbt.getInt("xsize"), 1, BTileEntity.MAX_TRANSFER_COUNT);
if(nbt.contains("period")) te.transfer_period_ = MathHelper.clamp(nbt.getInt("period"), 0, 100);
if(nbt.contains("range")) te.collection_range_ = MathHelper.clamp(nbt.getInt("range"), 0, BTileEntity.MAX_COLLECTION_RANGE);
if(nbt.contains("logic")) te.logic_ = nbt.getInt("logic");
if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; }
te.markDirty();
}
}
//--------------------------------------------------------------------------------------------------------------------
// GUI
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class BGui extends ContainerScreen<BContainer>
{
protected final PlayerEntity player_;
public BGui(BContainer container, PlayerInventory player_inventory, ITextComponent title)
{ super(container, player_inventory, title); this.player_ = player_inventory.player; }
@Override
public void init()
{ super.init(); }
@Override
public void render(int mouseX, int mouseY, float partialTicks)
{
renderBackground();
super.render(mouseX, mouseY, partialTicks);
renderHoveredToolTip(mouseX, mouseY);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton)
{
BContainer container = (BContainer)getContainer();
int mx = (int)(mouseX - getGuiLeft() + .5), my = (int)(mouseY - getGuiTop() + .5);
if((!isPointInRegion(126, 1, 49, 60, mouseX, mouseY))) {
return super.mouseClicked(mouseX, mouseY, mouseButton);
} else if(isPointInRegion(128, 9, 44, 10, mouseX, mouseY)) {
int range = (mx-133);
if(range < -1) {
range = container.field(0) - 1; // -
} else if(range >= 34) {
range = container.field(0) + 1; // +
} else {
range = (int)(0.5 + ((((double)BTileEntity.MAX_COLLECTION_RANGE) * range)/34)); // slider
range = MathHelper.clamp(range, 0, BTileEntity.MAX_COLLECTION_RANGE);
}
container.onGuiAction("range", range);
} else if(isPointInRegion(128, 21, 44, 10, mouseX, mouseY)) {
int period = (mx-133);
if(period < -1) {
period = container.field(3) - 3; // -
} else if(period >= 35) {
period = container.field(3) + 3; // +
} else {
period = (int)(0.5 + ((100.0 * period)/34));
}
period = MathHelper.clamp(period, 0, 100);
container.onGuiAction("period", period);
} else if(isPointInRegion(128, 34, 44, 10, mouseX, mouseY)) {
int ndrop = (mx-134);
if(ndrop < -1) {
ndrop = container.field(1) - 1; // -
} else if(ndrop >= 34) {
ndrop = container.field(1) + 1; // +
} else {
ndrop = MathHelper.clamp(1+ndrop, 1, BTileEntity.MAX_TRANSFER_COUNT); // slider
}
container.onGuiAction("xsize", ndrop);
} else if(isPointInRegion(133, 49, 9, 9, mouseX, mouseY)) {
container.onGuiAction("manual_trigger", 1);
} else if(isPointInRegion(145, 49, 9, 9, mouseX, mouseY)) {
container.onGuiAction("logic", container.field(2) ^ BTileEntity.LOGIC_INVERTED);
} else if(isPointInRegion(159, 49, 7, 9, mouseX, mouseY)) {
container.onGuiAction("logic", container.field(2) ^ BTileEntity.LOGIC_CONTINUOUS);
}
return true;
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
{
GlStateManager.color4f(1f, 1f, 1f, 1f);
this.minecraft.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/factory_hopper_gui.png"));
final int x0=getGuiLeft(), y0=getGuiTop(), w=getXSize(), h=getYSize();
blit(x0, y0, 0, 0, w, h);
BContainer container = (BContainer)getContainer();
// active slot
{
int slot_index = container.field(6);
if((slot_index < 0) || (slot_index >= BTileEntity.NUM_OF_SLOTS)) slot_index = 0;
int x = (x0+10+((slot_index % 6) * 18));
int y = (y0+8+((slot_index / 6) * 17));
blit(x, y, 200, 8, 18, 18);
}
// collection range
{
int lut[] = { 133, 141, 149, 157, 166 };
int px = lut[MathHelper.clamp(container.field(0), 0, BTileEntity.MAX_COLLECTION_RANGE)];
int x = x0 + px - 2;
int y = y0 + 14;
blit(x, y, 179, 40, 5, 5);
}
// transfer period
{
int px = (int)Math.round(((33.5 * container.field(3)) / 100) + 1);
int x = x0 + 132 - 2 + MathHelper.clamp(px, 0, 34);
int y = y0 + 27;
blit(x, y, 179, 40, 5, 5);
}
// transfer count
{
int x = x0 + 133 - 2 + (container.field(1));
int y = y0 + 40;
blit(x, y, 179, 40, 5, 5);
}
// redstone input
{
if(container.field(5) != 0) {
blit(x0+133, y0+49, 217, 49, 9, 9);
}
}
// trigger logic
{
int inverter_offset = ((container.field(2) & BTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0;
blit(x0+145, y0+49, 177+inverter_offset, 49, 9, 9);
int pulse_mode_offset = ((container.field(2) & BTileEntity.LOGIC_CONTINUOUS ) != 0) ? 9 : 0;
blit(x0+159, y0+49, 199+pulse_mode_offset, 49, 9, 9);
}
// delay timer running indicator
{
if((container.field(4) > BTileEntity.PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) {
blit(x0+148, y0+22, 187, 22, 3, 3);
}
}
}
}
}

View file

@ -0,0 +1,16 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:block/device/factory_hopper_model"
},
"variants": {
"facing": {
"north":{"y":0},
"south":{"y":180},
"west":{"y":270},
"east":{"y":90},
"up": { "model": "engineersdecor:block/device/factory_hopper_model_up" },
"down": { "model": "engineersdecor:block/device/factory_hopper_model_down" }
}
}
}

View file

@ -155,6 +155,8 @@
"block.engineersdecor.passive_fluid_accumulator.help": "§6Vacuum suction based fluid collector.§r Has one output, all other sides are input. Drains fluids from adjacent tanks when being drained from the output port by a pump.",
"block.engineersdecor.factory_dropper": "Factory Dropper",
"block.engineersdecor.factory_dropper.help": "§6Dropper suitable for advanced factory automation.§r Has twelve round-robin selected slots. Drop force, angle, stack size, and cool-down delay adjustable in the GUI. Three stack compare slots with logical AND or OR can be used as internal trigger source. Internal trigger can be AND'ed or OR'ed with the external redstone signal trigger. Trigger simulation buttons for testing. Pre-opens shutter door when internal trigger conditions are met. Drops all matching stacks simultaneously. Click on all elements in the GUI to see how it works.",
"block.engineersdecor.factory_hopper": "Factory Hopper",
"block.engineersdecor.factory_hopper.help": "§6Hopper suitable for advanced factory automation.§r",
"block.engineersdecor.small_mineral_smelter": "Small Mineral Melting Furnace",
"block.engineersdecor.small_mineral_smelter.help": "§6High temperature, high insulation electrical stone melting furnace.§r\n Heats up mineral blocks to magma blocks, and finally to lava. Due to the miniturized device size the process is rather inefficient - much time and energy is needed to liquefy a stone block.",
"block.engineersdecor.small_solar_panel": "Small Solar Panel",
@ -172,8 +174,9 @@
"block.engineersdecor.sign_defense": "Sign \"Caution Defense System Ahead\"",
"block.engineersdecor.sign_defense.help": "§6Warning sign for turrets, Tesla Coils, and traps.",
"block.engineersdecor.sign_factoryarea": "Sign \"Factory Area\"",
"block.engineersdecor.sign_factoryarea.help": "§6There's the door, please ...",
"block.engineersdecor.sign_factoryarea.help": "§6Marker sign for buildings or areas where the really big machines are located.",
"block.engineersdecor.sign_exit": "Exit Sign",
"block.engineersdecor.sign_exit.help": "§6There's the door, please ...",
"block.engineersdecor.halfslab_rebar_concrete": "Rebar Concrete Slice",
"block.engineersdecor.halfslab_rebar_concrete.help": "§6Vertically stackable slice.§r Right/left click with the slice stack on the top or bottom surface to add/remove slices.",
"block.engineersdecor.halfslab_concrete": "Concrete Slice",

View file

@ -152,6 +152,7 @@
"block.engineersdecor.passive_fluid_accumulator.help": "§6Вакуумный всасывающий жидкостный коллектор.§r Имеет один выход, все остальные стороны входные. Сливает жидкости из соседних резервуаров при выкачивании жидкости из выходного порта.",
"block.engineersdecor.factory_dropper": "Фабричный выбрасыватель",
"block.engineersdecor.factory_dropper.help": "§6Выбрасыватель подходит для продвинутой автоматизации производства.§r Имеет 12 выборочных слотов. Сила броска, угол, размер стопки и задержка настраиваются в GUI. 3 слота сравнения стека с логическим И или ИЛИ могут использоваться в качестве внутреннего источника запуска. Внутренний триггер может быть И или ИЛИ с внешним триггерным сигналом красного камня. Триггерные кнопки симуляции для тестирования. Предварительно открывает дверцу затвора, когда выполняются условия внутреннего запуска. Сбрасывает все соответствующие стеки одновременно. Нажмите на все элементы в GUI, чтобы увидеть, как это работает.",
"block.engineersdecor.factory_hopper": "Factory Hopper",
"block.engineersdecor.small_mineral_smelter": "Small Mineral Melting Furnace",
"block.engineersdecor.small_solar_panel": "Small Solar Panel",
"block.engineersdecor.small_tree_cutter": "Small Tree Cutter",

View file

@ -4,133 +4,193 @@
"language.region": "China",
"itemGroup.tabengineersdecor": "工程师的装饰",
"engineersdecor.config.title": "工程师的装饰配置",
"engineersdecor.tooltip.hint.extended": "§6[按§9SHIFT§r获取更多信息§6]§r",
"engineersdecor.tooltip.hint.help": "§6[按§9CTRL-SHIFT§r获取帮助§6]§r",
"engineersdecor.config.pattern_excludes": "Pattern excludes",
"engineersdecor.config.pattern_includes": "Pattern includes",
"engineersdecor.config.without_clinker_bricks": "Without clinker bricks",
"engineersdecor.config.without_slag_bricks": "Without slag bricks",
"engineersdecor.config.without_rebar_concrete": "Without rebar concrete",
"engineersdecor.config.without_walls": "Without walls",
"engineersdecor.config.without_stairs": "Without stairs",
"engineersdecor.config.without_ie_concrete_wall": "Without concrete wall",
"engineersdecor.config.without_panzer_glass": "Without panzer glass",
"engineersdecor.config.without_crafting_table": "Without crafting table",
"engineersdecor.config.without_lab_furnace": "Without lab furnace",
"engineersdecor.config.without_electrical_furnace": "Without electrical furnace",
"engineersdecor.config.without_treated_wood_furniture": "Without tr. wood furniture",
"engineersdecor.config.without_windows": "Without windows",
"engineersdecor.config.without_light_sources": "Without lights",
"engineersdecor.config.without_ladders": "Without ladders",
"engineersdecor.config.without_chair_sitting": "Without chair sitting",
"engineersdecor.config.without_mob_chair_sitting": "Without chair mob sitting",
"engineersdecor.config.without_ladder_speed_boost": "Without ladder speed boost",
"engineersdecor.config.without_crafting_table_history": "Without crafting table history",
"engineersdecor.config.without_valves": "Without valves",
"engineersdecor.config.without_passive_fluid_accumulator": "Without fluid accumulator",
"engineersdecor.config.without_waste_incinerator": "Without waste incinerator",
"engineersdecor.config.without_sign_plates": "Without signs",
"engineersdecor.config.without_factory_dropper": "Without factory dropper",
"engineersdecor.config.without_slabs": "Without slabs",
"engineersdecor.config.without_halfslabs": "Without slab slices",
"engineersdecor.config.without_direct_slab_pickup": "Without slab pickup",
"engineersdecor.config.without_poles": "Without poles",
"engineersdecor.config.without_hsupports": "Without h. supports",
"engineersdecor.config.without_tooltips": "Without tooltips",
"engineersdecor.config.without_recipes": "Without recipes",
"engineersdecor.config.furnace_smelting_speed_percent": "Furnace: Smelting speed %",
"engineersdecor.config.furnace_fuel_efficiency_percent": "Furnace: Fuel efficiency %",
"engineersdecor.config.furnace_boost_energy_consumption": "Furnace: Boost energy",
"engineersdecor.config.chair_mob_sitting_probability_percent": "Chairs: Sitting chance %",
"engineersdecor.config.chair_mob_standup_probability_percent": "\"Chairs: Stand up chance %\"",
"engineersdecor.config.with_crafting_quickmove_buttons": "Crafting table: Move buttons",
"engineersdecor.config.pipevalve_max_flowrate": "Valves: Max flow rate",
"engineersdecor.config.pipevalve_redstone_gain": "Valves: Redstone slope",
"engineersdecor.config.e_furnace_speed_percent": "E-furnace: Smelting speed %",
"engineersdecor.config.e_furnace_power_consumption": "E-furnace: Power consumption",
"block.engineersdecor.clinker_brick_block": "熟料砖",
"block.engineersdecor.clinker_brick_block.help": "§6具有位置相关纹理变化的砖块.§r\n看起来比原版砖块稍暗,颜色更浓.",
"block.engineersdecor.clinker_brick_stained_block": "Stained Clinker Brick Block",
"block.engineersdecor.slag_brick_block": "炉渣砖",
"block.engineersdecor.slag_brick_block.help": "§6灰褐色砖块,具有位置相关的纹理变化.",
"engineersdecor.tooltip.hint.extended": "§6[§9SHIFT§r 查看更多信息§6]§r",
"engineersdecor.tooltip.hint.help": "§6[§9CTRL-SHIFT§r 查看帮助§6]§r",
"engineersdecor.tooltip.slabpickup.help": "§r手持同类台阶往上/下看时单击该台阶可无需破坏快速拾起。",
"engineersdecor.config.pattern_excludes": "模式不包括",
"engineersdecor.config.pattern_includes": "模式包括",
"engineersdecor.config.without_clinker_bricks": "不要过烧砖",
"engineersdecor.config.without_slag_bricks": "不要炉渣砖",
"engineersdecor.config.without_rebar_concrete": "不要强化混凝土",
"engineersdecor.config.without_walls": "不要墙",
"engineersdecor.config.without_stairs": "不要楼梯",
"engineersdecor.config.without_ie_concrete_wall": "不要混凝土墙",
"engineersdecor.config.without_panzer_glass": "不要装甲玻璃",
"engineersdecor.config.without_crafting_table": "不要合成台",
"engineersdecor.config.without_lab_furnace": "不要实验室炉",
"engineersdecor.config.without_electrical_furnace": "不要电炉",
"engineersdecor.config.without_treated_wood_furniture": "不要防腐木家具",
"engineersdecor.config.without_windows": "不要窗户",
"engineersdecor.config.without_light_sources": "不要灯",
"engineersdecor.config.without_ladders": "不要梯子",
"engineersdecor.config.without_chair_sitting": "椅子不能坐",
"engineersdecor.config.without_mob_chair_sitting": "椅子不能给其他生物坐",
"engineersdecor.config.without_ladder_speed_boost": "不要爬梯加速",
"engineersdecor.config.without_crafting_table_history": "不要合成台历史",
"engineersdecor.config.without_valves": "不要阀门",
"engineersdecor.config.without_passive_fluid_accumulator": "不要流体积累器",
"engineersdecor.config.without_waste_incinerator": "不要焚烧炉",
"engineersdecor.config.without_sign_plates": "不要标志牌",
"engineersdecor.config.without_factory_dropper": "不要工厂掉落器",
"engineersdecor.config.without_slabs": "不要台阶",
"engineersdecor.config.without_halfslabs": "不要台阶切片",
"engineersdecor.config.without_direct_slab_pickup": "不要快速捡起台阶",
"engineersdecor.config.without_poles": "不要杆",
"engineersdecor.config.without_hsupports": "不要支撑",
"engineersdecor.config.without_tooltips": "不要工具提示",
"engineersdecor.config.without_recipes": "不要配方",
"engineersdecor.config.furnace_smelting_speed_percent": "熔炉:熔炼速度 %",
"engineersdecor.config.furnace_fuel_efficiency_percent": "熔炉:燃料效率 %",
"engineersdecor.config.furnace_boost_energy_consumption": "熔炉:能量加速",
"engineersdecor.config.chair_mob_sitting_probability_percent": "椅子:坐下机率 %",
"engineersdecor.config.chair_mob_standup_probability_percent": "\"椅子:站起机率 %\"",
"engineersdecor.config.with_crafting_quickmove_buttons": "合成台:移动按钮",
"engineersdecor.config.pipevalve_max_flowrate": "阀门:最大流速",
"engineersdecor.config.pipevalve_redstone_gain": "阀门:红石斜率",
"engineersdecor.config.e_furnace_speed_percent": "电炉:熔炉速度 %",
"engineersdecor.config.e_furnace_power_consumption": "电炉:能量消耗",
"block.engineersdecor.clinker_brick_block": "过烧砖块",
"block.engineersdecor.clinker_brick_block.help": "§6一种放在不同位置贴图有不同变化的砖块。§r\n比原版砖看起来颜色更深色度也更高。",
"block.engineersdecor.clinker_brick_stained_block": "污渍过烧砖块",
"block.engineersdecor.clinker_brick_stained_block.help": "§6一种放在不同位置贴图有不同变化的砖块。§r\n比原版砖看起来颜色更深色度也更高。有更多可见的污垢或污迹。",
"block.engineersdecor.slag_brick_block": "炉渣砖块",
"block.engineersdecor.slag_brick_block.help": "§6一种放在不同位置贴图有不同变化的灰棕色砖块。",
"block.engineersdecor.rebar_concrete": "钢筋混凝土",
"block.engineersdecor.rebar_concrete.help": "§6钢筋混凝土砌块.§r 昂贵,但像黑曜石一样防苦力怕.",
"block.engineersdecor.panzerglass_block": "Panzer Glass Block",
"block.engineersdecor.rebar_concrete_tile": "Rebar Concrete Tile",
"block.engineersdecor.clinker_brick_slab": "Clinker Brick Slab",
"block.engineersdecor.clinker_brick_stained_slab": "Stained Clinker Brick Slab",
"block.engineersdecor.slag_brick_slab": "Slag Brick Slab",
"block.engineersdecor.rebar_concrete_slab": "Rebar Concrete Slab",
"block.engineersdecor.rebar_concrete_tile_slab": "Rebar Concrete Tile Slab",
"block.engineersdecor.panzerglass_slab": "Panzer Glass Slab",
"block.engineersdecor.treated_wood_floor": "Treated Wood Floor",
"block.engineersdecor.rebar_concrete.help": "§6钢强化的混凝土。§r昂贵但像黑曜石一样防爬行者爆炸。",
"block.engineersdecor.panzerglass_block": "装甲玻璃块",
"block.engineersdecor.panzerglass_block.help": "§6强化的玻璃方块。§r昂贵防爆。深灰色调有隐约可见的结构线和多种纹理外观无光泽。",
"block.engineersdecor.rebar_concrete_tile": "钢筋混凝土砖",
"block.engineersdecor.rebar_concrete_tile.help": "§6钢强化的混凝土砖。§r昂贵但像黑曜石一样防爬行者爆炸。",
"block.engineersdecor.clinker_brick_slab": "过烧砖台阶",
"block.engineersdecor.clinker_brick_slab.help": "§6过烧砖块制造的台阶。§r\n比原版砖看起来颜色更深色度也更高。",
"block.engineersdecor.clinker_brick_stained_slab": "污渍过烧砖台阶",
"block.engineersdecor.clinker_brick_stained_slab.help": "§6污渍过烧砖块制造的台阶。",
"block.engineersdecor.slag_brick_slab": "炉渣砖台阶",
"block.engineersdecor.slag_brick_slab.help": "§6一种灰棕色砖块台阶。",
"block.engineersdecor.rebar_concrete_slab": "钢筋混凝土台阶",
"block.engineersdecor.rebar_concrete_slab.help": "§6钢强化的混凝土台阶。§r昂贵但像黑曜石一样防爬行者爆炸。",
"block.engineersdecor.rebar_concrete_tile_slab": "钢筋混凝土砖台阶",
"block.engineersdecor.rebar_concrete_tile_slab.help": "§6钢强化的混凝土砖台阶。§r昂贵但像黑曜石一样防爬行者爆炸。",
"block.engineersdecor.panzerglass_slab": "装甲玻璃台阶",
"block.engineersdecor.panzerglass_slab.help": "§6强化的玻璃台阶。§r昂贵防爆。深灰色调有隐约可见的结构线和多种纹理。",
"block.engineersdecor.treated_wood_floor": "防腐木地板",
"block.engineersdecor.treated_wood_floor.help": "§6装饰性地板砖有可变的贴图。§r",
"block.engineersdecor.rebar_concrete_wall": "钢筋混凝土墙",
"block.engineersdecor.rebar_concrete_wall.help": "§6钢筋混凝土墙.§r 昂贵,但像黑曜石一样防苦力怕.",
"block.engineersdecor.concrete_wall": "水泥墙",
"block.engineersdecor.concrete_wall.help": "§6墙由坚固的混凝土制成.",
"block.engineersdecor.clinker_brick_wall": "Clinker Brick Wall",
"block.engineersdecor.slag_brick_wall": "Slag Brick Wall",
"block.engineersdecor.metal_rung_ladder": "金属环梯",
"block.engineersdecor.metal_rung_ladder.help": "§6典型的工业墙梯,包括水平金属杆横档.",
"block.engineersdecor.metal_rung_steps": "交错的金属台阶",
"block.engineersdecor.metal_rung_steps.help": "§6贴在墙上的交错的杆横档,允许爬上,爬下等等.",
"block.engineersdecor.treated_wood_ladder": "经过处理的木梯",
"block.engineersdecor.treated_wood_ladder.help": "§6防风雨的木梯.",
"block.engineersdecor.clinker_brick_stairs": "熟料砖楼梯",
"block.engineersdecor.clinker_brick_stairs.help": "§6看起来比原版砖块稍暗,颜色更浓.",
"block.engineersdecor.clinker_brick_stained_stairs": "Stained Clinker Brick Stairs",
"block.engineersdecor.rebar_concrete_wall.help": "§6钢强化的混凝土墙。§r 昂贵但像黑曜石一样防爬行者爆炸。",
"block.engineersdecor.concrete_wall": "混凝土墙",
"block.engineersdecor.concrete_wall.help": "§6用坚固混凝土制造的墙。",
"block.engineersdecor.clinker_brick_wall": "过烧砖墙",
"block.engineersdecor.clinker_brick_wall.help": "§6简单的过烧砖墙。",
"block.engineersdecor.slag_brick_wall": "炉渣砖墙",
"block.engineersdecor.slag_brick_wall.help": "§6简单的炉渣砖墙。",
"block.engineersdecor.metal_rung_ladder": "金属蹬梯子",
"block.engineersdecor.metal_rung_ladder.help": "§6典型的工业墙梯由水平的金属杆蹬组成。§r往上/下看会爬得更快。",
"block.engineersdecor.metal_rung_steps": "交错金属台阶",
"block.engineersdecor.metal_rung_steps.help": "§6贴在墙上的交错金属杆蹬能够爬上或爬下。§r往上/下看会爬得更快。",
"block.engineersdecor.treated_wood_ladder": "防腐木梯",
"block.engineersdecor.treated_wood_ladder.help": "§6防风雨的木梯。§r往上/下看会爬得更快。",
"block.engineersdecor.clinker_brick_stairs": "过烧砖楼梯",
"block.engineersdecor.clinker_brick_stairs.help": "§6比原版砖看起来颜色更深色度也更高。",
"block.engineersdecor.clinker_brick_stained_stairs": "污渍过烧砖楼梯",
"block.engineersdecor.clinker_brick_stained_stairs.help": "§6比原版砖看起来颜色更深色度也更高。有更多可见的污垢或污迹。",
"block.engineersdecor.slag_brick_stairs": "炉渣砖楼梯",
"block.engineersdecor.slag_brick_stairs.help": "§6灰褐色砖块楼梯.",
"block.engineersdecor.slag_brick_stairs.help": "§6一种灰棕色砖块楼梯。",
"block.engineersdecor.rebar_concrete_stairs": "钢筋混凝土楼梯",
"block.engineersdecor.rebar_concrete_stairs.help": "§6钢筋混凝土楼梯.§r 昂贵,但像黑曜石一样防苦力怕.",
"block.engineersdecor.rebar_concrete_tile_stairs": "Rebar Concrete Tile Stairs",
"block.engineersdecor.treated_wood_pole": "直立处理木杆",
"block.engineersdecor.treated_wood_pole.help": "§6具有导线继电器直径的直极片段.§r\n如果需要特殊的特殊长度,或作为结构的支撑,可以作为线柱的替代品.",
"block.engineersdecor.treated_wood_pole_head": "Straight Treated Wood Pole Head/Foot",
"block.engineersdecor.treated_wood_pole_support": "Straight Treated Wood Pole Support",
"block.engineersdecor.thick_steel_pole": "Straight Thick Steel Pole",
"block.engineersdecor.thin_steel_pole": "Straight Thin Steel Pole",
"block.engineersdecor.thin_steel_pole_head": "Straight Thin Steel Pole head/foot",
"block.engineersdecor.thick_steel_pole_head": "Straight Thick Steel Pole Head/Foot",
"block.engineersdecor.steel_double_t_support": "Steel Double T Support",
"block.engineersdecor.treated_wood_table": "经过处理的木桌",
"block.engineersdecor.treated_wood_table.help": "§6坚固的四足木桌.",
"block.engineersdecor.steel_table": "Steel Table",
"block.engineersdecor.steel_floor_grating": "Steel Floor Grating",
"block.engineersdecor.treated_wood_stool": "Treated Wood Stool",
"block.engineersdecor.treated_wood_crafting_table": "Treated Wood Crafting Table",
"block.engineersdecor.treated_wood_side_table": "Treated Wood Side Table",
"block.engineersdecor.iron_inset_light": "Inset Light",
"block.engineersdecor.treated_wood_window": "Treated Wood Window",
"block.engineersdecor.treated_wood_windowsill": "Treated Wood Window Sill",
"block.engineersdecor.treated_wood_broad_windowsill": "Broad Treated Wood Window Sill",
"block.engineersdecor.steel_framed_window": "Steel Framed Window",
"block.engineersdecor.steel_mesh_fence": "Steel Mesh Fence",
"block.engineersdecor.small_lab_furnace": "Small Laboratory Furnace",
"block.engineersdecor.small_electrical_furnace": "Small Electrical Furnace",
"block.engineersdecor.small_waste_incinerator": "Small Waste Incinerator",
"block.engineersdecor.straight_pipe_valve": "Fluid Pipe Check Valve",
"block.engineersdecor.straight_pipe_valve_redstone": "Redstone Controlled Fluid Valve",
"block.engineersdecor.straight_pipe_valve_redstone_analog": "Redstone Analog Fluid Valve",
"block.engineersdecor.passive_fluid_accumulator": "Passive Fluid Accumulator",
"block.engineersdecor.factory_dropper": "Factory Dropper",
"block.engineersdecor.small_mineral_smelter": "Small Mineral Melting Furnace",
"block.engineersdecor.small_solar_panel": "Small Solar Panel",
"block.engineersdecor.small_tree_cutter": "Small Tree Cutter",
"block.engineersdecor.sign_decor": "Sign Plate (Engineer's decor)",
"block.engineersdecor.sign_hotwire": "Sign \"Caution Hot Wire\"",
"block.engineersdecor.sign_mindstep": "Sign \"Mind The Step\"",
"block.engineersdecor.sign_danger": "Sign \"Caution Really Dangerous There\"",
"block.engineersdecor.sign_defense": "Sign \"Caution Defense System Ahead\"",
"block.engineersdecor.sign_factoryarea": "Sign \"Factory Area\"",
"block.engineersdecor.sign_exit": "Exit Sign",
"block.engineersdecor.halfslab_rebar_concrete": "Rebar Concrete Slice",
"block.engineersdecor.halfslab_concrete": "Concrete Slice",
"block.engineersdecor.halfslab_treated_wood": "Treated Wood Slice",
"block.engineersdecor.halfslab_sheetmetal_iron": "Iron Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_steel": "Steel Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_copper": "Copper Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_gold": "Gold Sheet Metal Slice",
"block.engineersdecor.halfslab_sheetmetal_aluminum": "Aluminum Sheet Metal Slice",
"block.engineersdecor.testblock": "ED Test Block (do NOT use)"
"block.engineersdecor.rebar_concrete_stairs.help": "§6钢强化的混凝土楼梯。§r昂贵但像黑曜石一样防爬行者爆炸。",
"block.engineersdecor.rebar_concrete_tile_stairs": "钢筋混凝土砖楼梯",
"block.engineersdecor.rebar_concrete_tile_stairs.help": "§6钢强化的混凝土砖楼梯。§r昂贵但像黑曜石一样防爬行者爆炸。",
"block.engineersdecor.treated_wood_pole": "直防腐木杆",
"block.engineersdecor.treated_wood_pole.help": "§6直杆的一段有着继电器的直径。§r\n 在需要特殊长度电线杆的时候很有用, 也可以作为结构的柱子。",
"block.engineersdecor.treated_wood_pole_head": "直防腐木杆头/尾",
"block.engineersdecor.treated_wood_pole_head.help": "§6木制部件适合作为直杆的头或尾。",
"block.engineersdecor.treated_wood_pole_support": "直防腐木杆支撑",
"block.engineersdecor.treated_wood_pole_support.help": "§6重型木制支撑部件适合作为直杆的头或尾。",
"block.engineersdecor.thick_steel_pole": "直粗钢杆",
"block.engineersdecor.thick_steel_pole.help": "§6一段直空心杆(6x6x16),适合用于结构支撑。",
"block.engineersdecor.thin_steel_pole": "直细钢杆",
"block.engineersdecor.thin_steel_pole.help": "§6一段直空心杆(4x4x16),适合用于结构支撑。",
"block.engineersdecor.thin_steel_pole_head": "直细钢杆头/尾",
"block.engineersdecor.thin_steel_pole_head.help": "§6钢制部件适合作为细钢杆(4x4x16)的头或尾。",
"block.engineersdecor.thick_steel_pole_head": "直粗钢杆头/尾",
"block.engineersdecor.thick_steel_pole_head.help": "§6钢制部件适合作为粗钢杆(6x6x16)的头或尾。",
"block.engineersdecor.steel_double_t_support": "钢制双T型支架",
"block.engineersdecor.steel_double_t_support.help": "§6一段水平吊顶支撑梁。",
"block.engineersdecor.treated_wood_table": "防腐木桌",
"block.engineersdecor.treated_wood_table.help": "§6结实的四脚木桌。§r适用于室内和室外使用。",
"block.engineersdecor.steel_table": "钢桌",
"block.engineersdecor.steel_table.help": "§6结实的四脚钢桌。",
"block.engineersdecor.steel_floor_grating": "钢地板格栅",
"block.engineersdecor.steel_floor_grating.help": "§6装饰用钢制地板盖。§r顶端对齐。掉落物会穿过。",
"block.engineersdecor.treated_wood_stool": "防腐木凳",
"block.engineersdecor.treated_wood_stool.help": "§6坚固的木凳。§r适用于室内和室外使用。",
"block.engineersdecor.treated_wood_crafting_table": "防腐木合成台",
"block.engineersdecor.treated_wood_crafting_table.help": "§6坚固防风防雨。§r内含八个存储格破坏后保留内容物没有原版合成书。\n 单击上/下箭头按钮可选择合成历史单击输出格自动放置物品单击X按钮 清除合成栏和历史。Shift单击一叠物品合成格空时转移到存储格 非空时到合成栏。会自动分配转移的物品。",
"block.engineersdecor.treated_wood_side_table": "防腐木茶几",
"block.engineersdecor.treated_wood_side_table.help": "§6干完活后需要喝杯茶。",
"block.engineersdecor.iron_inset_light": "嵌入灯",
"block.engineersdecor.iron_inset_light.help": "§6小型荧石光源能嵌入地板、天花板或墙里。§r\n 用于照亮电力光源难以安装的地方。 亮度与火把一样。",
"block.engineersdecor.treated_wood_window": "防腐木窗",
"block.engineersdecor.treated_wood_window.help": "§6木框三层玻璃窗。绝缘良好。§r不像玻璃板一样连接到相邻方块。",
"block.engineersdecor.treated_wood_windowsill": "防腐木窗台",
"block.engineersdecor.treated_wood_windowsill.help": "§6简单的窗户装饰。",
"block.engineersdecor.treated_wood_broad_windowsill": "宽防腐木窗台",
"block.engineersdecor.treated_wood_broad_windowsill.help": "§6简单的窗户装饰。",
"block.engineersdecor.steel_framed_window": "钢框窗",
"block.engineersdecor.steel_framed_window.help": "§6钢框三层玻璃窗。绝缘良好。§r不像玻璃板一样连接到相邻方块。",
"block.engineersdecor.steel_mesh_fence": "钢丝栅栏",
"block.engineersdecor.steel_mesh_fence.help": "§6工业式栅栏。§r\n不与普通栅栏连接。",
"block.engineersdecor.small_lab_furnace": "小型实验室炉",
"block.engineersdecor.small_lab_furnace.help": "§6小型金属壳实验室窑。§r消耗固体燃料向上排气。 比圆石炉稍微热一点,隔热性也更好,因此效率更高。 有两个用于储存的辅助格。两个堆叠的内部漏斗对输入、输出和燃料进行队列管理。 在辅助格放置一个外置加热器并通入电力可以加快熔炼速度。",
"block.engineersdecor.small_electrical_furnace": "小型电炉",
"block.engineersdecor.small_electrical_furnace.help": "§6小型金属封装穿过式熔炉。§r 自动从输入端获取物品并在输出端物品栏放置物品。 物品能从所有面使用漏斗插入或提取。无法熔炼或烹饪的物品会直接送到出口。 比加热的圆石炉有稍微高的能效比和更快。 先进先出和自动输出一次移动一组物品。自动输出需要一点能量。",
"block.engineersdecor.small_waste_incinerator": "小型垃圾焚烧炉",
"block.engineersdecor.small_waste_incinerator.help": "§6有内部先进先出队列的垃圾桶。§r物品可以从任何一面插入而且 直到队列满都会保留。一旦超过队列上限,最老的物品会被焚毁。 通入RF/FE会增加处理速度。破坏时保留内部未销毁的物品。",
"block.engineersdecor.straight_pipe_valve": "输液管止回阀",
"block.engineersdecor.straight_pipe_valve.help": "§6一段直输液管。§r单向传递流体。 侧面不会与管道连接。会减少流速。潜行能反方向放置。",
"block.engineersdecor.straight_pipe_valve_redstone": "红石控制流体阀",
"block.engineersdecor.straight_pipe_valve_redstone.help": "§6一段直输液管。§r单向传递流体。 侧面不会与管道连接。会减少流速。潜行能反方向放置。 没有红石信号时断流。",
"block.engineersdecor.straight_pipe_valve_redstone_analog": "红石模拟流体阀",
"block.engineersdecor.straight_pipe_valve_redstone_analog.help": "§6一段直输液管。§r单向传递流体。 侧面不会与管道连接。会减少流速。潜行能反方向放置。 没有红石信号时断流流速与红石信号强度从1到14线性增长 15时流速上限达到最大。",
"block.engineersdecor.passive_fluid_accumulator": "被动流体累积器。",
"block.engineersdecor.passive_fluid_accumulator.help": "§6基于真空吸力的流体收集器。§r有一个输出面其他面都是输入。 当从输出面被泵抽取时,从输入面邻接储罐抽取液体。",
"block.engineersdecor.factory_dropper": "工厂掉落器",
"block.engineersdecor.factory_dropper.help": "§6适用于高级工厂自动化的掉落器。§r有十二个轮询选择的储物格。 掉落的力度、角度、一叠数量和冷却延时可在GUI调节。三个 内部比较槽带有逻辑与或逻辑或功能,可用作内部触发源。内部触发 还能和外部红石信号触发再进行逻辑与或逻辑或。触发模拟按钮仅作测试用途。 当内部触发条件满足时,预先打开卷帘门。所有符合条件的物品 会同时掉落。点击GUI的各处来了解如何运作。",
"block.engineersdecor.factory_hopper": "Factory Hopper",
"block.engineersdecor.small_mineral_smelter": "小型矿物熔炼炉",
"block.engineersdecor.small_mineral_smelter.help": "§6高温、高绝缘电熔石炉。§r\n 把矿物块加热成岩浆块,最后变成熔岩。由于 小型化的设备大小,该过程效率不高,需要大量时间和能源 来液化一块石头。",
"block.engineersdecor.small_solar_panel": "小型太阳能板",
"block.engineersdecor.small_solar_panel.help": "§6暴露在阳光下时产生少量能量。§r\n 用于低消耗地在远程系统给低压电容器充电。 内部电荷泵电路积累并频繁输出RF。产出取决于时间 和天气。",
"block.engineersdecor.small_tree_cutter": "小型砍树机",
"block.engineersdecor.small_tree_cutter.help": "§6砍倒正前方的树。§r\n 不收集木材。通入红石信号停用。 提供RF来加快砍树速度。没有的话会很慢。",
"block.engineersdecor.sign_decor": "标志板(工程师的装饰)",
"block.engineersdecor.sign_decor.help": "§6这不应该可合成或在JEI看到。用于创造模式的物品栏标签和截屏。",
"block.engineersdecor.sign_hotwire": "指示牌 \"小心电线\"",
"block.engineersdecor.sign_hotwire.help": "§6电气危害警告。不要忘记在高压线周围放置否则下次审计时你会发现不合格。",
"block.engineersdecor.sign_mindstep": "指示牌 \"小心脚滑\"",
"block.engineersdecor.sign_mindstep.help": "§6能水平放在墙上。",
"block.engineersdecor.sign_danger": "指示牌 \"小心危险\"",
"block.engineersdecor.sign_danger.help": "§6通用危险警告。",
"block.engineersdecor.sign_defense": "指示牌 \"小心防御系统\"",
"block.engineersdecor.sign_defense.help": "§6用于警告炮塔、特斯拉线圈和陷阱。",
"block.engineersdecor.sign_factoryarea": "指示牌 \"工厂区域\"",
"block.engineersdecor.sign_factoryarea.help": "§6用于指示真的很大的机器所在的建筑和区域。",
"block.engineersdecor.sign_exit": "出口指示牌",
"block.engineersdecor.halfslab_rebar_concrete": "强化混凝土切片",
"block.engineersdecor.halfslab_rebar_concrete.help": "§6可垂直堆叠的切片。§r手持切片右/左击切片堆叠的顶端或底部来添加/移除切片。",
"block.engineersdecor.halfslab_concrete": "混凝土切片",
"block.engineersdecor.halfslab_concrete.help": "§6可垂直堆叠的切片。§r手持切片右/左击切片堆叠的顶端或底部来添加/移除切片。",
"block.engineersdecor.halfslab_treated_wood": "防腐木切片",
"block.engineersdecor.halfslab_treated_wood.help": "§6可垂直堆叠的切片。§r手持切片右/左击切片堆叠的顶端或底部来添加/移除切片。",
"block.engineersdecor.halfslab_sheetmetal_iron": "铁板金属块切片",
"block.engineersdecor.halfslab_sheetmetal_iron.help": "§6可垂直堆叠的切片。§r手持切片右/左击切片堆叠的顶端或底部来添加/移除切片。",
"block.engineersdecor.halfslab_sheetmetal_steel": "钢板金属块切片",
"block.engineersdecor.halfslab_sheetmetal_steel.help": "§6可垂直堆叠的切片。§r手持切片右/左击切片堆叠的顶端或底部来添加/移除切片。",
"block.engineersdecor.halfslab_sheetmetal_copper": "铜板金属块切片",
"block.engineersdecor.halfslab_sheetmetal_copper.help": "§6可垂直堆叠的切片。§r手持切片右/左击切片堆叠的顶端或底部来添加/移除切片。",
"block.engineersdecor.halfslab_sheetmetal_gold": "金板金属块切片",
"block.engineersdecor.halfslab_sheetmetal_gold.help": "§6可垂直堆叠的切片。§r手持切片右/左击切片堆叠的顶端或底部来添加/移除切片。",
"block.engineersdecor.halfslab_sheetmetal_aluminum": "铝板金属块切片",
"block.engineersdecor.halfslab_sheetmetal_aluminum.help": "§6可垂直堆叠的切片。§r手持切片右/左击切片堆叠的顶端或底部来添加/移除切片。",
"block.engineersdecor.testblock": "ED测试方块不要使用(do NOT use)",
"block.engineersdecor.testblock.help": "§6不可合成的测试方块有着经常变动的测试功能不要使用最坏可能会游戏崩溃"
}

View file

@ -0,0 +1,255 @@
{
"parent": "block/cube",
"textures": {
"t": "engineersdecor:block/device/factory_hopper_top",
"b": "engineersdecor:block/device/factory_hopper_bottom",
"s": "engineersdecor:block/device/factory_hopper_side",
"f": "engineersdecor:block/device/factory_hopper_front",
"particle": "engineersdecor:block/device/factory_hopper_side"
},
"elements": [
{
"from": [2, 7, 2],
"to": [14, 11, 14],
"faces": {
"north": {"uv": [2, 5, 14, 9], "texture": "#f"},
"east": {"uv": [2, 5, 14, 9], "texture": "#s"},
"south": {"uv": [2, 5, 14, 9], "texture": "#s"},
"west": {"uv": [2, 5, 14, 9], "texture": "#s"},
"up": {"uv": [2, 2, 14, 14], "texture": "#t"},
"down": {"uv": [2, 2, 14, 14], "texture": "#b"}
}
},
{
"from": [4, 1, 4],
"to": [12, 7, 12],
"faces": {
"north": {"uv": [4, 9, 12, 15], "texture": "#f"},
"east": {"uv": [4, 9, 12, 15], "texture": "#s"},
"south": {"uv": [4, 9, 12, 15], "texture": "#s"},
"west": {"uv": [4, 9, 12, 15], "texture": "#s"},
"up": {"uv": [4, 4, 12, 12], "texture": "#s"},
"down": {"uv": [4, 4, 12, 12], "texture": "#b"}
}
},
{
"from": [0, 4, 5],
"to": [2, 10, 11],
"faces": {
"north": {"uv": [14, 6, 16, 12], "texture": "#f"},
"east": {"uv": [5, 6, 11, 12], "texture": "#s"},
"south": {"uv": [0, 6, 2, 12], "texture": "#s"},
"west": {"uv": [5, 6, 11, 12], "texture": "#s"},
"up": {"uv": [0, 5, 2, 11], "texture": "#s"},
"down": {"uv": [0, 5, 2, 11], "texture": "#b"}
}
},
{
"from": [14, 4, 5],
"to": [16, 10, 11],
"faces": {
"north": {"uv": [0, 6, 2, 12], "texture": "#f"},
"east": {"uv": [5, 6, 11, 12], "texture": "#s"},
"south": {"uv": [14, 6, 16, 12], "texture": "#s"},
"west": {"uv": [5, 6, 11, 12], "texture": "#s"},
"up": {"uv": [14, 5, 16, 11], "texture": "#s"},
"down": {"uv": [14, 5, 16, 11], "texture": "#b"}
}
},
{
"from": [2, 3, 5],
"to": [4, 5, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]},
"faces": {
"north": {"uv": [12, 11, 14, 13], "texture": "#f"},
"east": {"uv": [5, 11, 11, 13], "texture": "#s"},
"south": {"uv": [2, 11, 4, 13], "texture": "#s"},
"west": {"uv": [5, 11, 11, 13], "texture": "#s"},
"up": {"uv": [2, 5, 4, 11], "texture": "#s"},
"down": {"uv": [2, 5, 4, 11], "texture": "#b"}
}
},
{
"from": [12, 3, 5],
"to": [14, 5, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]},
"faces": {
"north": {"uv": [2, 11, 4, 13], "texture": "#f"},
"east": {"uv": [5, 11, 11, 13], "texture": "#s"},
"south": {"uv": [12, 11, 14, 13], "texture": "#s"},
"west": {"uv": [5, 11, 11, 13], "texture": "#s"},
"up": {"uv": [12, 5, 14, 11], "texture": "#s"},
"down": {"uv": [12, 5, 14, 11], "texture": "#b"}
}
},
{
"from": [5, 4, 14],
"to": [11, 10, 16],
"faces": {
"north": {"uv": [5, 6, 11, 12], "texture": "#s"},
"east": {"uv": [0, 6, 2, 12], "texture": "#s"},
"south": {"uv": [5, 6, 11, 12], "texture": "#s"},
"west": {"uv": [14, 6, 16, 12], "texture": "#s"},
"up": {"uv": [5, 14, 11, 16], "texture": "#s"},
"down": {"uv": [5, 0, 11, 2], "texture": "#b"}
}
},
{
"from": [5, 3, 12],
"to": [11, 5, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]},
"faces": {
"north": {"uv": [5, 11, 11, 13], "texture": "#s"},
"east": {"uv": [2, 11, 4, 13], "texture": "#s"},
"south": {"uv": [5, 11, 11, 13], "texture": "#s"},
"west": {"uv": [12, 11, 14, 13], "texture": "#s"},
"up": {"uv": [5, 12, 11, 14], "texture": "#s"},
"down": {"uv": [5, 2, 11, 4], "texture": "#b"}
}
},
{
"from": [5, 0, 5],
"to": [11, 1, 11],
"faces": {
"north": {"uv": [5, 15, 11, 16], "texture": "#f"},
"east": {"uv": [5, 15, 11, 16], "texture": "#s"},
"south": {"uv": [5, 15, 11, 16], "texture": "#s"},
"west": {"uv": [5, 15, 11, 16], "texture": "#s"},
"up": {"uv": [5, 5, 11, 11], "texture": "#s"},
"down": {"uv": [5, 5, 11, 11], "texture": "#b"}
}
},
{
"from": [5, 1, 1],
"to": [11, 7, 4],
"faces": {
"north": {"uv": [5, 9, 11, 15], "texture": "#f"},
"east": {"uv": [12, 9, 15, 15], "texture": "#s"},
"south": {"uv": [5, 9, 11, 15], "texture": "#t"},
"west": {"uv": [1, 9, 4, 15], "texture": "#s"},
"up": {"uv": [5, 1, 11, 4], "texture": "#s"},
"down": {"uv": [5, 12, 11, 15], "texture": "#b"}
}
},
{
"from": [5, 1, 0],
"to": [11, 2, 1],
"faces": {
"north": {"uv": [5, 14, 11, 15], "texture": "#f"},
"east": {"uv": [15, 14, 16, 15], "texture": "#s"},
"south": {"uv": [5, 14, 11, 15], "texture": "#t"},
"west": {"uv": [0, 14, 1, 15], "texture": "#s"},
"up": {"uv": [5, 0, 11, 1], "texture": "#s"},
"down": {"uv": [5, 15, 11, 16], "texture": "#b"}
}
},
{
"from": [5, 6, 0],
"to": [11, 7, 1],
"faces": {
"north": {"uv": [5, 9, 11, 10], "texture": "#f"},
"east": {"uv": [15, 9, 16, 10], "texture": "#s"},
"south": {"uv": [5, 9, 11, 10], "texture": "#t"},
"west": {"uv": [0, 9, 1, 10], "texture": "#s"},
"up": {"uv": [5, 0, 11, 1], "texture": "#s"},
"down": {"uv": [5, 15, 11, 16], "texture": "#s"}
}
},
{
"from": [5, 2, 0],
"to": [6, 6, 1],
"faces": {
"north": {"uv": [10, 10, 11, 14], "texture": "#f"},
"east": {"uv": [15, 10, 16, 14], "texture": "#s"},
"south": {"uv": [5, 10, 6, 14], "texture": "#t"},
"west": {"uv": [0, 10, 1, 14], "texture": "#s"},
"up": {"uv": [5, 0, 6, 1], "texture": "#s"},
"down": {"uv": [5, 15, 6, 16], "texture": "#s"}
}
},
{
"from": [10, 2, 0],
"to": [11, 6, 1],
"faces": {
"north": {"uv": [5, 10, 6, 14], "texture": "#f"},
"east": {"uv": [15, 10, 16, 14], "texture": "#s"},
"south": {"uv": [10, 10, 11, 14], "texture": "#t"},
"west": {"uv": [0, 10, 1, 14], "texture": "#s"},
"up": {"uv": [10, 0, 11, 1], "texture": "#s"},
"down": {"uv": [10, 15, 11, 16], "texture": "#s"}
}
},
{
"from": [14, 10, 2],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 2, 6], "texture": "#b"},
"east": {"uv": [0, 0, 14, 6], "texture": "#s"},
"south": {"uv": [14, 0, 16, 6], "texture": "#s"},
"west": {"uv": [2, 2, 16, 8], "texture": "#t"},
"up": {"uv": [14, 2, 16, 16], "texture": "#t"},
"down": {"uv": [14, 0, 16, 14], "texture": "#b"}
}
},
{
"from": [0, 10, 0],
"to": [16, 16, 2],
"faces": {
"north": {"uv": [0, 0, 16, 6], "texture": "#f"},
"east": {"uv": [14, 0, 16, 6], "texture": "#s"},
"south": {"uv": [0, 2, 16, 8], "texture": "#t"},
"west": {"uv": [0, 0, 2, 6], "texture": "#s"},
"up": {"uv": [0, 0, 16, 2], "texture": "#t"},
"down": {"uv": [0, 14, 16, 16], "texture": "#b"}
}
},
{
"from": [0, 10, 14],
"to": [14, 16, 16],
"faces": {
"north": {"uv": [2, 2, 16, 8], "texture": "#t"},
"east": {"uv": [0, 0, 2, 6], "texture": "#s"},
"south": {"uv": [0, 0, 14, 6], "texture": "#s"},
"west": {"uv": [14, 0, 16, 6], "texture": "#s"},
"up": {"uv": [0, 14, 14, 16], "texture": "#t"},
"down": {"uv": [0, 0, 14, 2], "texture": "#b"}
}
},
{
"from": [0, 10, 2],
"to": [2, 16, 14],
"faces": {
"north": {"uv": [14, 0, 16, 6], "texture": "#b"},
"east": {"uv": [2, 2, 14, 8], "texture": "#t"},
"south": {"uv": [0, 0, 2, 6], "texture": "#t"},
"west": {"uv": [2, 0, 14, 6], "texture": "#s"},
"up": {"uv": [0, 2, 2, 14], "texture": "#t"},
"down": {"uv": [0, 2, 2, 14], "texture": "#b"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [85, 3, -10],
"translation": [1.75, -2.25, -2.25],
"scale": [0.35, 0.35, 0.35]
},
"firstperson_righthand": {
"rotation": [22, 65, -44],
"translation": [0.5, 0, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, -0.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {
"rotation": [30, 225, 0],
"translation": [0, -0.25, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
}
}

View file

@ -0,0 +1,260 @@
{
"parent": "block/cube",
"textures": {
"t": "engineersdecor:block/device/factory_hopper_top",
"b": "engineersdecor:block/device/factory_hopper_bottom",
"s": "engineersdecor:block/device/factory_hopper_side",
"particle": "engineersdecor:block/device/factory_hopper_side"
},
"elements": [
{
"from": [2, 7, 2],
"to": [14, 11, 14],
"faces": {
"north": {"uv": [2, 5, 14, 9], "texture": "#s"},
"east": {"uv": [2, 5, 14, 9], "texture": "#s"},
"south": {"uv": [2, 5, 14, 9], "texture": "#s"},
"west": {"uv": [2, 5, 14, 9], "texture": "#s"},
"up": {"uv": [2, 2, 14, 14], "texture": "#t"},
"down": {"uv": [2, 2, 14, 14], "texture": "#b"}
}
},
{
"from": [4, 1, 4],
"to": [12, 7, 12],
"faces": {
"north": {"uv": [4, 9, 12, 15], "texture": "#s"},
"east": {"uv": [4, 9, 12, 15], "texture": "#s"},
"south": {"uv": [4, 9, 12, 15], "texture": "#s"},
"west": {"uv": [4, 9, 12, 15], "texture": "#s"},
"up": {"uv": [4, 4, 12, 12], "texture": "#s"},
"down": {"uv": [4, 4, 12, 12], "texture": "#b"}
}
},
{
"from": [0, 4, 5],
"to": [2, 10, 11],
"faces": {
"north": {"uv": [14, 6, 16, 12], "texture": "#s"},
"east": {"uv": [5, 6, 11, 12], "texture": "#s"},
"south": {"uv": [0, 6, 2, 12], "texture": "#s"},
"west": {"uv": [5, 6, 11, 12], "texture": "#s"},
"up": {"uv": [0, 5, 2, 11], "texture": "#s"},
"down": {"uv": [0, 5, 2, 11], "texture": "#b"}
}
},
{
"from": [14, 4, 5],
"to": [16, 10, 11],
"faces": {
"north": {"uv": [0, 6, 2, 12], "texture": "#s"},
"east": {"uv": [5, 6, 11, 12], "texture": "#s"},
"south": {"uv": [14, 6, 16, 12], "texture": "#s"},
"west": {"uv": [5, 6, 11, 12], "texture": "#s"},
"up": {"uv": [14, 5, 16, 11], "texture": "#s"},
"down": {"uv": [14, 5, 16, 11], "texture": "#b"}
}
},
{
"from": [2, 3, 5],
"to": [4, 5, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]},
"faces": {
"north": {"uv": [12, 10, 14, 12], "texture": "#s"},
"east": {"uv": [5, 10, 11, 12], "texture": "#s"},
"south": {"uv": [2, 10, 4, 12], "texture": "#s"},
"west": {"uv": [5, 10, 11, 12], "texture": "#s"},
"up": {"uv": [2, 5, 4, 11], "texture": "#s"},
"down": {"uv": [2, 5, 4, 11], "texture": "#b"}
}
},
{
"from": [12, 3, 5],
"to": [14, 5, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]},
"faces": {
"north": {"uv": [2, 10, 4, 12], "texture": "#s"},
"east": {"uv": [5, 10, 11, 12], "texture": "#s"},
"south": {"uv": [12, 10, 14, 12], "texture": "#s"},
"west": {"uv": [5, 10, 11, 12], "texture": "#s"},
"up": {"uv": [12, 5, 14, 11], "texture": "#s"},
"down": {"uv": [12, 5, 14, 11], "texture": "#b"}
}
},
{
"from": [5, 4, 14],
"to": [11, 10, 16],
"faces": {
"north": {"uv": [5, 6, 11, 12], "texture": "#s"},
"east": {"uv": [0, 6, 2, 12], "texture": "#s"},
"south": {"uv": [5, 6, 11, 12], "texture": "#s"},
"west": {"uv": [14, 6, 16, 12], "texture": "#s"},
"up": {"uv": [5, 14, 11, 16], "texture": "#s"},
"down": {"uv": [5, 0, 11, 2], "texture": "#b"}
}
},
{
"from": [5, 4, 0],
"to": [11, 10, 2],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -6]},
"faces": {
"north": {"uv": [5, 6, 11, 12], "texture": "#s"},
"east": {"uv": [14, 6, 16, 12], "texture": "#s"},
"south": {"uv": [5, 6, 11, 12], "texture": "#s"},
"west": {"uv": [0, 6, 2, 12], "texture": "#s"},
"up": {"uv": [5, 0, 11, 2], "texture": "#s"},
"down": {"uv": [5, 14, 11, 16], "texture": "#b"}
}
},
{
"from": [5, 3, 12],
"to": [11, 5, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]},
"faces": {
"north": {"uv": [5, 10, 11, 12], "texture": "#s"},
"east": {"uv": [2, 10, 4, 12], "texture": "#s"},
"south": {"uv": [5, 10, 11, 12], "texture": "#s"},
"west": {"uv": [12, 10, 14, 12], "texture": "#s"},
"up": {"uv": [5, 12, 11, 14], "texture": "#s"},
"down": {"uv": [5, 2, 11, 4], "texture": "#s"}
}
},
{
"from": [5, 3, 2],
"to": [11, 5, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7, -2]},
"faces": {
"north": {"uv": [5, 10, 11, 12], "texture": "#s"},
"east": {"uv": [12, 10, 14, 12], "texture": "#s"},
"south": {"uv": [5, 10, 11, 12], "texture": "#s"},
"west": {"uv": [2, 10, 4, 12], "texture": "#s"},
"up": {"uv": [5, 2, 11, 4], "texture": "#s"},
"down": {"uv": [5, 12, 11, 14], "texture": "#b"}
}
},
{
"from": [5, 0, 10],
"to": [11, 1, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 18]},
"faces": {
"north": {"uv": [5, 15, 11, 16], "texture": "#b"},
"east": {"uv": [5, 15, 6, 16], "texture": "#s"},
"south": {"uv": [5, 15, 11, 16], "texture": "#s"},
"west": {"uv": [10, 15, 11, 16], "texture": "#s"},
"up": {"uv": [5, 10, 11, 11], "texture": "#s"},
"down": {"uv": [5, 5, 11, 6], "texture": "#b"}
}
},
{
"from": [5, 0, 5],
"to": [11, 1, 6],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 2, 13]},
"faces": {
"north": {"uv": [5, 15, 11, 16], "texture": "#s"},
"east": {"uv": [10, 15, 11, 16], "texture": "#s"},
"south": {"uv": [5, 15, 11, 16], "texture": "#t"},
"west": {"uv": [5, 15, 6, 16], "texture": "#s"},
"up": {"uv": [5, 5, 11, 6], "texture": "#s"},
"down": {"uv": [5, 10, 11, 11], "texture": "#b"}
}
},
{
"from": [5, 0, 6],
"to": [6, 1, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 6, 14]},
"faces": {
"north": {"uv": [10, 15, 11, 16], "texture": "#b"},
"east": {"uv": [6, 15, 10, 16], "texture": "#s"},
"south": {"uv": [5, 15, 6, 16], "texture": "#t"},
"west": {"uv": [6, 15, 10, 16], "texture": "#s"},
"up": {"uv": [5, 6, 6, 10], "texture": "#s"},
"down": {"uv": [5, 6, 6, 10], "texture": "#b"}
}
},
{
"from": [10, 0, 6],
"to": [11, 1, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 6, 14]},
"faces": {
"north": {"uv": [5, 15, 6, 16], "texture": "#b"},
"east": {"uv": [6, 15, 10, 16], "texture": "#s"},
"south": {"uv": [10, 15, 11, 16], "texture": "#t"},
"west": {"uv": [6, 15, 10, 16], "texture": "#s"},
"up": {"uv": [10, 6, 11, 10], "texture": "#s"},
"down": {"uv": [10, 6, 11, 10], "texture": "#b"}
}
},
{
"from": [14, 10, 2],
"to": [16, 16, 16],
"faces": {
"north": {"uv": [0, 0, 2, 6], "texture": "#b"},
"east": {"uv": [0, 0, 14, 6], "texture": "#s"},
"south": {"uv": [14, 0, 16, 6], "texture": "#s"},
"west": {"uv": [2, 2, 16, 8], "texture": "#t"},
"up": {"uv": [14, 2, 16, 16], "texture": "#t"},
"down": {"uv": [14, 0, 16, 14], "texture": "#b"}
}
},
{
"from": [0, 10, 0],
"to": [16, 16, 2],
"faces": {
"north": {"uv": [0, 0, 16, 6], "texture": "#s"},
"east": {"uv": [14, 0, 16, 6], "texture": "#s"},
"south": {"uv": [0, 2, 16, 8], "texture": "#t"},
"west": {"uv": [0, 0, 2, 6], "texture": "#s"},
"up": {"uv": [0, 0, 16, 2], "texture": "#t"},
"down": {"uv": [0, 14, 16, 16], "texture": "#b"}
}
},
{
"from": [0, 10, 14],
"to": [14, 16, 16],
"faces": {
"north": {"uv": [2, 2, 16, 8], "texture": "#t"},
"east": {"uv": [0, 0, 2, 6], "texture": "#s"},
"south": {"uv": [0, 0, 14, 6], "texture": "#s"},
"west": {"uv": [14, 0, 16, 6], "texture": "#s"},
"up": {"uv": [0, 14, 14, 16], "texture": "#t"},
"down": {"uv": [0, 0, 14, 2], "texture": "#b"}
}
},
{
"from": [0, 10, 2],
"to": [2, 16, 14],
"faces": {
"north": {"uv": [14, 0, 16, 6], "texture": "#b"},
"east": {"uv": [2, 2, 14, 8], "texture": "#t"},
"south": {"uv": [0, 0, 2, 6], "texture": "#t"},
"west": {"uv": [2, 0, 14, 6], "texture": "#s"},
"up": {"uv": [0, 2, 2, 14], "texture": "#t"},
"down": {"uv": [0, 2, 2, 14], "texture": "#b"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [85, 3, -10],
"translation": [1.75, -2.25, -2.25],
"scale": [0.35, 0.35, 0.35]
},
"firstperson_righthand": {
"rotation": [22, 65, -44],
"translation": [0.5, 0, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, -0.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {
"rotation": [30, 225, 0],
"translation": [0, -0.25, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
}
}

View file

@ -0,0 +1,255 @@
{
"parent": "block/cube",
"textures": {
"t": "engineersdecor:block/device/factory_hopper_top",
"b": "engineersdecor:block/device/factory_hopper_bottom",
"s": "engineersdecor:block/device/factory_hopper_side",
"particle": "engineersdecor:block/device/factory_hopper_side"
},
"elements": [
{
"from": [2, 5, 2],
"to": [14, 9, 14],
"faces": {
"north": {"uv": [2, 5, 14, 9], "rotation": 180, "texture": "#s"},
"east": {"uv": [2, 5, 14, 9], "rotation": 180, "texture": "#s"},
"south": {"uv": [2, 5, 14, 9], "rotation": 180, "texture": "#s"},
"west": {"uv": [2, 5, 14, 9], "rotation": 180, "texture": "#s"},
"up": {"uv": [2, 2, 14, 14], "texture": "#b"},
"down": {"uv": [2, 2, 14, 14], "texture": "#t"}
}
},
{
"from": [4, 9, 4],
"to": [12, 15, 12],
"faces": {
"north": {"uv": [4, 9, 12, 15], "rotation": 180, "texture": "#s"},
"east": {"uv": [4, 9, 12, 15], "rotation": 180, "texture": "#s"},
"south": {"uv": [4, 9, 12, 15], "rotation": 180, "texture": "#s"},
"west": {"uv": [4, 9, 12, 15], "rotation": 180, "texture": "#s"},
"up": {"uv": [4, 4, 12, 12], "texture": "#b"},
"down": {"uv": [4, 4, 12, 12], "texture": "#s"}
}
},
{
"from": [0, 6, 5],
"to": [2, 12, 11],
"faces": {
"north": {"uv": [0, 6, 2, 12], "rotation": 180, "texture": "#s"},
"east": {"uv": [5, 6, 11, 12], "rotation": 180, "texture": "#s"},
"south": {"uv": [14, 6, 16, 12], "rotation": 180, "texture": "#s"},
"west": {"uv": [5, 6, 11, 12], "rotation": 180, "texture": "#s"},
"up": {"uv": [0, 5, 2, 11], "texture": "#b"},
"down": {"uv": [0, 5, 2, 11], "texture": "#s"}
}
},
{
"from": [14, 6, 5],
"to": [16, 12, 11],
"faces": {
"north": {"uv": [14, 6, 16, 12], "rotation": 180, "texture": "#s"},
"east": {"uv": [5, 6, 11, 12], "rotation": 180, "texture": "#s"},
"south": {"uv": [0, 6, 2, 12], "rotation": 180, "texture": "#s"},
"west": {"uv": [5, 6, 11, 12], "rotation": 180, "texture": "#s"},
"up": {"uv": [14, 5, 16, 11], "texture": "#b"},
"down": {"uv": [14, 5, 16, 11], "texture": "#s"}
}
},
{
"from": [2, 11, 5],
"to": [4, 13, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 8]},
"faces": {
"north": {"uv": [2, 10, 4, 12], "rotation": 180, "texture": "#s"},
"east": {"uv": [5, 10, 11, 12], "rotation": 180, "texture": "#s"},
"south": {"uv": [12, 10, 14, 12], "rotation": 180, "texture": "#s"},
"west": {"uv": [5, 10, 11, 12], "rotation": 180, "texture": "#s"},
"up": {"uv": [2, 5, 4, 11], "texture": "#b"},
"down": {"uv": [2, 5, 4, 11], "texture": "#s"}
}
},
{
"from": [12, 11, 5],
"to": [14, 13, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 8]},
"faces": {
"north": {"uv": [12, 10, 14, 12], "rotation": 180, "texture": "#s"},
"east": {"uv": [5, 10, 11, 12], "rotation": 180, "texture": "#s"},
"south": {"uv": [2, 10, 4, 12], "rotation": 180, "texture": "#s"},
"west": {"uv": [5, 10, 11, 12], "rotation": 180, "texture": "#s"},
"up": {"uv": [12, 5, 14, 11], "texture": "#b"},
"down": {"uv": [12, 5, 14, 11], "texture": "#s"}
}
},
{
"from": [5, 6, 0],
"to": [11, 12, 2],
"faces": {
"north": {"uv": [5, 6, 11, 12], "rotation": 180, "texture": "#s"},
"east": {"uv": [0, 6, 2, 12], "rotation": 180, "texture": "#s"},
"south": {"uv": [5, 6, 11, 12], "rotation": 180, "texture": "#s"},
"west": {"uv": [14, 6, 16, 12], "rotation": 180, "texture": "#s"},
"up": {"uv": [5, 0, 11, 2], "texture": "#s"},
"down": {"uv": [5, 14, 11, 16], "texture": "#s"}
}
},
{
"from": [5, 6, 14],
"to": [11, 12, 16],
"faces": {
"north": {"uv": [5, 6, 11, 12], "rotation": 180, "texture": "#s"},
"east": {"uv": [14, 6, 16, 12], "rotation": 180, "texture": "#s"},
"south": {"uv": [5, 6, 11, 12], "rotation": 180, "texture": "#s"},
"west": {"uv": [0, 6, 2, 12], "rotation": 180, "texture": "#s"},
"up": {"uv": [5, 14, 11, 16], "texture": "#b"},
"down": {"uv": [5, 0, 11, 2], "texture": "#s"}
}
},
{
"from": [5, 11, 2],
"to": [11, 13, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 8]},
"faces": {
"north": {"uv": [5, 10, 11, 12], "rotation": 180, "texture": "#s"},
"east": {"uv": [2, 10, 4, 12], "rotation": 180, "texture": "#s"},
"south": {"uv": [5, 10, 11, 12], "rotation": 180, "texture": "#s"},
"west": {"uv": [12, 10, 14, 12], "rotation": 180, "texture": "#s"},
"up": {"uv": [5, 2, 11, 4], "texture": "#s"},
"down": {"uv": [5, 12, 11, 14], "texture": "#s"}
}
},
{
"from": [5, 11, 12],
"to": [11, 13, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 9, 8]},
"faces": {
"north": {"uv": [5, 10, 11, 12], "rotation": 180, "texture": "#s"},
"east": {"uv": [12, 10, 14, 12], "rotation": 180, "texture": "#s"},
"south": {"uv": [5, 10, 11, 12], "rotation": 180, "texture": "#s"},
"west": {"uv": [2, 10, 4, 12], "rotation": 180, "texture": "#s"},
"up": {"uv": [5, 12, 11, 14], "texture": "#b"},
"down": {"uv": [5, 2, 11, 4], "texture": "#s"}
}
},
{
"from": [5, 15, 5],
"to": [11, 16, 6],
"faces": {
"north": {"uv": [5, 15, 11, 16], "rotation": 180, "texture": "#t"},
"east": {"uv": [5, 15, 6, 16], "rotation": 180, "texture": "#s"},
"south": {"uv": [5, 15, 11, 16], "rotation": 180, "texture": "#b"},
"west": {"uv": [10, 15, 11, 16], "rotation": 180, "texture": "#s"},
"up": {"uv": [5, 5, 11, 6], "texture": "#b"},
"down": {"uv": [5, 10, 11, 11], "texture": "#s"}
}
},
{
"from": [5, 15, 10],
"to": [11, 16, 11],
"faces": {
"north": {"uv": [5, 15, 11, 16], "rotation": 180, "texture": "#t"},
"east": {"uv": [10, 15, 11, 16], "rotation": 180, "texture": "#s"},
"south": {"uv": [5, 15, 11, 16], "rotation": 180, "texture": "#s"},
"west": {"uv": [5, 15, 6, 16], "rotation": 180, "texture": "#s"},
"up": {"uv": [5, 10, 11, 11], "texture": "#b"},
"down": {"uv": [5, 5, 11, 6], "texture": "#s"}
}
},
{
"from": [5, 15, 6],
"to": [6, 16, 10],
"faces": {
"north": {"uv": [5, 15, 6, 16], "rotation": 180, "texture": "#t"},
"east": {"uv": [6, 15, 10, 16], "rotation": 180, "texture": "#s"},
"south": {"uv": [10, 15, 11, 16], "rotation": 180, "texture": "#b"},
"west": {"uv": [6, 15, 10, 16], "rotation": 180, "texture": "#s"},
"up": {"uv": [5, 6, 6, 10], "texture": "#b"},
"down": {"uv": [5, 6, 6, 10], "texture": "#s"}
}
},
{
"from": [10, 15, 6],
"to": [11, 16, 10],
"faces": {
"north": {"uv": [10, 15, 11, 16], "rotation": 180, "texture": "#t"},
"east": {"uv": [6, 15, 10, 16], "rotation": 180, "texture": "#s"},
"south": {"uv": [5, 15, 6, 16], "rotation": 180, "texture": "#b"},
"west": {"uv": [6, 15, 10, 16], "rotation": 180, "texture": "#s"},
"up": {"uv": [10, 6, 11, 10], "texture": "#b"},
"down": {"uv": [10, 6, 11, 10], "texture": "#s"}
}
},
{
"from": [14, 0, 0],
"to": [16, 6, 14],
"faces": {
"north": {"uv": [14, 0, 16, 6], "rotation": 180, "texture": "#s"},
"east": {"uv": [0, 0, 14, 6], "rotation": 180, "texture": "#s"},
"south": {"uv": [0, 0, 2, 6], "rotation": 180, "texture": "#b"},
"west": {"uv": [2, 2, 16, 8], "rotation": 180, "texture": "#t"},
"up": {"uv": [14, 0, 16, 14], "texture": "#b"},
"down": {"uv": [14, 2, 16, 16], "texture": "#t"}
}
},
{
"from": [0, 0, 14],
"to": [16, 6, 16],
"faces": {
"north": {"uv": [0, 2, 16, 8], "rotation": 180, "texture": "#t"},
"east": {"uv": [14, 0, 16, 6], "rotation": 180, "texture": "#s"},
"south": {"uv": [0, 0, 16, 6], "rotation": 180, "texture": "#s"},
"west": {"uv": [0, 0, 2, 6], "rotation": 180, "texture": "#s"},
"up": {"uv": [0, 14, 16, 16], "texture": "#b"},
"down": {"uv": [0, 0, 16, 2], "texture": "#t"}
}
},
{
"from": [0, 0, 0],
"to": [14, 6, 2],
"faces": {
"north": {"uv": [0, 0, 14, 6], "rotation": 180, "texture": "#s"},
"east": {"uv": [0, 0, 2, 6], "rotation": 180, "texture": "#s"},
"south": {"uv": [2, 2, 16, 8], "rotation": 180, "texture": "#t"},
"west": {"uv": [14, 0, 16, 6], "rotation": 180, "texture": "#s"},
"up": {"uv": [0, 0, 14, 2], "texture": "#b"},
"down": {"uv": [0, 14, 14, 16], "texture": "#t"}
}
},
{
"from": [0, 0, 2],
"to": [2, 6, 14],
"faces": {
"north": {"uv": [0, 0, 2, 6], "rotation": 180, "texture": "#t"},
"east": {"uv": [2, 2, 14, 8], "rotation": 180, "texture": "#t"},
"south": {"uv": [14, 0, 16, 6], "rotation": 180, "texture": "#b"},
"west": {"uv": [2, 0, 14, 6], "rotation": 180, "texture": "#s"},
"up": {"uv": [0, 2, 2, 14], "texture": "#b"},
"down": {"uv": [0, 2, 2, 14], "texture": "#t"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [85, 3, -10],
"translation": [1.75, -2.25, -2.25],
"scale": [0.35, 0.35, 0.35]
},
"firstperson_righthand": {
"rotation": [22, 65, -44],
"translation": [0.5, 0, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, -0.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {
"rotation": [30, 225, 0],
"translation": [0, -0.25, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"scale": [0.5, 0.5, 0.5]
}
}
}

View file

@ -0,0 +1 @@
{ "parent": "engineersdecor:block/device/factory_hopper_model" }

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 505 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB