1.12: Added Factory Block Placer/Planter.
This commit is contained in:
parent
17ab68eb78
commit
297b840b65
33 changed files with 1190 additions and 49 deletions
|
@ -4,4 +4,4 @@ org.gradle.jvmargs=-Xmx8G
|
|||
version_minecraft=1.12.2
|
||||
version_forge=14.23.5.2768
|
||||
version_jei=4.10.0.198
|
||||
version_engineersdecor=1.0.14
|
||||
version_engineersdecor=1.0.15-b1
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
|
||||
"1.12.2": {
|
||||
"1.0.15-b1": "[A] Added Floor Edge Light.\n[A] Added Factory Block Placer and Planter.",
|
||||
"1.0.14": "[R] Release based on v1.0.14-b1. Release-to-release changes: * Factory Hopper added. * Small Waste Incinerator improved. * Lang updates. * Recipe fixes.",
|
||||
"1.0.14-b1": "[A] Factory Hopper added (configurable hopper and item collector).\n[M] Small Waste Incinerator Fifo shifting improved.\n[M] Lang file zh_cn updated (scikirbypoke, PR#53).\n[F] Fixed conditional recipe constant for redstone pipe valve (thx @albert_ac).",
|
||||
"1.0.13": "[R] Release based on v1.0.13-b2. Release-to-release changes: * Small Tree Cutter device added. * Small Solar Panel added. * Steel Mesh Fence added. * Broad Window Sill added.",
|
||||
|
@ -63,6 +64,6 @@
|
|||
},
|
||||
"promos": {
|
||||
"1.12.2-recommended": "1.0.14",
|
||||
"1.12.2-latest": "1.0.14"
|
||||
"1.12.2-latest": "1.0.15-b1"
|
||||
}
|
||||
}
|
|
@ -10,6 +10,9 @@ Mod sources for Minecraft version 1.12.2.
|
|||
----
|
||||
## Version history
|
||||
|
||||
- v1.0.15-b1 [A] Added Floor Edge Light.
|
||||
[A] Added Factory Block Placer and Planter.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
- v1.0.14 [R] Release based on v1.0.14-b1. Release-to-release changes:
|
||||
* Factory Hopper added.
|
||||
|
|
|
@ -32,34 +32,7 @@ import net.minecraftforge.fml.client.registry.ClientRegistry;
|
|||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import wile.engineersdecor.blocks.BlockDecor;
|
||||
import wile.engineersdecor.blocks.BlockDecorChair;
|
||||
import wile.engineersdecor.blocks.BlockDecorCraftingTable;
|
||||
import wile.engineersdecor.blocks.BlockDecorDirected;
|
||||
import wile.engineersdecor.blocks.BlockDecorDropper;
|
||||
import wile.engineersdecor.blocks.BlockDecorFence;
|
||||
import wile.engineersdecor.blocks.BlockDecorFloorGrating;
|
||||
import wile.engineersdecor.blocks.BlockDecorFull;
|
||||
import wile.engineersdecor.blocks.BlockDecorFurnace;
|
||||
import wile.engineersdecor.blocks.BlockDecorFurnaceElectrical;
|
||||
import wile.engineersdecor.blocks.BlockDecorGlassBlock;
|
||||
import wile.engineersdecor.blocks.BlockDecorHalfSlab;
|
||||
import wile.engineersdecor.blocks.BlockDecorHopper;
|
||||
import wile.engineersdecor.blocks.BlockDecorHorizontalSupport;
|
||||
import wile.engineersdecor.blocks.BlockDecorLadder;
|
||||
import wile.engineersdecor.blocks.BlockDecorMineralSmelter;
|
||||
import wile.engineersdecor.blocks.BlockDecorPassiveFluidAccumulator;
|
||||
import wile.engineersdecor.blocks.BlockDecorPipeValve;
|
||||
import wile.engineersdecor.blocks.BlockDecorSlab;
|
||||
import wile.engineersdecor.blocks.BlockDecorSolarPanel;
|
||||
import wile.engineersdecor.blocks.BlockDecorStairs;
|
||||
import wile.engineersdecor.blocks.BlockDecorStraightPole;
|
||||
import wile.engineersdecor.blocks.BlockDecorTest;
|
||||
import wile.engineersdecor.blocks.BlockDecorTreeCutter;
|
||||
import wile.engineersdecor.blocks.BlockDecorWall;
|
||||
import wile.engineersdecor.blocks.BlockDecorWasteIncinerator;
|
||||
import wile.engineersdecor.blocks.BlockDecorWindow;
|
||||
import wile.engineersdecor.blocks.BlockDecorWindowSill;
|
||||
import wile.engineersdecor.blocks.*;
|
||||
import wile.engineersdecor.detail.ModAuxiliaries;
|
||||
import wile.engineersdecor.detail.ModConfig;
|
||||
import wile.engineersdecor.detail.ModTesrs;
|
||||
|
@ -144,6 +117,13 @@ public class ModContent
|
|||
ModAuxiliaries.getPixeledAABB(2,2,2, 14,14,14)
|
||||
);
|
||||
|
||||
public static final BlockDecorPlacer FACTORY_PLACER = new BlockDecorPlacer(
|
||||
"factory_placer",
|
||||
BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_FLIP_PLACEMENT_SHIFTCLICK|BlockDecor.CFG_REDSTONE_CONTROLLED,
|
||||
Material.IRON, 1f, 15f, SoundType.METAL,
|
||||
ModAuxiliaries.getPixeledAABB(2,2,2, 14,14,14)
|
||||
);
|
||||
|
||||
public static final BlockDecorWasteIncinerator SMALL_WASTE_INCINERATOR = new BlockDecorWasteIncinerator(
|
||||
"small_waste_incinerator",
|
||||
BlockDecor.CFG_DEFAULT|BlockDecor.CFG_ELECTRICAL,
|
||||
|
@ -490,6 +470,9 @@ public class ModContent
|
|||
private static final TileEntityRegistrationData FACTORY_HOPPER_TEI = new TileEntityRegistrationData(
|
||||
BlockDecorHopper.BTileEntity.class, "te_factory_hopper"
|
||||
);
|
||||
private static final TileEntityRegistrationData FACTORY_PLACER_TEI = new TileEntityRegistrationData(
|
||||
BlockDecorPlacer.BTileEntity.class, "te_factory_placer"
|
||||
);
|
||||
private static final TileEntityRegistrationData SMALL_MINERAL_SMELTER_TEI = new TileEntityRegistrationData(
|
||||
BlockDecorMineralSmelter.BTileEntity.class, "te_small_mineral_smelter"
|
||||
);
|
||||
|
@ -513,6 +496,7 @@ public class ModContent
|
|||
SMALL_ELECTRICAL_FURNACE, SMALL_ELECTRICAL_FURNACE_TEI,
|
||||
FACTORY_HOPPER,FACTORY_HOPPER_TEI,
|
||||
FACTORY_DROPPER, FACTORY_DROPPER_TEI,
|
||||
FACTORY_PLACER, FACTORY_PLACER_TEI,
|
||||
SMALL_WASTE_INCINERATOR, WASTE_INCINERATOR_TEI,
|
||||
STRAIGHT_CHECK_VALVE, STRAIGHT_REDSTONE_VALVE, STRAIGHT_REDSTONE_ANALOG_VALVE, STRAIGHT_PIPE_VALVE_TEI,
|
||||
PASSIVE_FLUID_ACCUMULATOR, PASSIVE_FLUID_ACCUMULATOR_TEI,
|
||||
|
@ -551,6 +535,7 @@ public class ModContent
|
|||
TREATED_WOOD_WINDOWSILL,
|
||||
TREATED_WOOD_BROAD_WINDOWSILL,
|
||||
INSET_LIGHT_IRON,
|
||||
FLOOR_EDGE_LIGHT_IRON,
|
||||
TREATED_WOOD_POLE_SUPPORT,
|
||||
TREATED_WOOD_POLE_HEAD,
|
||||
THIN_STEEL_POLE,
|
||||
|
@ -572,7 +557,6 @@ public class ModContent
|
|||
PANZERGLASS_SLAB, // @todo: check if another class is needed due to is_side_visible
|
||||
TREATED_WOOD_FLOOR, // @todo: check if textures need improvement
|
||||
TEST_BLOCK,TEST_BLOCK_TEI,
|
||||
FLOOR_EDGE_LIGHT_IRON
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -159,6 +159,7 @@ public class ModEngineersDecor
|
|||
public static final int GUIID_SMALL_WASTE_INCINERATOR = 213104;
|
||||
public static final int GUIID_FACTORY_DROPPER = 213105;
|
||||
public static final int GUIID_FACTORY_HOPPER = 213106;
|
||||
public static final int GUIID_FACTORY_PLACER = 213107;
|
||||
|
||||
@Override
|
||||
public Object getServerGuiElement(final int guiid, final EntityPlayer player, final World world, int x, int y, int z)
|
||||
|
@ -172,6 +173,7 @@ public class ModEngineersDecor
|
|||
case GUIID_SMALL_WASTE_INCINERATOR: return BlockDecorWasteIncinerator.getServerGuiElement(player, world, pos, te);
|
||||
case GUIID_FACTORY_DROPPER: return BlockDecorDropper.getServerGuiElement(player, world, pos, te);
|
||||
case GUIID_FACTORY_HOPPER: return BlockDecorHopper.getServerGuiElement(player, world, pos, te);
|
||||
case GUIID_FACTORY_PLACER: return BlockDecorPlacer.getServerGuiElement(player, world, pos, te);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -189,6 +191,7 @@ public class ModEngineersDecor
|
|||
case GUIID_SMALL_WASTE_INCINERATOR: return BlockDecorWasteIncinerator.getClientGuiElement(player, world, pos, te);
|
||||
case GUIID_FACTORY_DROPPER: return BlockDecorDropper.getClientGuiElement(player, world, pos, te);
|
||||
case GUIID_FACTORY_HOPPER: return BlockDecorHopper.getClientGuiElement(player, world, pos, te);
|
||||
case GUIID_FACTORY_PLACER: return BlockDecorPlacer.getClientGuiElement(player, world, pos, te);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,714 @@
|
|||
/*
|
||||
* @file BlockDecorPlacer.java
|
||||
* @author Stefan Wilhelm (wile)
|
||||
* @copyright (C) 2019 Stefan Wilhelm
|
||||
* @license MIT (see https://opensource.org/licenses/MIT)
|
||||
*
|
||||
* Block placer and planter, factory automation suitable.
|
||||
*/
|
||||
package wile.engineersdecor.blocks;
|
||||
|
||||
|
||||
|
||||
|
||||
import wile.engineersdecor.ModEngineersDecor;
|
||||
import wile.engineersdecor.detail.Networking;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.SoundEvents;
|
||||
|
||||
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.block.state.BlockFaceShape;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.Explosion;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.item.*;
|
||||
import net.minecraft.inventory.*;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraftforge.common.IPlantable;
|
||||
import net.minecraftforge.common.util.FakePlayer;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.items.wrapper.SidedInvWrapper;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class BlockDecorPlacer extends BlockDecorDirected
|
||||
{
|
||||
public BlockDecorPlacer(@Nonnull String registryName, long config, @Nullable Material material, float hardness, float resistance, @Nullable SoundType sound, @Nonnull AxisAlignedBB unrotatedAABB)
|
||||
{ super(registryName, config, material, hardness, resistance, sound, unrotatedAABB); }
|
||||
|
||||
@Override
|
||||
public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face)
|
||||
{ return BlockFaceShape.SOLID; }
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public boolean hasComparatorInputOverride(IBlockState state)
|
||||
{ return true; }
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public int getComparatorInputOverride(IBlockState blockState, World world, BlockPos pos)
|
||||
{ return Container.calcRedstone(world.getTileEntity(pos)); }
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(IBlockState state)
|
||||
{ return true; }
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public TileEntity createTileEntity(World world, IBlockState state)
|
||||
{ return new BTileEntity(); }
|
||||
|
||||
@Override
|
||||
public void onBlockPlacedBy(World world, BlockPos pos, IBlockState state, EntityLivingBase placer, ItemStack stack)
|
||||
{
|
||||
if(world.isRemote) return;
|
||||
if((!stack.hasTagCompound()) || (!stack.getTagCompound().hasKey("tedata"))) return;
|
||||
NBTTagCompound te_nbt = stack.getTagCompound().getCompoundTag("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 removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
|
||||
{
|
||||
if(world.isRemote) return true;
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if(!(te instanceof BTileEntity)) return super.removedByPlayer(state, world, pos, player, willHarvest);
|
||||
ItemStack stack = new ItemStack(this, 1);
|
||||
NBTTagCompound te_nbt = new NBTTagCompound();
|
||||
((BTileEntity) te).writenbt(te_nbt, false);
|
||||
if(!te_nbt.isEmpty()) {
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setTag("tedata", te_nbt);
|
||||
stack.setTagCompound(nbt);
|
||||
}
|
||||
world.spawnEntity(new EntityItem(world, pos.getX()+0.5, pos.getY()+0.5, pos.getZ()+0.5, stack));
|
||||
world.setBlockToAir(pos);
|
||||
world.removeTileEntity(pos);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlockExploded(World world, BlockPos pos, Explosion explosion)
|
||||
{
|
||||
if(world.isRemote) return;
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if(!(te instanceof BTileEntity)) return;
|
||||
for(ItemStack stack: ((BTileEntity)te).stacks_) {
|
||||
if(!stack.isEmpty()) world.spawnEntity(new EntityItem(world, pos.getX(), pos.getY(), pos.getZ(), stack));
|
||||
}
|
||||
((BTileEntity)te).reset_rtstate();
|
||||
super.onBlockExploded(world, pos, explosion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
|
||||
{
|
||||
if(world.isRemote) return true;
|
||||
player.openGui(ModEngineersDecor.instance, ModEngineersDecor.GuiHandler.GUIID_FACTORY_PLACER, world, pos.getX(), pos.getY(), pos.getZ());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block block, BlockPos neighborPos)
|
||||
{
|
||||
if(!(world instanceof World) || (((World) world).isRemote)) return;
|
||||
TileEntity te = world.getTileEntity(pos);
|
||||
if(!(te instanceof BTileEntity)) return;
|
||||
((BTileEntity)te).block_updated();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// ModEngineersDecor.GuiHandler connectors
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public static Object getServerGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te)
|
||||
{ return (te instanceof BTileEntity) ? (new BContainer(player.inventory, world, pos, (BTileEntity)te)) : null; }
|
||||
|
||||
public static Object getClientGuiElement(final EntityPlayer player, final World world, final BlockPos pos, final TileEntity te)
|
||||
{ return (te instanceof BTileEntity) ? (new BGui(player.inventory, world, pos, (BTileEntity)te)) : null; }
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// GUI
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
private static class BGui extends GuiContainer
|
||||
{
|
||||
private final BTileEntity te;
|
||||
|
||||
public BGui(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te)
|
||||
{ super(new BContainer(playerInventory, world, pos, te)); this.te = te; }
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{ super.initGui(); }
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float partialTicks)
|
||||
{
|
||||
drawDefaultBackground();
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
renderHoveredToolTip(mouseX, mouseY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException
|
||||
{
|
||||
super.mouseClicked(mouseX, mouseY, mouseButton);
|
||||
BContainer container = (BContainer)inventorySlots;
|
||||
if(container.fields_.length != 3) return;
|
||||
int mx = mouseX - getGuiLeft(), my = mouseY - getGuiTop();
|
||||
if(!isPointInRegion(126, 1, 49, 60, mouseX, mouseY)) {
|
||||
return;
|
||||
} else if(isPointInRegion(133, 49, 9, 9, mouseX, mouseY)) {
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setInteger("manual_trigger", 1);
|
||||
Networking.PacketTileNotify.sendToServer(te, nbt);
|
||||
} else if(isPointInRegion(145, 49, 9, 9, mouseX, mouseY)) {
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setInteger("logic", container.fields_[0] ^ BTileEntity.LOGIC_INVERTED);
|
||||
Networking.PacketTileNotify.sendToServer(te, nbt);
|
||||
} else if(isPointInRegion(159, 49, 7, 9, mouseX, mouseY)) {
|
||||
NBTTagCompound nbt = new NBTTagCompound();
|
||||
nbt.setInteger("logic", container.fields_[0] ^ BTileEntity.LOGIC_CONTINUOUS);
|
||||
Networking.PacketTileNotify.sendToServer(te, nbt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY)
|
||||
{
|
||||
GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
mc.getTextureManager().bindTexture(new ResourceLocation(ModEngineersDecor.MODID, "textures/gui/factory_placer_gui.png"));
|
||||
final int x0=getGuiLeft(), y0=getGuiTop(), w=getXSize(), h=getYSize();
|
||||
drawTexturedModalRect(x0, y0, 0, 0, w, h);
|
||||
BContainer container = (BContainer)inventorySlots;
|
||||
if(container.fields_.length != 3) return; // no init, no cake.
|
||||
// active slot
|
||||
{
|
||||
int slot_index = container.fields_[2];
|
||||
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));
|
||||
drawTexturedModalRect(x, y, 200, 8, 18, 18);
|
||||
}
|
||||
// redstone input
|
||||
{
|
||||
if(container.fields_[1] != 0) {
|
||||
drawTexturedModalRect(x0+133, y0+49, 217, 49, 9, 9);
|
||||
}
|
||||
}
|
||||
// trigger logic
|
||||
{
|
||||
int inverter_offset = ((container.fields_[0] & BTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0;
|
||||
drawTexturedModalRect(x0+145, y0+49, 177+inverter_offset, 49, 9, 9);
|
||||
int pulse_mode_offset = ((container.fields_[0] & BTileEntity.LOGIC_CONTINUOUS ) != 0) ? 9 : 0;
|
||||
drawTexturedModalRect(x0+159, y0+49, 199+pulse_mode_offset, 49, 9, 9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// container
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public static class BContainer extends Container
|
||||
{
|
||||
private static final int PLAYER_INV_START_SLOTNO = BTileEntity.NUM_OF_SLOTS;
|
||||
private final World world;
|
||||
private final BlockPos pos;
|
||||
private final EntityPlayer player;
|
||||
private final BTileEntity te;
|
||||
private int fields_[] = new int[3];
|
||||
|
||||
public BContainer(InventoryPlayer playerInventory, World world, BlockPos pos, BTileEntity te)
|
||||
{
|
||||
this.player = playerInventory.player;
|
||||
this.world = world;
|
||||
this.pos = pos;
|
||||
this.te = te;
|
||||
int i=-1;
|
||||
// device 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;
|
||||
addSlotToContainer(new Slot(te, ++i, xpos, ypos));
|
||||
}
|
||||
}
|
||||
// player slots
|
||||
for(int x=0; x<9; ++x) {
|
||||
addSlotToContainer(new Slot(playerInventory, x, 8+x*18, 129)); // player slots: 0..8
|
||||
}
|
||||
for(int y=0; y<3; ++y) {
|
||||
for(int x=0; x<9; ++x) {
|
||||
addSlotToContainer(new Slot(playerInventory, x+y*9+9, 8+x*18, 71+y*18)); // player slots: 9..35
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BlockPos getPos()
|
||||
{ return pos; }
|
||||
|
||||
@Override
|
||||
public void addListener(IContainerListener listener)
|
||||
{ super.addListener(listener); listener.sendAllWindowProperties(this, te); }
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges()
|
||||
{
|
||||
super.detectAndSendChanges();
|
||||
for(int il=0; il<listeners.size(); ++il) {
|
||||
IContainerListener lis = listeners.get(il);
|
||||
for(int k=0; k<fields_.length; ++k) {
|
||||
int f = te.getField(k);
|
||||
if(fields_[k] != f) {
|
||||
fields_[k] = f;
|
||||
lis.sendWindowProperty(this, k, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void updateProgressBar(int id, int value)
|
||||
{
|
||||
if((id < 0) || (id >= fields_.length)) return;
|
||||
fields_[id] = value;
|
||||
te.setField(id, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer player)
|
||||
{ return (world.getBlockState(pos).getBlock() instanceof BlockDecorPlacer) && (player.getDistanceSq(pos) <= 64); }
|
||||
|
||||
@Override
|
||||
public ItemStack transferStackInSlot(EntityPlayer player, int index)
|
||||
{
|
||||
Slot slot = inventorySlots.get(index);
|
||||
if((slot==null) || (!slot.getHasStack())) return ItemStack.EMPTY;
|
||||
ItemStack slot_stack = slot.getStack();
|
||||
ItemStack transferred = slot_stack.copy();
|
||||
if((index>=0) && (index<PLAYER_INV_START_SLOTNO)) {
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
// Tile entity
|
||||
//--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
public static class BTileEntity extends TileEntity implements ITickable, ISidedInventory, Networking.IPacketReceiver
|
||||
{
|
||||
public static final int TICK_INTERVAL = 40;
|
||||
public static final int NUM_OF_SLOTS = 18;
|
||||
///
|
||||
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 logic_ = LOGIC_INVERTED|LOGIC_CONTINUOUS;
|
||||
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 placer:");
|
||||
}
|
||||
|
||||
public BTileEntity()
|
||||
{
|
||||
stacks_ = NonNullList.<ItemStack>withSize(NUM_OF_SLOTS, ItemStack.EMPTY);
|
||||
reset_rtstate();
|
||||
}
|
||||
|
||||
public void reset_rtstate()
|
||||
{
|
||||
block_power_signal_ = false;
|
||||
block_power_updated_ = false;
|
||||
}
|
||||
|
||||
public void readnbt(NBTTagCompound 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.getInteger("act_slot_index");
|
||||
logic_ = nbt.getInteger("logic");
|
||||
}
|
||||
|
||||
protected void writenbt(NBTTagCompound nbt, boolean update_packet)
|
||||
{
|
||||
ItemStackHelper.saveAllItems(nbt, stacks_);
|
||||
nbt.setBoolean("powered", block_power_signal_);
|
||||
nbt.setInteger("act_slot_index", current_slot_index_);
|
||||
nbt.setInteger("logic", logic_);
|
||||
}
|
||||
|
||||
public void block_updated()
|
||||
{
|
||||
boolean powered = world.isBlockPowered(pos);
|
||||
if(block_power_signal_ != powered) block_power_updated_ = true;
|
||||
block_power_signal_ = powered;
|
||||
if(block_power_updated_) {
|
||||
tick_timer_ = 1;
|
||||
} else if(tick_timer_ > 4) {
|
||||
tick_timer_ = 4;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean is_input_slot(int index)
|
||||
{ return (index >= 0) && (index < NUM_OF_SLOTS); }
|
||||
|
||||
// TileEntity ------------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns)
|
||||
{ return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorPlacer)); }
|
||||
|
||||
@Override
|
||||
public void readFromNBT(NBTTagCompound nbt)
|
||||
{ super.readFromNBT(nbt); readnbt(nbt, false); }
|
||||
|
||||
@Override
|
||||
public NBTTagCompound writeToNBT(NBTTagCompound nbt)
|
||||
{ super.writeToNBT(nbt); writenbt(nbt, false); return nbt; }
|
||||
|
||||
// IWorldNamable ---------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public String getName()
|
||||
{ final Block block=getBlockType(); return (block!=null) ? (block.getTranslationKey() + ".name") : (""); }
|
||||
|
||||
@Override
|
||||
public boolean hasCustomName()
|
||||
{ return false; }
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName()
|
||||
{ return new TextComponentTranslation(getName(), new Object[0]); }
|
||||
|
||||
// IInventory ------------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public int getSizeInventory()
|
||||
{ return stacks_.size(); }
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{ for(ItemStack stack: stacks_) { if(!stack.isEmpty()) return false; } return true; }
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int index)
|
||||
{ return (index < getSizeInventory()) ? stacks_.get(index) : ItemStack.EMPTY; }
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int index, int count)
|
||||
{ return ItemStackHelper.getAndSplit(stacks_, index, count); }
|
||||
|
||||
@Override
|
||||
public ItemStack removeStackFromSlot(int index)
|
||||
{ return ItemStackHelper.getAndRemove(stacks_, index); }
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int index, ItemStack stack)
|
||||
{
|
||||
stacks_.set(index, stack);
|
||||
if(stack.getCount() > getInventoryStackLimit()) stack.setCount(getInventoryStackLimit());
|
||||
if(tick_timer_ > 8) tick_timer_ = 8;
|
||||
markDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit()
|
||||
{ return 64; }
|
||||
|
||||
@Override
|
||||
public void markDirty()
|
||||
{ super.markDirty(); }
|
||||
|
||||
@Override
|
||||
public boolean isUsableByPlayer(EntityPlayer player)
|
||||
{ return ((world.getTileEntity(pos) == this) && (player.getDistanceSq(pos.getX()+0.5d, pos.getY()+0.5d, pos.getZ()+0.5d) <= 64.0d)); }
|
||||
|
||||
@Override
|
||||
public void openInventory(EntityPlayer player)
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void closeInventory(EntityPlayer player)
|
||||
{ markDirty(); }
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int index, ItemStack stack)
|
||||
{ return true; }
|
||||
|
||||
@Override
|
||||
public int getField(int id)
|
||||
{
|
||||
switch(id) {
|
||||
case 0: return logic_;
|
||||
case 1: return block_power_signal_ ? 1 : 0;
|
||||
case 2: return current_slot_index_;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setField(int id, int value)
|
||||
{
|
||||
switch(id) {
|
||||
case 0: logic_ = value; return;
|
||||
case 1: block_power_signal_ = (value != 0); return;
|
||||
case 2: current_slot_index_ = MathHelper.clamp(value, 0, NUM_OF_SLOTS-1); return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getFieldCount()
|
||||
{ return 3; }
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{ stacks_.clear(); }
|
||||
|
||||
// ISidedInventory ----------------------------------------------------------------------------
|
||||
|
||||
private final IItemHandler item_handler_ = new SidedInvWrapper(this, EnumFacing.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(EnumFacing side)
|
||||
{ return SIDED_INV_SLOTS; }
|
||||
|
||||
@Override
|
||||
public boolean canInsertItem(int index, ItemStack stack, EnumFacing direction)
|
||||
{ return is_input_slot(index) && isItemValidForSlot(index, stack); }
|
||||
|
||||
@Override
|
||||
public boolean canExtractItem(int index, ItemStack stack, EnumFacing direction)
|
||||
{ return false; }
|
||||
|
||||
// Capability export ----------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean hasCapability(Capability<?> cap, EnumFacing facing)
|
||||
{ return (cap==CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) || super.hasCapability(cap, facing); }
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing)
|
||||
{
|
||||
if(capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return (T)item_handler_;
|
||||
return super.getCapability(capability, facing);
|
||||
}
|
||||
|
||||
// IPacketReceiver -------------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public void onServerPacketReceived(NBTTagCompound nbt)
|
||||
{}
|
||||
|
||||
@Override
|
||||
public void onClientPacketReceived(EntityPlayer player, NBTTagCompound nbt)
|
||||
{
|
||||
if(nbt.hasKey("logic")) logic_ = nbt.getInteger("logic");
|
||||
if(nbt.hasKey("manual_trigger") && (nbt.getInteger("manual_trigger")!=0)) { block_power_signal_=true; block_power_updated_=true; tick_timer_=1; }
|
||||
markDirty();
|
||||
}
|
||||
|
||||
// ITickable and aux methods ---------------------------------------------------------------------
|
||||
|
||||
private static int next_slot(int i)
|
||||
{ return (i<NUM_OF_SLOTS-1) ? (i+1) : 0; }
|
||||
|
||||
private boolean spit_out(EnumFacing facing)
|
||||
{
|
||||
ItemStack stack = stacks_.get(current_slot_index_);
|
||||
ItemStack drop = stack.copy();
|
||||
stack.shrink(1);
|
||||
stacks_.set(current_slot_index_, stack);
|
||||
drop.setCount(1);
|
||||
for(int i=0; i<8; ++i) {
|
||||
BlockPos p = pos.offset(facing, i);
|
||||
if(!world.isAirBlock(p)) continue;
|
||||
world.spawnEntity(new EntityItem(world, (p.getX()+0.5), (p.getY()+0.5), (p.getZ()+0.5), drop));
|
||||
world.playSound(null, p, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 0.7f, 0.8f);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean try_place(EnumFacing facing)
|
||||
{
|
||||
if(world.isRemote) return false;
|
||||
BlockPos placement_pos = pos.offset(facing);
|
||||
if(world.getTileEntity(placement_pos) != null) return false;
|
||||
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; }
|
||||
boolean no_space = false;
|
||||
final Item item = current_stack.getItem();
|
||||
Block block = (item instanceof IPlantable) ? (((IPlantable)item).getPlant(world, pos).getBlock()) : Block.getBlockFromItem(item);
|
||||
if(block == Blocks.AIR) {
|
||||
if(item != null) {
|
||||
return spit_out(facing); // Item not accepted
|
||||
} 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 != Blocks.AIR) {
|
||||
try {
|
||||
final FakePlayer placer = net.minecraftforge.common.util.FakePlayerFactory.getMinecraft((net.minecraft.world.WorldServer)world);
|
||||
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));
|
||||
if(placement_state == null) {
|
||||
return spit_out(facing);
|
||||
} else if(item instanceof ItemBlock) {
|
||||
ItemStack placement_stack = current_stack.copy();
|
||||
placement_stack.setCount(1);
|
||||
((ItemBlock)item).placeBlockAt(placement_stack, placer, world, placement_pos, EnumFacing.DOWN, 0.5f,0.5f,0f, placement_state);
|
||||
SoundType stype = block.getSoundType(placement_state, world, pos, null);
|
||||
if(stype != null) world.playSound(null, placement_pos, stype.getPlaceSound(), SoundCategory.BLOCKS, stype.getVolume()*0.6f, stype.getPitch());
|
||||
} else {
|
||||
if(world.setBlockState(placement_pos, placement_state, 1|2|8)) {
|
||||
SoundType stype = block.getSoundType(placement_state, world, pos, null);
|
||||
if(stype != null) world.playSound(null, placement_pos, stype.getPlaceSound(), SoundCategory.BLOCKS, stype.getVolume()*0.6f, stype.getPitch());
|
||||
}
|
||||
}
|
||||
current_stack.shrink(1);
|
||||
stacks_.set(current_slot_index_, current_stack);
|
||||
return true;
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update()
|
||||
{
|
||||
// Tick cycle pre-conditions
|
||||
if(world.isRemote) return;
|
||||
if(--tick_timer_ > 0) return;
|
||||
tick_timer_ = TICK_INTERVAL;
|
||||
// Cycle init
|
||||
boolean dirty = block_power_updated_;
|
||||
boolean rssignal = ((logic_ & LOGIC_INVERTED)!=0)==(!block_power_signal_);
|
||||
boolean trigger = (rssignal && ((block_power_updated_) || ((logic_ & LOGIC_CONTINUOUS)!=0)));
|
||||
final IBlockState state = world.getBlockState(pos);
|
||||
if(state == null) { block_power_signal_= false; return; }
|
||||
final EnumFacing placer_facing = state.getValue(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;
|
||||
}
|
||||
// Placing
|
||||
if(trigger && try_place(placer_facing)) dirty = true;
|
||||
if(dirty) markDirty();
|
||||
if(trigger && (tick_timer_ > TICK_INTERVAL)) tick_timer_ = TICK_INTERVAL;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -168,6 +168,11 @@ public class ModConfig
|
|||
@Config.RequiresMcRestart
|
||||
public boolean without_factory_hopper = false;
|
||||
|
||||
@Config.Comment({"Disable the Factory Block Placer."})
|
||||
@Config.Name("Without factory placer")
|
||||
@Config.RequiresMcRestart
|
||||
public boolean without_factory_placer = false;
|
||||
|
||||
@Config.Comment({"Disable horizontal half-block slab."})
|
||||
@Config.Name("Without slabs")
|
||||
@Config.RequiresMcRestart
|
||||
|
@ -411,6 +416,7 @@ public class ModConfig
|
|||
if(block instanceof BlockDecorWasteIncinerator) return optout.without_waste_incinerator;
|
||||
if(block instanceof BlockDecorDropper) return optout.without_factory_dropper;
|
||||
if(block instanceof BlockDecorHopper) return optout.without_factory_hopper;
|
||||
if(block instanceof BlockDecorPlacer) return optout.without_factory_placer;
|
||||
if(block instanceof BlockDecorHalfSlab) return optout.without_halfslabs;
|
||||
if(block instanceof BlockDecorLadder) return optout.without_ladders;
|
||||
if(block instanceof BlockDecorWindow) return optout.without_windows;
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"forge_marker": 1,
|
||||
"defaults": {
|
||||
"model": "engineersdecor:device/factory_placer_model"
|
||||
},
|
||||
"variants": {
|
||||
"normal": [{}],
|
||||
"inventory": [{}],
|
||||
"facing": { "north":{"y":0}, "south":{"y":180}, "west":{"y":270}, "east":{"y":90}, "up": {"x":-90}, "down": {"x":90} }
|
||||
}
|
||||
}
|
|
@ -159,7 +159,13 @@ tile.engineersdecor.factory_dropper.help=§6Dropper suitable for advanced factor
|
|||
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.
|
||||
tile.engineersdecor.factory_hopper.name=Factory Hopper
|
||||
tile.engineersdecor.factory_hopper.help=§6Hopper suitable for advanced factory automation.§r
|
||||
tile.engineersdecor.factory_hopper.help=§6Hopper suitable for advanced factory automation.§r Can transfer half-stacks, max collection range 9x9.\n\
|
||||
GUI Slider controls: Collection range (0 to 4), insertion delay (0.5s to 10s), insertion stack size (1 to 32).\n\
|
||||
GUI Redstone controls: Not inverted / inverted (default), pulse mode / continuous mode (default).
|
||||
tile.engineersdecor.factory_placer.name=Factory Block Placer
|
||||
tile.engineersdecor.factory_placer.help=§6Allows placing blocks and planting crops or trees.§r\n\
|
||||
GUI Redstone controls: Not inverted / inverted (default), pulse mode / continuous mode (default).\n\
|
||||
Also supports spike planing from underneath the soil. Spits out items that it cannot place or plant.
|
||||
tile.engineersdecor.small_mineral_smelter.name=Small Mineral Melting Furnace
|
||||
tile.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 \
|
||||
|
|
|
@ -155,7 +155,13 @@ tile.engineersdecor.factory_dropper.help=§6Выбрасыватель подх
|
|||
когда выполняются условия внутреннего запуска. Сбрасывает все соответствующие стеки одновременно. \
|
||||
Нажмите на все элементы в GUI, чтобы увидеть, как это работает.
|
||||
tile.engineersdecor.factory_hopper.name=Factory Hopper
|
||||
#tile.engineersdecor.factory_hopper.help=§6Hopper suitable for advanced factory automation.§r
|
||||
#tile.engineersdecor.factory_hopper.help=§6Hopper suitable for advanced factory automation.§r Can transfer half-stacks, max collection range 9x9.\n\
|
||||
GUI Slider controls: Collection range (0 to 4), insertion delay (0.5s to 10s), insertion stack size (1 to 32).\n\
|
||||
GUI Redstone controls: Not inverted / inverted (default), pulse mode / continuous mode (default).
|
||||
tile.engineersdecor.factory_placer.name=Factory Block Placer
|
||||
#tile.engineersdecor.factory_placer.help=§6Allows placing blocks and planting crops or trees.§r\n\
|
||||
GUI Redstone controls: Not inverted / inverted (default), pulse mode / continuous mode (default).\n\
|
||||
Also supports spike planing from underneath the soil. Spits out items that it cannot place or plant.
|
||||
tile.engineersdecor.small_mineral_smelter.name=Small Mineral Melting Furnace
|
||||
#tile.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 \
|
||||
|
|
|
@ -158,7 +158,13 @@ tile.engineersdecor.factory_dropper.help=§6适用于高级工厂自动化的掉
|
|||
当内部触发条件满足时,预先打开卷帘门。所有符合条件的物品\
|
||||
会同时掉落。点击GUI的各处来了解如何运作。
|
||||
tile.engineersdecor.factory_hopper.name=Factory Hopper
|
||||
#tile.engineersdecor.factory_hopper.help=§6Hopper suitable for advanced factory automation.§r
|
||||
#tile.engineersdecor.factory_hopper.help=§6Hopper suitable for advanced factory automation.§r Can transfer half-stacks, max collection range 9x9.\n\
|
||||
GUI Slider controls: Collection range (0 to 4), insertion delay (0.5s to 10s), insertion stack size (1 to 32).\n\
|
||||
GUI Redstone controls: Not inverted / inverted (default), pulse mode / continuous mode (default).
|
||||
tile.engineersdecor.factory_placer.name=Factory Block Placer
|
||||
#tile.engineersdecor.factory_placer.help=§6Allows placing blocks and planting crops or trees.§r\n\
|
||||
GUI Redstone controls: Not inverted / inverted (default), pulse mode / continuous mode (default).\n\
|
||||
Also supports spike planing from underneath the soil. Spits out items that it cannot place or plant.
|
||||
tile.engineersdecor.small_mineral_smelter.name=小型矿物熔炼炉
|
||||
tile.engineersdecor.small_mineral_smelter.help=§6高温、高绝缘电熔石炉。§r\n\
|
||||
把矿物块加热成岩浆块,最后变成熔岩。由于\
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
{
|
||||
"parent": "block/cube",
|
||||
"textures": {
|
||||
"top": "engineersdecor:blocks/device/factory_placer_top",
|
||||
"bottom": "engineersdecor:blocks/device/factory_placer_bottom",
|
||||
"side": "engineersdecor:blocks/device/factory_placer_side",
|
||||
"particle": "engineersdecor:blocks/device/factory_placer_side"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"from": [0, 0, 3],
|
||||
"to": [16, 16, 16],
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 16, 16], "texture": "#bottom"},
|
||||
"east": {"uv": [3, 0, 16, 16], "rotation": 180, "texture": "#side"},
|
||||
"south": {"uv": [0, 0, 16, 16], "texture": "#top"},
|
||||
"west": {"uv": [3, 0, 16, 16], "texture": "#side"},
|
||||
"up": {"uv": [3, 0, 16, 16], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [3, 0, 16, 16], "rotation": 270, "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [15, 0, 0],
|
||||
"to": [16, 16, 1],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 1, 16], "texture": "#bottom"},
|
||||
"east": {"uv": [15, 0, 16, 16], "texture": "#side"},
|
||||
"south": {"uv": [14, 0, 16, 16], "texture": "#top"},
|
||||
"west": {"uv": [0, 0, 1, 16], "texture": "#side"},
|
||||
"up": {"uv": [14, 0, 15, 1], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [14, 15, 16, 16], "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [15, 0, 2],
|
||||
"to": [16, 16, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 11]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 1, 16], "texture": "#bottom"},
|
||||
"east": {"uv": [2, 0, 3, 16], "rotation": 180, "texture": "#side"},
|
||||
"south": {"uv": [15, 0, 16, 16], "texture": "#top"},
|
||||
"west": {"uv": [2, 0, 4, 16], "texture": "#side"},
|
||||
"up": {"uv": [15, 2, 16, 4], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [15, 12, 16, 14], "rotation": 270, "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 0],
|
||||
"to": [1, 16, 1],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 7]},
|
||||
"faces": {
|
||||
"north": {"uv": [15, 0, 16, 16], "texture": "#bottom"},
|
||||
"east": {"uv": [15, 0, 16, 16], "texture": "#side"},
|
||||
"south": {"uv": [0, 0, 2, 16], "texture": "#top"},
|
||||
"west": {"uv": [0, 0, 1, 16], "texture": "#side"},
|
||||
"up": {"uv": [0, 0, 1, 1], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [0, 15, 2, 16], "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 2],
|
||||
"to": [1, 16, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 11]},
|
||||
"faces": {
|
||||
"north": {"uv": [15, 0, 16, 16], "texture": "#bottom"},
|
||||
"east": {"uv": [2, 0, 3, 16], "texture": "#side"},
|
||||
"south": {"uv": [0, 0, 1, 16], "texture": "#top"},
|
||||
"west": {"uv": [2, 0, 3, 16], "texture": "#side"},
|
||||
"up": {"uv": [0, 2, 1, 3], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [0, 13, 1, 14], "rotation": 270, "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 15, 1],
|
||||
"to": [1, 16, 2],
|
||||
"faces": {
|
||||
"north": {"uv": [15, 0, 16, 1], "texture": "#bottom"},
|
||||
"east": {"uv": [14, 0, 15, 1], "texture": "#side"},
|
||||
"south": {"uv": [0, 0, 1, 1], "texture": "#top"},
|
||||
"west": {"uv": [1, 0, 2, 1], "texture": "#side"},
|
||||
"up": {"uv": [1, 0, 2, 1], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [0, 14, 1, 15], "rotation": 270, "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [15, 15, 1],
|
||||
"to": [16, 16, 2],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [23, 8, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 0, 1, 1], "texture": "#bottom"},
|
||||
"east": {"uv": [14, 0, 15, 1], "texture": "#side"},
|
||||
"south": {"uv": [15, 0, 16, 1], "texture": "#top"},
|
||||
"west": {"uv": [1, 0, 2, 1], "texture": "#side"},
|
||||
"up": {"uv": [15, 1, 16, 2], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [15, 14, 16, 15], "rotation": 270, "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [15, 0, 1],
|
||||
"to": [16, 1, 2],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [23, -7, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [0, 15, 1, 16], "texture": "#bottom"},
|
||||
"east": {"uv": [14, 15, 15, 16], "texture": "#side"},
|
||||
"south": {"uv": [15, 15, 16, 16], "texture": "#top"},
|
||||
"west": {"uv": [1, 15, 2, 16], "texture": "#side"},
|
||||
"up": {"uv": [15, 1, 16, 2], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [15, 14, 16, 15], "rotation": 270, "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [0, 0, 1],
|
||||
"to": [1, 1, 2],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -7, 8]},
|
||||
"faces": {
|
||||
"north": {"uv": [15, 15, 16, 16], "texture": "#bottom"},
|
||||
"east": {"uv": [14, 15, 15, 16], "texture": "#side"},
|
||||
"south": {"uv": [0, 15, 1, 16], "texture": "#top"},
|
||||
"west": {"uv": [1, 15, 2, 16], "texture": "#side"},
|
||||
"up": {"uv": [0, 1, 1, 2], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [0, 14, 1, 15], "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 15, 2],
|
||||
"to": [15, 16, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 11]},
|
||||
"faces": {
|
||||
"north": {"uv": [1, 0, 15, 1], "texture": "#bottom"},
|
||||
"east": {"uv": [12, 0, 14, 1], "texture": "#side"},
|
||||
"south": {"uv": [1, 0, 15, 1], "texture": "#top"},
|
||||
"west": {"uv": [2, 0, 4, 1], "texture": "#side"},
|
||||
"up": {"uv": [2, 1, 3, 15], "rotation": 90, "texture": "#side"},
|
||||
"down": {"uv": [2, 1, 3, 15], "rotation": 270, "texture": "#side"}
|
||||
}
|
||||
},
|
||||
{
|
||||
"from": [1, 0, 2],
|
||||
"to": [15, 1, 3],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 11]},
|
||||
"faces": {
|
||||
"north": {"uv": [1, 15, 15, 16], "texture": "#bottom"},
|
||||
"east": {"uv": [12, 15, 14, 16], "texture": "#side"},
|
||||
"south": {"uv": [1, 15, 15, 16], "texture": "#top"},
|
||||
"west": {"uv": [2, 15, 4, 16], "texture": "#side"},
|
||||
"up": {"uv": [2, 1, 3, 15], "rotation": 180, "texture": "#side"},
|
||||
"down": {"uv": [2, 1, 3, 15], "rotation": 270, "texture": "#side"}
|
||||
}
|
||||
}
|
||||
],
|
||||
"display": {
|
||||
"thirdperson_righthand": {
|
||||
"rotation": [85, 3, -10],
|
||||
"translation": [1.75, -0.75, -2.25],
|
||||
"scale": [0.35, 0.35, 0.35]
|
||||
},
|
||||
"ground": {
|
||||
"translation": [0, -0.75, 0],
|
||||
"scale": [0.2, 0.2, 0.2]
|
||||
},
|
||||
"gui": {
|
||||
"rotation": [30, 225, 0],
|
||||
"scale": [0.625, 0.625, 0.625]
|
||||
},
|
||||
"fixed": {
|
||||
"scale": [0.5, 0.5, 0.5]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"type": "engineersdecor:grc",
|
||||
"result": "engineersdecor:factory_placer",
|
||||
"missing": ["immersiveengineering:material"]
|
||||
}
|
||||
],
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"WWW",
|
||||
"WDP",
|
||||
"WWW"
|
||||
],
|
||||
"key": {
|
||||
"D": {
|
||||
"item": "minecraft:dispenser",
|
||||
"data": 0
|
||||
},
|
||||
"P": {
|
||||
"item": "#ingotIron",
|
||||
"data": 0
|
||||
},
|
||||
"W": {
|
||||
"item": "#plankWood",
|
||||
"data": 0
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "engineersdecor:factory_placer",
|
||||
"count": 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"conditions": [
|
||||
{
|
||||
"type": "engineersdecor:grc",
|
||||
"result": "engineersdecor:factory_placer",
|
||||
"required": ["immersiveengineering:material"]
|
||||
}
|
||||
],
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"WWW",
|
||||
"WDP",
|
||||
"WWW"
|
||||
],
|
||||
"key": {
|
||||
"D": {
|
||||
"item": "minecraft:dispenser",
|
||||
"data": 0
|
||||
},
|
||||
"P": {
|
||||
"item": "#plateIron",
|
||||
"data": 0
|
||||
},
|
||||
"W": {
|
||||
"item": "#plankTreatedWood",
|
||||
"data": 0
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "engineersdecor:factory_placer",
|
||||
"count": 1
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 478 B |
Binary file not shown.
After Width: | Height: | Size: 652 B |
Binary file not shown.
After Width: | Height: | Size: 527 B |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Loading…
Add table
Add a link
Reference in a new issue