Gas concrete added (1.12), RF-required config options added (issue #63). Clinker recipe yield increased. Item-on-ground item display fixed (issue #61). Sign bounding box orientations fixed (issue #62).

This commit is contained in:
stfwi 2019-11-13 18:09:53 +01:00
parent 8cfa64170f
commit 1938f34faf
32 changed files with 1525 additions and 99 deletions

View file

@ -1,6 +1,7 @@
{
"homepage": "https://www.curseforge.com/minecraft/mc-mods/engineers-decor/",
"1.12.2": {
"1.0.16-b2": "[A] Added Gas Concrete (including slab, wall, stairs, and slab slice).\n[A] Added explicit RF-power-required option for Small Block Breaker and Small Tree Cutter (issue #63).\n[M] Increased clinker brick recipe yield to 8 for the master builders needs.\n[F] Fixed item-on-ground display glitch (issue #61, thx Federsavo for the hint).\n[F] Fixed sign bounding boxes (issue #62, thx angela/themartin).",
"1.0.16-b1": "[A] Added Fluid Collection Funnel.\n[A] Added config opt-outs for Breaker, Placer, Fluid Funnel, Mineral Smelter.\n[A] Added configs tweaks for Small Block Breaker and Small Tree Cutter (cffr#185).\n[F] Fixed Block Placer discarding item metadata/variants while placing (issue #60).\n[F] Fixed Block Breaker duping empty shulker boxes, model updated.",
"1.0.15": "[R] Release based on v1.0.15-b2. Release-to-release changes: * Added Small Block Breaker * Small Tree Cutter fixes and compatability improved. * Crafting table compat fixes.\n[M] Small Tree Cutter log detection bug fixed (issue #59).\n[M] Small Tree Cutter supports Menril chopping (issue #54).",
"1.0.15-b2": "[A] Added Small Block Breaker\n[M] Crafting Table: Allowing NBT \"Damage\" mismatch only items that are declared damagable (issue #56).\n[M] Tree Cutter: Loosened the strict mod namespace requirement for Dynamic Trees log detection (issue #52) to enable checking DT compat mod log blocks.",
@ -67,6 +68,6 @@
},
"promos": {
"1.12.2-recommended": "1.0.15",
"1.12.2-latest": "1.0.16-b1"
"1.12.2-latest": "1.0.16-b2"
}
}

View file

@ -10,8 +10,11 @@ Mod sources for Minecraft version 1.12.2.
----
## Version history
~ v1.0.16-b2 [A] Added Gas Concrete (including slab, wall, stairs, and slab slice).
- v1.0.16-b2 [A] Added Gas Concrete (including slab, wall, stairs, and slab slice).
[A] Added explicit RF-power-required option for Small Block Breaker and Small Tree Cutter (issue #63).
[M] Increased clinker brick recipe yield to 8 for the master builders needs.
[F] Fixed item-on-ground display glitch (issue #61, thx Federsavo for the hint).
[F] Fixed sign bounding boxes (issue #62, thx angela/themartin).
- v1.0.16-b1 [A] Added Fluid Collection Funnel.
[A] Added config opt-outs for Breaker, Placer, Fluid Funnel, Mineral Smelter.

View file

@ -143,6 +143,13 @@ public class ModContent
ModAuxiliaries.getPixeledAABB(1.1,0,1.1, 14.9,16,14.9)
);
public static final BlockDecorMilker SMALL_MILKING_MACHINE = new BlockDecorMilker(
"small_milking_machine",
BlockDecor.CFG_LOOK_PLACEMENT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_CUTOUT|BlockDecor.CFG_ELECTRICAL,
Material.IRON, 1f, 15f, SoundType.METAL,
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,13)
);
public static final BlockDecorSolarPanel SMALL_SOLAR_PANEL = new BlockDecorSolarPanel(
"small_solar_panel",
BlockDecor.CFG_LOOK_PLACEMENT,
@ -355,51 +362,51 @@ public class ModContent
public static final BlockDecorDirected SIGN_MODLOGO = new BlockDecorDirected(
"sign_decor",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
Material.WOOD, 0.1f, 1000f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(0,0,15.6, 16,16,16)
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,0.5)
);
public static final BlockDecorDirected SIGN_HOTWIRE = new BlockDecorDirected(
"sign_hotwire",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
Material.WOOD, 0.1f, 1f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
ModAuxiliaries.getPixeledAABB(2,2,0, 14,14,0.5)
);
public static final BlockDecorDirected SIGN_MINDSTEP = new BlockDecorDirected(
"sign_mindstep",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
Material.WOOD, 0.1f, 1f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,0.5)
);
public static final BlockDecorDirected SIGN_DANGER = new BlockDecorDirected(
"sign_danger",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
Material.WOOD, 0.1f, 1f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
ModAuxiliaries.getPixeledAABB(2,2,0, 14,14,0.5)
);
public static final BlockDecorDirected SIGN_DEFENSE = new BlockDecorDirected(
"sign_defense",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_OPPOSITE_PLACEMENT|(1<<BlockDecor.CFG_LIGHT_VALUE_SHIFT),
Material.WOOD, 0.1f, 1f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(2,2,15.6, 14,14,16)
ModAuxiliaries.getPixeledAABB(0,0,0, 16,16,0.5)
);
public static final BlockDecorDirected SIGN_FACTORY_AREA = new BlockDecorDirected(
"sign_factoryarea",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Material.WOOD, 0.1f, 1f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(2,2,15.6, 15,15,16)
ModAuxiliaries.getPixeledAABB(1,1,0, 15,15,0.5)
);
public static final BlockDecorDirected SIGN_EXIT = new BlockDecorDirected(
"sign_exit",
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_OPPOSITE_PLACEMENT,
BlockDecor.CFG_CUTOUT|BlockDecor.CFG_HORIZIONTAL|BlockDecor.CFG_OPPOSITE_PLACEMENT,
Material.WOOD, 0.1f, 1f, SoundType.WOOD,
ModAuxiliaries.getPixeledAABB(3,7,15.6, 13,13,16)
ModAuxiliaries.getPixeledAABB(3,7,0, 13,13,0.5)
);
//--------------------------------------------------------------------------------------------------------------------
@ -503,6 +510,9 @@ public class ModContent
private static final TileEntityRegistrationData SMALL_MINERAL_SMELTER_TEI = new TileEntityRegistrationData(
BlockDecorMineralSmelter.BTileEntity.class, "te_small_mineral_smelter"
);
private static final TileEntityRegistrationData SMALL_MILKING_MACHINE_TEI = new TileEntityRegistrationData(
BlockDecorMilker.BTileEntity.class, "te_small_milking_machine"
);
private static final TileEntityRegistrationData SMALL_SOLAR_PANEL_TEI = new TileEntityRegistrationData(
BlockDecorSolarPanel.BTileEntity.class, "te_small_solar_panel"
);
@ -593,6 +603,7 @@ 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,
SMALL_MILKING_MACHINE,SMALL_MILKING_MACHINE_TEI
};
//--------------------------------------------------------------------------------------------------------------------

View file

@ -0,0 +1,544 @@
/*
* @file BlockDecorMilker.java
* @author Stefan Wilhelm (wile)
* @copyright (C) 2019 Stefan Wilhelm
* @license MIT (see https://opensource.org/licenses/MIT)
*
* Frequently attracts and milks nearby cows
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.BlockChest;
import net.minecraft.inventory.IInventory;
import net.minecraft.tileentity.TileEntityChest;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.init.SoundEvents;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.Explosion;
import net.minecraft.entity.MoverType;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.init.Items;
import net.minecraft.item.*;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.*;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.energy.CapabilityEnergy;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.wrapper.PlayerMainInvWrapper;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.fluids.capability.IFluidTankProperties;
import wile.engineersdecor.detail.ExtItems;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.UUID;
public class BlockDecorMilker extends BlockDecorDirectedHorizontal
{
public static final PropertyBool FILLED = PropertyBool.create("filled");
public static final PropertyBool ACTIVE = PropertyBool.create("active");
public BlockDecorMilker(@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);
setLightOpacity(0);
}
@Override
protected BlockStateContainer createBlockState()
{ return new BlockStateContainer(this, FACING, FILLED, ACTIVE); }
@Override
public IBlockState getStateFromMeta(int meta)
{ return super.getStateFromMeta(meta).withProperty(FILLED, ((meta & 0x4)!=0)).withProperty(ACTIVE, ((meta & 0x8)!=0)) ; }
@Override
public int getMetaFromState(IBlockState state)
{ return super.getMetaFromState(state) | (state.getValue(FILLED)?0x4:0x00) | (state.getValue(ACTIVE)?0x8:0x00); }
@Override
public IBlockState getStateForPlacement(World world, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer, EnumHand hand)
{ return super.getStateForPlacement(world, pos, facing, hitX, hitY, hitZ, meta, placer, hand).withProperty(FILLED, false).withProperty(ACTIVE, false); }
@Override
public BlockFaceShape getBlockFaceShape(IBlockAccess world, IBlockState state, BlockPos pos, EnumFacing face)
{ return BlockFaceShape.UNDEFINED; }
@Override
public boolean isPassable(IBlockAccess worldIn, BlockPos pos)
{ return false; }
@Override
@SuppressWarnings("deprecation")
public boolean hasComparatorInputOverride(IBlockState state)
{ return true; }
@Override
@SuppressWarnings("deprecation")
public int getComparatorInputOverride(IBlockState state, World world, BlockPos pos)
{
BTileEntity te = getTe(world, pos);
return (te==null) ? 0 : MathHelper.clamp((16 * te.fluid_level())/BTileEntity.TANK_CAPACITY, 0, 15);
}
@Override
public boolean hasTileEntity(IBlockState state)
{ return true; }
@Nullable
public TileEntity createTileEntity(World world, IBlockState state)
{ return new BlockDecorMilker.BTileEntity(); }
@Override
public boolean removedByPlayer(IBlockState state, World world, BlockPos pos, EntityPlayer player, boolean willHarvest)
{
if(world.isRemote) return true;
BTileEntity te = getTe(world, pos);
if(te==null) return super.removedByPlayer(state, world, pos, player, willHarvest);
final NBTTagCompound te_nbt = te.destroy_getnbt();
ItemStack stack = new ItemStack(this, 1);
if((te_nbt!=null) && !te_nbt.isEmpty()) {
NBTTagCompound nbt = stack.getTagCompound();
if(nbt == null) 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)
{ super.onBlockExploded(world, pos, explosion); } // currently nothing to do here
@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;
BTileEntity te = getTe(world, pos);
if(te==null) return true;
final ItemStack in_stack = player.getHeldItem(hand);
final ItemStack out_stack = te.milk_filled_container_item(in_stack);
if(out_stack.isEmpty()) return FluidUtil.interactWithFluidHandler(player, hand, te.fluid_handler());
boolean drained = false;
IItemHandler player_inventory = new PlayerMainInvWrapper(player.inventory);
if(te.fluid_level() >= 1000) {
final ItemStack insert_stack = out_stack.copy();
ItemStack remainder = ItemHandlerHelper.insertItemStacked(player_inventory, insert_stack, false);
if(remainder.getCount() < insert_stack.getCount()) {
te.drain(1000);
in_stack.shrink(1);
drained = true;
if(remainder.getCount() > 0) {
final EntityItem ei = new EntityItem(world, player.posX, player.posY + 0.5, player.posZ, remainder);
ei.setPickupDelay(40);
ei.motionX = 0;
ei.motionZ = 0;
world.spawnEntity(ei);
}
}
}
if(drained) {
world.playSound(null, pos, SoundEvents.ITEM_BUCKET_FILL, SoundCategory.BLOCKS, 0.8f, 1f);
}
return true;
}
@Nullable
private BTileEntity getTe(World world, BlockPos pos)
{ final TileEntity te=world.getTileEntity(pos); return (!(te instanceof BTileEntity)) ? (null) : ((BTileEntity)te); }
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BTileEntity extends TileEntity implements ITickable, ICapabilityProvider, IEnergyStorage
{
public static final int TICK_INTERVAL = 80;
public static final int PROCESSING_TICK_INTERVAL = 10;
public static final int TANK_CAPACITY = 12000;
public static final int MAX_MILKING_TANK_LEVEL = TANK_CAPACITY-500;
public static final int MAX_ENERGY_BUFFER = 16000;
public static final int MAX_ENERGY_TRANSFER = 512;
public static final int DEFAULT_ENERGY_CONSUMPTION = 16;
private static final EnumFacing FLUID_TRANSFER_DIRECTRIONS[] = {EnumFacing.DOWN,EnumFacing.EAST,EnumFacing.SOUTH,EnumFacing.WEST,EnumFacing.NORTH};
private static final ItemStack BUCKET_STACK = new ItemStack(Items.BUCKET);
private enum MilkingState { IDLE, PICKED, COMING, POSITIONING, MILKING, LEAVING, WAITING }
private static FluidStack milk_fluid_ = new FluidStack(FluidRegistry.WATER, 0);
private static int energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
private int tick_timer_;
private int energy_stored_;
private int tank_level_ = 0;
private UUID tracked_cow_ = null;
private MilkingState state_ = MilkingState.IDLE;
private int state_timeout_ = 0;
private int state_timer_ = 0;
private BlockPos tracked_cow_original_position_ = null;
public static void on_config(int energy_consumption_per_tick, int heatup_per_second)
{
energy_consumption = MathHelper.clamp(energy_consumption_per_tick, 0, 4096);
ModEngineersDecor.logger.info("Config milker energy consumption:" + energy_consumption + "rf/t");
}
public BTileEntity()
{ reset(); }
public void reset()
{
tank_level_ = 0;
energy_stored_ = 0;
tick_timer_ = 0;
tracked_cow_ = null;
state_ = MilkingState.IDLE;
state_timeout_ = 0;
}
public NBTTagCompound destroy_getnbt()
{
final UUID cowuid = tracked_cow_;
NBTTagCompound nbt = new NBTTagCompound();
writenbt(nbt, false); reset();
if(cowuid == null) return nbt;
world.getEntitiesWithinAABB(EntityCow.class, new AxisAlignedBB(pos).grow(16, 16, 16), e->e.getPersistentID().equals(cowuid)).forEach(e->e.setNoAI(false));
return nbt;
}
public void readnbt(NBTTagCompound nbt, boolean update_packet)
{
tank_level_ = nbt.getInteger("tank");
energy_stored_ = nbt.getInteger("energy");
}
protected void writenbt(NBTTagCompound nbt, boolean update_packet)
{
if(tank_level_ > 0) nbt.setInteger("tank", tank_level_);
if(energy_stored_ > 0) nbt.setInteger("energy", energy_stored_ );
}
private IFluidHandler fluid_handler()
{ return fluid_handler_; }
private int fluid_level()
{ return MathHelper.clamp(tank_level_, 0, TANK_CAPACITY); }
private void drain(int amount)
{ tank_level_ = MathHelper.clamp(tank_level_-1000, 0, TANK_CAPACITY); markDirty(); }
// TileEntity ------------------------------------------------------------------------------
@Override
public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns)
{ return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorMilker)); }
@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; }
// IEnergyStorage ----------------------------------------------------------------------------
@Override
public boolean canExtract()
{ return false; }
@Override
public boolean canReceive()
{ return true; }
@Override
public int getMaxEnergyStored()
{ return MAX_ENERGY_BUFFER; }
@Override
public int getEnergyStored()
{ return energy_stored_; }
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
if(energy_stored_ >= MAX_ENERGY_BUFFER) return 0;
int n = Math.min(maxReceive, (MAX_ENERGY_BUFFER - energy_stored_));
if(n > MAX_ENERGY_TRANSFER) n = MAX_ENERGY_TRANSFER;
if(!simulate) {energy_stored_ += n; markDirty(); }
return n;
}
// IFluidHandler / IFluidTankProperties ---------------------------------------------------------------------
private static class BFluidHandler implements IFluidHandler, IFluidTankProperties
{
private final BTileEntity te;
private final IFluidTankProperties[] props_ = {this};
BFluidHandler(BTileEntity te) { this.te=te; }
@Override @Nullable public FluidStack getContents() { return new FluidStack(milk_fluid_, te.fluid_level()); }
@Override public IFluidTankProperties[] getTankProperties() { return props_; }
@Override public int fill(FluidStack resource, boolean doFill) { return 0; }
@Override public int getCapacity() { return TANK_CAPACITY; }
@Override public boolean canFill() { return false; }
@Override public boolean canDrain() { return (milk_fluid_.amount > 0); }
@Override public boolean canFillFluidType(FluidStack fs) { return false; }
@Override public boolean canDrainFluidType(FluidStack fs) { return fs.isFluidEqual(milk_fluid_); }
@Override @Nullable public FluidStack drain(FluidStack resource, boolean doDrain)
{ return (!resource.isFluidEqual(milk_fluid_)) ? (null) : drain(resource.amount, doDrain); }
@Override @Nullable public FluidStack drain(int maxDrain, boolean doDrain)
{
if(te.fluid_level() <= 0) return null;
FluidStack fs = milk_fluid_.copy();
fs.amount = Math.min(fs.amount, te.fluid_level());
if(doDrain) te.tank_level_ -= fs.amount;
return fs;
}
}
private final BFluidHandler fluid_handler_ = new BFluidHandler(this);
// ICapabilityProvider ---------------------------------------------------------------------------
@Override
public boolean hasCapability(Capability<?> cap, EnumFacing facing)
{
if((cap==CapabilityEnergy.ENERGY) && (energy_consumption>0)) return true;
if((cap==CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) && (milk_fluid_.amount>0)) return true;
return super.hasCapability(cap, facing);
}
@Override
@SuppressWarnings("unchecked")
@Nullable
public <T> T getCapability(Capability<T> capability, @Nullable EnumFacing facing)
{
if(capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) {
return (T)fluid_handler_;
} else if(capability == CapabilityEnergy.ENERGY) {
return (T)this;
} else {
return super.getCapability(capability, facing);
}
}
// ITickable ------------------------------------------------------------------------------------
private void log(String s)
{} // may be enabled with config
private ItemStack milk_filled_container_item(ItemStack stack)
{
// Returns out stack for input stack size == 1 (convert one item of the stack).
if(stack.isItemEqualIgnoreDurability(BTileEntity.BUCKET_STACK)) return new ItemStack(Items.MILK_BUCKET);
if((ExtItems.BOTTLED_MILK_BOTTLE_DRINKLABLE!=null) && stack.getItem().equals(Items.GLASS_BOTTLE)) return new ItemStack(ExtItems.BOTTLED_MILK_BOTTLE_DRINKLABLE);
return ItemStack.EMPTY;
}
private void fill_adjacent_inventory_item_containers(EnumFacing block_facing)
{
// Check inventory existence, back to down if possible, otherwise sort back into same inventory.
IInventory src, dst;
{
TileEntity te_src = world.getTileEntity(pos.offset(block_facing));
TileEntity te_dst = world.getTileEntity(pos.down());
if(!(te_src instanceof IInventory)) te_src = null;
if(!(te_dst instanceof IInventory)) te_dst = null;
if((te_src==null)) te_src = te_dst;
if((te_dst==null)) te_dst = te_src;
if((te_src==null) || (te_dst==null)) return;
src = (IInventory)te_src;
dst = (IInventory)te_dst;
}
/// @todo --> hier weitermachen
}
private boolean milking_process()
{
if((tracked_cow_ == null) && (fluid_level() >= MAX_MILKING_TANK_LEVEL)) return false; // nothing to do
EntityCow cow = null;
{
final List<EntityCow> cows = world.getEntitiesWithinAABB(EntityCow.class, new AxisAlignedBB(pos).grow(16, 3, 16),
e->(((tracked_cow_==null) && (!e.isChild() && !e.isInLove()))||(e.getPersistentID().equals(tracked_cow_)))
);
if(cows.size() == 1) {
cow = cows.get(0); // tracked or only one
} else if(cows.size() > 1) {
cow = cows.get(world.rand.nextInt(cows.size()-1)); // pick one
}
}
if((state_ != MilkingState.IDLE) && ((state_timeout_ -= PROCESSING_TICK_INTERVAL) <= 0)) { log("Cow motion timeout"); cow = null; }
if((cow == null) || (cow.isDead) || ((tracked_cow_ != null) && (!tracked_cow_.equals(cow.getPersistentID())))) { tracked_cow_ = null; cow = null; }
if(tracked_cow_ == null) state_ = MilkingState.IDLE;
if(cow == null) return false; // retry next cycle
final EnumFacing facing = world.getBlockState(getPos()).getValue(FACING).getOpposite();
tick_timer_ = PROCESSING_TICK_INTERVAL;
state_timer_ -= PROCESSING_TICK_INTERVAL;
if(state_timer_ > 0) return false;
switch(state_) {
case IDLE: {
final List<EntityLivingBase> blocking_entities = world.getEntitiesWithinAABB(EntityLivingBase.class, new AxisAlignedBB(pos).grow(1, 2, 1));
if(blocking_entities.size() > 0) return false; // an entity is blocking the way
if(cow.getLeashed() || cow.isChild() || cow.isInLove() || (!cow.onGround) || cow.isBeingRidden() || cow.isSprinting()) return false;
tracked_cow_ = cow.getPersistentID();
state_ = MilkingState.PICKED;
state_timeout_ = 200;
tracked_cow_original_position_ = cow.getPosition();
log("Idle: Picked cow" + tracked_cow_);
return true;
}
case PICKED: {
if(cow.hasPath()) return true;
BlockPos p = getPos().offset(facing).offset(facing.rotateY());
if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(),1.0)) {
log("Picked: No path");
tracked_cow_ = null;
return false;
}
state_ = MilkingState.COMING;
state_timeout_ = 300; // 15s should be enough
log("Picked: coming");
return true;
}
case COMING: {
BlockPos p = getPos().offset(facing).offset(facing.rotateY());
if(cow.getPosition().distanceSq(p) > 1) {
if(cow.hasPath()) return true;
if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(),1.0)) {
log("Coming: lost path");
tracked_cow_ = null;
return false;
} else {
state_timeout_ -= 100;
}
} else {
BlockPos next_p = getPos().offset(facing);
if(!cow.getNavigator().tryMoveToXYZ(next_p.getX(), next_p.getY(), next_p.getZ(), 1.0)) {
log("Coming: No path");
tracked_cow_ = null;
return false;
}
log("Coming: position reached");
state_ = MilkingState.POSITIONING;
state_timeout_ = 100; // 5s
}
return true;
}
case POSITIONING: {
BlockPos p = getPos().offset(facing);
if(cow.getPosition().distanceSq(p) > 0) {
if(cow.hasPath()) return true;
if(!cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(), 1.0)) {
log("Positioning: lost path");
} else {
state_timeout_ -= 200;
}
tracked_cow_ = null;
return false;
}
cow.setNoAI(true);
cow.move(MoverType.SELF, p.getX()+0.5-cow.posX, 0,p.getZ()+0.5-cow.posZ);
world.playSound(null, pos, SoundEvents.ENTITY_COW_MILK, SoundCategory.BLOCKS, 0.5f, 1f);
state_timeout_ = 600;
state_ = MilkingState.MILKING;
state_timer_ = 30;
log("Positioning: start milking");
return true;
}
case MILKING: {
tank_level_ = MathHelper.clamp(tank_level_+1000, 0, TANK_CAPACITY);
state_timeout_ = 600;
state_ = MilkingState.LEAVING;
state_timer_ = 20;
BlockPos p = (tracked_cow_original_position_ != null) ? (tracked_cow_original_position_) : getPos().offset(facing.rotateYCCW(),2);
cow.setNoAI(false);
cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(), 1.0);
log("Milking: done, leave");
return true;
}
case LEAVING: {
BlockPos p = (tracked_cow_original_position_ != null) ? (tracked_cow_original_position_) : getPos().offset(facing.rotateYCCW(),2);
cow.getNavigator().tryMoveToXYZ(p.getX(), p.getY(), p.getZ(), 1.0);
state_timeout_ = 600;
state_timer_ = 500;
state_ = MilkingState.WAITING;
log("Leaving: process done");
return true;
}
case WAITING: {
return true; // wait for the timeout to kick in until starting with the next.
}
default:
tracked_cow_ = null;
}
return (tracked_cow_ != null);
}
@Override
public void update()
{
if((world.isRemote) || ((--tick_timer_ > 0))) return;
tick_timer_ = TICK_INTERVAL;
final IBlockState block_state = world.getBlockState(pos);
boolean dirty = false;
// Track and milk cows
if(milking_process()) dirty = true;
// Fluid transfer
if((milk_fluid_.amount > 0) && (fluid_level() >= 1000)) {
for(EnumFacing facing: FLUID_TRANSFER_DIRECTRIONS) {
IFluidHandler fh = FluidUtil.getFluidHandler(world, pos.offset(facing), facing.getOpposite());
if(fh == null) continue;
FluidStack fs = milk_fluid_.copy();
fs.amount = 1000;
int nfilled = MathHelper.clamp(fh.fill(fs, true), 0, 1000);
if(nfilled <= 0) continue;
tank_level_ -= nfilled;
if(tank_level_ < 0) tank_level_ = 0;
dirty = true;
break;
}
}
// Adjacent inventory update, only done just after milking to prevent waste of server cpu.
if(dirty && (fluid_level() >= 1000)) {
fill_adjacent_inventory_item_containers(block_state.getValue(FACING));
}
// State update
IBlockState new_state = block_state.withProperty(FILLED, fluid_level()>0).withProperty(ACTIVE, state_==MilkingState.MILKING);
if(block_state != new_state) world.setBlockState(pos, new_state,1|2|16);
if(dirty) markDirty();
}
}
}

View file

@ -9,9 +9,8 @@
*/
package wile.engineersdecor.blocks;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.world.IBlockAccess;
import wile.engineersdecor.ModEngineersDecor;
import net.minecraft.block.state.BlockFaceShape;
import net.minecraft.block.properties.PropertyInteger;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.Block;
@ -19,6 +18,7 @@ import net.minecraft.block.SoundType;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.world.World;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.Explosion;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.EntityLivingBase;

View file

@ -8,20 +8,25 @@
*/
package wile.engineersdecor.blocks;
import wile.engineersdecor.detail.ModAuxiliaries;
import net.minecraft.world.World;
import net.minecraft.block.state.IBlockState;
import net.minecraft.block.material.Material;
import net.minecraft.block.SoundType;
import net.minecraft.entity.passive.EntityCow;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ITickable;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.block.material.Material;
import net.minecraft.block.SoundType;
import net.minecraft.util.math.AxisAlignedBB;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.UUID;
public class BlockDecorTest extends BlockDecorDirected implements ModAuxiliaries.IExperimentalFeature
@ -54,9 +59,8 @@ public class BlockDecorTest extends BlockDecorDirected implements ModAuxiliaries
public static class BTileEntity extends TileEntity implements ITickable
{
public static double increment = 0.008;
private double progress_ = 0;
private double incr_ = increment;
private static int tick_interval_ = 40;
private int tick_timer_ = 0;
public BTileEntity()
{}
@ -65,29 +69,45 @@ public class BlockDecorTest extends BlockDecorDirected implements ModAuxiliaries
public boolean shouldRefresh(World world, BlockPos pos, IBlockState os, IBlockState ns)
{ return (os.getBlock() != ns.getBlock()) || (!(ns.getBlock() instanceof BlockDecorTest)); }
//------------------------------------------------------------------------------------------------------------------
public static double increment = 0.008;
private boolean TESR_TEST = false;
private double progress_ = -1;
private double incr_ = increment;
public double progress() { return progress_; }
private void tesr_basic_test(boolean reset)
{
if(!TESR_TEST || !world.isRemote) return;
if(reset) {
progress_ = 0; incr_ = increment;
} else {
progress_ += incr_;
if(progress_ < 0) {
incr_ = increment;
progress_ = 0;
} else if(progress_ > 1.0) {
progress_ = 1.0;
incr_ = -increment;
}
}
}
public double progress()
{ return progress_; }
//------------------------------------------------------------------------------------------------------------------
public boolean clicked(EntityPlayer player, boolean lclicked)
{
progress_ = 0;
incr_ = increment;
tesr_basic_test(true);
return true;
}
@Override
public void update()
{
progress_ += incr_;
if(progress_ < 0) {
incr_ = increment;
progress_ = 0;
} else if(progress_ > 1.0) {
progress_ = 1.0;
incr_ = -increment;
}
tesr_basic_test(false);
if(++tick_timer_ < tick_interval_) return;
tick_timer_ = tick_interval_;
}
}
}

View file

@ -16,6 +16,9 @@ public class ExtItems
@GameRegistry.ObjectHolder("immersiveengineering:metal_device1")
public static final Item IE_EXTERNAL_HEATER = null;
@GameRegistry.ObjectHolder("bottledmilk:milk_bottle_drinkable")
public static final Item BOTTLED_MILK_BOTTLE_DRINKLABLE = null;
public static final void onPostInit()
{}
}

View file

@ -48,10 +48,27 @@ public class ModAuxiliaries
final String ft = tr.getFormattedText();
if(ft.contains("${")) {
// Non-recursive, non-argument lang file entry cross referencing.
Pattern pt = Pattern.compile("\\$\\{([\\w\\.]+)\\}");
Pattern pt = Pattern.compile("\\$\\{([^}]+)\\}");
Matcher mt = pt.matcher(ft);
StringBuffer sb = new StringBuffer();
while(mt.find()) mt.appendReplacement(sb, (new TextComponentTranslation(mt.group(1))).getFormattedText().trim());
while(mt.find()) {
String m = mt.group(1);
if(m.contains("?")) {
String[] kv = m.split("\\?", 2);
String key = kv[0].trim();
boolean not = key.startsWith("!");
if(not) key = key.replaceFirst("!", "");
m = kv[1].trim();
if(!ModConfig.getServerConfig().hasKey(key)) {
m = "";
} else {
boolean r = ModConfig.getServerConfig().getBoolean(key);
if(not) r = !r;
if(!r) m = "";
}
}
mt.appendReplacement(sb, (new TextComponentTranslation(m)).getFormattedText().trim());
}
mt.appendTail(sb);
return sb.toString();
} else {

View file

@ -12,10 +12,11 @@ package wile.engineersdecor.detail;
import wile.engineersdecor.ModContent;
import wile.engineersdecor.ModEngineersDecor;
import wile.engineersdecor.blocks.*;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
@ -211,6 +212,11 @@ public class ModConfig
@Config.RequiresMcRestart
public boolean without_mineral_smelter = false;
@Config.Comment({"Disable the Small Mikling Machine."})
@Config.Name("Without milking machine")
@Config.RequiresMcRestart
public boolean without_milker = false;
@Config.Comment({"Disable directly picking up layers from slabs and slab slices by left clicking while looking up/down."})
@Config.Name("Without slab pickup")
public boolean without_direct_slab_pickup = false;
@ -400,6 +406,12 @@ public class ModConfig
@Config.RangeInt(min=10, max=100)
public int block_breaker_min_breaking_time = BlockDecorBreaker.BTileEntity.DEFAULT_MIN_BREAKING_TIME;
@Config.Comment({
"Defines if the Small Block Breaker does not work without RF power."
})
@Config.Name("Block Breaker: Power required")
public boolean block_breaker_requires_power = false;
@Config.Comment({
"Defines how much RF power the Small Tree Cutter requires to magnificently increase the processing speed. " +
"The config value can be changed on-the-fly for tuning."
@ -416,6 +428,12 @@ public class ModConfig
@Config.Name("Tree Cutter: Cutting time")
@Config.RangeInt(min=10, max=240)
public int tree_cuttter_cutting_time_needed = BlockDecorTreeCutter.BTileEntity.DEFAULT_CUTTING_TIME_NEEDED;
@Config.Comment({
"Defines if the Small Tree Cutter does not work without RF power."
})
@Config.Name("Tree Cutter: Power required")
public boolean tree_cuttter_requires_power = false;
}
@SuppressWarnings("unused")
@ -440,6 +458,10 @@ public class ModConfig
private static final ArrayList<String> includes_ = new ArrayList<String>();
private static final ArrayList<String> excludes_ = new ArrayList<String>();
private static final NBTTagCompound server_config_ = new NBTTagCompound();
public static final NBTTagCompound getServerConfig() // config that may be synchronized from server to client via net pkg.
{ return server_config_; }
public static final boolean isWithoutOptOutRegistration()
{ return (zmisc!=null) && (zmisc.without_optout_registration); }
@ -496,6 +518,7 @@ public class ModConfig
if(block instanceof BlockDecorSolarPanel) return optout.without_solar_panel;
if(block instanceof BlockDecorFluidFunnel) return optout.without_fluid_funnel;
if(block instanceof BlockDecorMineralSmelter) return optout.without_mineral_smelter;
if(block instanceof BlockDecorMilker) return optout.without_milker;
if(block instanceof BlockDecorPipeValve) return optout.without_valves;
// Type based evaluation where later filters may match, too
@ -537,8 +560,8 @@ public class ModConfig
BlockDecorPipeValve.on_config(tweaks.pipevalve_max_flowrate, tweaks.pipevalve_redstone_slope);
BlockDecorFurnaceElectrical.BTileEntity.on_config(tweaks.e_furnace_speed_percent, tweaks.e_furnace_power_consumption);
BlockDecorSolarPanel.BTileEntity.on_config(tweaks.solar_panel_peak_power);
BlockDecorBreaker.BTileEntity.on_config(tweaks.block_breaker_power_consumption, tweaks.block_breaker_reluctance, tweaks.block_breaker_min_breaking_time, false);
BlockDecorTreeCutter.BTileEntity.on_config(tweaks.tree_cuttter_energy_consumption, tweaks.tree_cuttter_cutting_time_needed, false);
BlockDecorBreaker.BTileEntity.on_config(tweaks.block_breaker_power_consumption, tweaks.block_breaker_reluctance, tweaks.block_breaker_min_breaking_time, tweaks.block_breaker_requires_power);
BlockDecorTreeCutter.BTileEntity.on_config(tweaks.tree_cuttter_energy_consumption, tweaks.tree_cuttter_cutting_time_needed, tweaks.tree_cuttter_requires_power);
{
optout.includes = optout.includes.toLowerCase().replaceAll(ModEngineersDecor.MODID+":", "").replaceAll("[^*_,a-z0-9]", "");
if(!optout.includes.isEmpty()) ModEngineersDecor.logger.info("Pattern includes: '" + optout.includes + "'");
@ -559,6 +582,11 @@ public class ModConfig
if(!excl[i].isEmpty()) excludes_.add(excl[i]);
}
}
{
// Check if the config is already synchronized or has to be synchronised.
server_config_.setBoolean("tree_cuttter_requires_power", tweaks.tree_cuttter_requires_power);
server_config_.setBoolean("block_breaker_requires_power", tweaks.block_breaker_requires_power);
}
}
}

View file

@ -97,6 +97,7 @@ public class ModTesrs
@Override
public void render(final BlockDecorTest.BTileEntity te, double x, double y, double z, final float partialTicks, final int destroyStage, final float alpha)
{
if(te.progress() < 0) return;
renderBlockState(Blocks.SANDSTONE.getDefaultState(), te.getPos(), (new Vec3d(1,1,1)).scale(te.progress()), x,y,z);
}

View file

@ -0,0 +1,13 @@
{
"forge_marker": 1,
"defaults": {
"model": "engineersdecor:device/small_milking_machine_model"
},
"variants": {
"normal": [{}],
"inventory": [{}],
"facing": { "north": {"y":0}, "south": {"y":180}, "west": {"y":-90}, "east": {"y":90} },
"filled": { "false":{}, "true":{} },
"active": { "false":{}, "true":{ "model": "engineersdecor:device/small_milking_machine_model_active" } }
}
}

View file

@ -9,7 +9,8 @@ engineersdecor.tooltip.hint.extended=§6[§9SHIFT§r More Info§6]§r
engineersdecor.tooltip.hint.help=§6[§9CTRL-SHIFT§r Help§6]§r
engineersdecor.tooltip.slabpickup.help=§rFast pickup by left-clicking while looking up/down and holding this slab.
#-----------------------------------------------------------------------------------------------------------
# Stone/"ceramic material" based blocks
engineersdecor.tooltip.requires_rf_power=Requires RF power.
engineersdecor.tooltip.massive_speed_boost_with_rf_power=Apply RF power to magnificently increase the speed.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.clinker_brick_block.name=Clinker Brick Block
tile.engineersdecor.clinker_brick_block.help=§6A brick block with position dependent texture variations.§r\nLooks slightly darker and more color intensive than the vanilla brick block.
@ -183,7 +184,8 @@ tile.engineersdecor.small_block_breaker.name=Small Block Breaker
tile.engineersdecor.small_block_breaker.help=§6Breaks blocks in front of it.§r\n\
Can be disabled by applying a redstone signal. \
The time needed to destroy a block depends on the hardness of that block. \
Provide RF/FE power to speed up the breaking process (massively).
${!block_breaker_requires_power?engineersdecor.tooltip.massive_speed_boost_with_rf_power}\
${block_breaker_requires_power?engineersdecor.tooltip.requires_rf_power}
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. Click with a \
@ -200,7 +202,11 @@ tile.engineersdecor.small_solar_panel.help=§6Produces a small amount of power w
tile.engineersdecor.small_tree_cutter.name=Small Tree Cutter
tile.engineersdecor.small_tree_cutter.help=§6Chops grown trees in front of it.§r\n\
Does not collect the lumbers. Deactivate with a redstone signal. \
Provide RF power to boost the cutting speed (takes a long time without power).
${!tree_cuttter_requires_power?engineersdecor.tooltip.massive_speed_boost_with_rf_power}\
${tree_cuttter_requires_power?engineersdecor.tooltip.requires_rf_power}
tile.engineersdecor.small_milking_machine.name=Small Milking Machine
tile.engineersdecor.small_milking_machine.help=§6Frequently attracts and milks cows.§r\n\
Has an internal fluid tank. Does not feed the animals. Use buckets to retrieve the milk.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.sign_decor.name=Sign Plate (Engineer's decor)
tile.engineersdecor.sign_decor.help=§6This should not be craftable or visible in JEI. Used for creative tab and screenshots.

View file

@ -9,7 +9,8 @@ engineersdecor.tooltip.hint.extended=§6[§9SHIFT§r Больше информа
engineersdecor.tooltip.hint.help=§6[§9CTRL-SHIFT§r Помощь§6]§r
engineersdecor.tooltip.slabpickup.help=§rБыстрое поднятие щелчком ЛКМ, смотря вверх/вниз с этой плитой в руках.
#-----------------------------------------------------------------------------------------------------------
# Stone/"ceramic material" based blocks
engineersdecor.tooltip.requires_rf_power=Requires RF power.
engineersdecor.tooltip.massive_speed_boost_with_rf_power=Apply RF power to magnificently increase the speed.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.clinker_brick_block.name=Клинкерный кирпич
tile.engineersdecor.clinker_brick_block.help=§6Кирпичный блок с вариациями текстуры, зависящими от положения.§r\nВыглядит темнее и интенсивнее, чем Кирпичный блок.
@ -179,7 +180,8 @@ tile.engineersdecor.small_block_breaker.name=Factory Block Breaker
#tile.engineersdecor.small_block_breaker.help=§6Breaks blocks in front of it.§r\n\
Can be disabled by applying a redstone signal. \
The time needed to destroy a block depends on the hardness of that block. \
Provide RF/FE power to speed up the breaking process (massively).
${!block_breaker_requires_power?engineersdecor.tooltip.massive_speed_boost_with_rf_power}\
${block_breaker_requires_power?engineersdecor.tooltip.requires_rf_power}
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. Click with a \
@ -196,7 +198,11 @@ tile.engineersdecor.small_solar_panel.name=Small Solar Panel
tile.engineersdecor.small_tree_cutter.name=Small Tree Cutter
#tile.engineersdecor.small_tree_cutter.help=§6Chops grown trees in front of it.§r\n\
Does not collect the lumbers. Deactivate with a redstone signal. \
Provide RF power to boost the cutting speed (takes a long time without power).
${!tree_cuttter_requires_power?engineersdecor.tooltip.massive_speed_boost_with_rf_power}\
${tree_cuttter_requires_power?engineersdecor.tooltip.requires_rf_power}
tile.engineersdecor.small_milking_machine.name=Small Milking Machine
#tile.engineersdecor.small_milking_machine.help=§6Frequently attracts and milks cows.§r\n\
Has an internal fluid tank. Does not feed the animals. Use buckets to retrieve the milk.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.sign_decor.name=Табличка с надписью (Логотип Engineer's decor)
tile.engineersdecor.sign_decor.help=§Это не должно быть крафтовым или видимым в JEI. Используется для творческой вкладки и скриншотов.

View file

@ -9,7 +9,8 @@ engineersdecor.tooltip.hint.extended=§6[§9SHIFT§r 查看更多信息§6]§r
engineersdecor.tooltip.hint.help=§6[§9CTRL-SHIFT§r 查看帮助§6]§r
engineersdecor.tooltip.slabpickup.help=§r手持同类台阶往上/下看时单击该台阶可无需破坏快速拾起。
#-----------------------------------------------------------------------------------------------------------
# Stone/"ceramic material" based blocks
engineersdecor.tooltip.requires_rf_power=Requires RF power.
engineersdecor.tooltip.massive_speed_boost_with_rf_power=Apply RF power to magnificently increase the speed.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.clinker_brick_block.name=过烧砖块
tile.engineersdecor.clinker_brick_block.help=§6一种放在不同位置贴图有不同变化的砖块。§r\n比原版砖看起来颜色更深色度也更高。
@ -182,7 +183,8 @@ tile.engineersdecor.small_block_breaker.name=Factory Block Breaker
#tile.engineersdecor.small_block_breaker.help=§6Breaks blocks in front of it.§r\n\
Can be disabled by applying a redstone signal. \
The time needed to destroy a block depends on the hardness of that block. \
Provide RF/FE power to speed up the breaking process (massively).
${!block_breaker_requires_power?engineersdecor.tooltip.massive_speed_boost_with_rf_power}\
${block_breaker_requires_power?engineersdecor.tooltip.requires_rf_power}
tile.engineersdecor.small_mineral_smelter.name=小型矿物熔炼炉
tile.engineersdecor.small_mineral_smelter.help=§6高温、高绝缘电熔石炉。§r\n\
把矿物块加热成岩浆块,最后变成熔岩。由于\
@ -197,6 +199,9 @@ tile.engineersdecor.small_tree_cutter.name=小型砍树机
tile.engineersdecor.small_tree_cutter.help=§6砍倒正前方的树。§r\n\
不收集木材。通入红石信号停用。\
提供RF来加快砍树速度。没有的话会很慢。
tile.engineersdecor.small_milking_machine.name=Small Milking Machine
#tile.engineersdecor.small_milking_machine.help=§6Frequently attracts and milks cows.§r\n\
Has an internal fluid tank. Does not feed the animals. Use buckets to retrieve the milk.
#-----------------------------------------------------------------------------------------------------------
tile.engineersdecor.sign_decor.name=标志板(工程师的装饰)
tile.engineersdecor.sign_decor.help=§6这不应该可合成或在JEI看到。用于创造模式的物品栏标签和截屏。

View file

@ -0,0 +1,271 @@
{
"parent": "block/cube",
"textures": {
"s": "engineersdecor:blocks/device/tree_cutter_side",
"particle": "engineersdecor:blocks/device/tree_cutter_side",
"t": "engineersdecor:blocks/device/tree_cutter_top",
"b": "engineersdecor:blocks/device/tree_cutter_bottom"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 1, 13],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -2]},
"faces": {
"north": {"uv": [0, 15, 16, 16], "texture": "#s"},
"east": {"uv": [3, 15, 16, 16], "texture": "#s"},
"south": {"uv": [0, 15, 16, 16], "texture": "#s"},
"west": {"uv": [0, 15, 13, 16], "texture": "#s"},
"up": {"uv": [0, 0, 16, 13], "texture": "#t"},
"down": {"uv": [0, 3, 16, 16], "texture": "#b"}
}
},
{
"from": [0, 14, 0],
"to": [16, 16, 13],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 23, -2]},
"faces": {
"north": {"uv": [0, 0, 16, 2], "texture": "#s"},
"east": {"uv": [3, 0, 16, 2], "texture": "#s"},
"south": {"uv": [0, 0, 16, 2], "texture": "#s"},
"west": {"uv": [0, 0, 13, 2], "texture": "#s"},
"up": {"uv": [0, 0, 16, 13], "texture": "#t"},
"down": {"uv": [0, 3, 16, 16], "texture": "#b"}
}
},
{
"from": [0, 1, 1],
"to": [1, 14, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [5, 7.5, 5.5]},
"faces": {
"north": {"uv": [15, 2, 16, 15], "texture": "#s"},
"east": {"uv": [5, 2, 15, 15], "texture": "#s"},
"south": {"uv": [0, 2, 1, 15], "texture": "#s"},
"west": {"uv": [1, 2, 11, 15], "texture": "#s"},
"up": {"uv": [0, 1, 1, 11], "texture": "#t"},
"down": {"uv": [0, 5, 1, 15], "texture": "#b"}
}
},
{
"from": [1, 1, 0],
"to": [15, 14, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [6, 7.5, 5.5]},
"faces": {
"north": {"uv": [1, 2, 15, 15], "texture": "#s"},
"east": {"uv": [6, 2, 16, 15], "texture": "#s"},
"south": {"uv": [1, 2, 15, 15], "texture": "#s"},
"west": {"uv": [0, 2, 10, 15], "texture": "#s"},
"up": {"uv": [1, 0, 15, 10], "texture": "#t"},
"down": {"uv": [1, 6, 15, 16], "texture": "#b"}
}
},
{
"from": [6, 1, 10],
"to": [10, 14, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 7.5, 15.5]},
"faces": {
"north": {"uv": [6, 2, 10, 15], "texture": "#s"},
"east": {"uv": [5, 2, 6, 15], "texture": "#s"},
"south": {"uv": [6, 2, 10, 15], "texture": "#s"},
"west": {"uv": [10, 2, 11, 15], "texture": "#s"},
"up": {"uv": [6, 10, 10, 11], "texture": "#t"},
"down": {"uv": [6, 5, 10, 6], "texture": "#b"}
}
},
{
"from": [15, 1, 1],
"to": [16, 14, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [13.5, 7.5, 9]},
"faces": {
"north": {"uv": [0, 2, 1, 15], "texture": "#s"},
"east": {"uv": [5, 2, 15, 15], "texture": "#s"},
"south": {"uv": [15, 2, 16, 15], "texture": "#s"},
"west": {"uv": [1, 2, 11, 15], "texture": "#s"},
"up": {"uv": [15, 1, 16, 11], "texture": "#t"},
"down": {"uv": [15, 5, 16, 15], "texture": "#b"}
}
},
{
"from": [7.5, 2, 12],
"to": [8.5, 12, 14],
"rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [13, 3, 14, 10], "rotation": 180, "texture": "#b"},
"east": {"uv": [0, 6, 8, 8], "rotation": 270, "texture": "#s"},
"south": {"uv": [2, 4, 3, 13], "texture": "#t"},
"west": {"uv": [6, 6, 16, 8], "rotation": 90, "texture": "#s"},
"up": {"uv": [5, 6, 6, 8], "rotation": 180, "texture": "#s"},
"down": {"uv": [10, 6, 11, 8], "texture": "#s"}
}
},
{
"from": [8.5, 10, 11],
"to": [9.5, 13, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8.5, 19, 9]},
"faces": {
"north": {"uv": [6.5, 3, 7.5, 6], "texture": "#s"},
"east": {"uv": [1, 3, 5, 6], "texture": "#s"},
"south": {"uv": [8.5, 3, 9.5, 6], "texture": "#s"},
"west": {"uv": [11, 3, 15, 6], "texture": "#s"},
"up": {"uv": [8.5, 11, 9.5, 15], "texture": "#t"},
"down": {"uv": [8.5, 1, 9.5, 5], "texture": "#b"}
}
},
{
"from": [8.5, 13, 11],
"to": [9.5, 14, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8.5, 20, 9]},
"faces": {
"north": {"uv": [6.5, 2, 7.5, 3], "texture": "#s"},
"east": {"uv": [2, 2, 5, 3], "texture": "#s"},
"south": {"uv": [8.5, 2, 9.5, 3], "texture": "#s"},
"west": {"uv": [11, 2, 14, 3], "texture": "#s"},
"up": {"uv": [8.5, 11, 9.5, 14], "texture": "#t"},
"down": {"uv": [8.5, 2, 9.5, 5], "texture": "#b"}
}
},
{
"from": [6.5, 13, 11],
"to": [7.5, 14, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, 20, 9]},
"faces": {
"north": {"uv": [8.5, 2, 9.5, 3], "texture": "#s"},
"east": {"uv": [2, 2, 5, 3], "texture": "#s"},
"south": {"uv": [6.5, 2, 7.5, 3], "texture": "#s"},
"west": {"uv": [11, 2, 14, 3], "texture": "#s"},
"up": {"uv": [6.5, 11, 7.5, 14], "texture": "#t"},
"down": {"uv": [6.5, 2, 7.5, 5], "texture": "#b"}
}
},
{
"from": [6.5, 10, 11],
"to": [7.5, 13, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, 19, 9]},
"faces": {
"north": {"uv": [8.5, 3, 9.5, 6], "texture": "#s"},
"east": {"uv": [1, 3, 5, 6], "texture": "#s"},
"south": {"uv": [6.5, 3, 7.5, 6], "texture": "#s"},
"west": {"uv": [11, 3, 15, 6], "texture": "#s"},
"up": {"uv": [6.5, 11, 7.5, 15], "texture": "#t"},
"down": {"uv": [6.5, 1, 7.5, 5], "texture": "#b"}
}
},
{
"from": [7.5, 10, 11],
"to": [8.5, 13, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [7.5, 19, 9]},
"faces": {
"north": {"uv": [7.5, 3, 8.5, 6], "texture": "#s"},
"east": {"uv": [4, 3, 5, 6], "texture": "#s"},
"south": {"uv": [7.5, 3, 8.5, 6], "texture": "#s"},
"west": {"uv": [11, 3, 12, 6], "texture": "#s"},
"up": {"uv": [7.5, 11, 8.5, 12], "texture": "#t"},
"down": {"uv": [7.5, 4, 8.5, 5], "texture": "#b"}
}
},
{
"from": [6.5, 2, 13],
"to": [7.5, 5, 14],
"rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [8.5, 11, 9.5, 14], "rotation": 180, "texture": "#b"},
"east": {"uv": [2, 11, 3, 14], "rotation": 270, "texture": "#s"},
"south": {"uv": [6.5, 11, 7.5, 14], "texture": "#t"},
"west": {"uv": [13, 11, 14, 14], "texture": "#s"},
"up": {"uv": [6.5, 13, 7.5, 14], "rotation": 180, "texture": "#s"},
"down": {"uv": [6.5, 2, 7.5, 3], "texture": "#s"}
}
},
{
"from": [8.5, 2, 13],
"to": [9.5, 5, 14],
"rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [6.5, 11, 7.5, 14], "rotation": 180, "texture": "#b"},
"east": {"uv": [2, 11, 3, 14], "texture": "#s"},
"south": {"uv": [8.5, 11, 9.5, 14], "texture": "#t"},
"west": {"uv": [13, 11, 14, 14], "rotation": 90, "texture": "#s"},
"up": {"uv": [8.5, 13, 9.5, 14], "rotation": 180, "texture": "#s"},
"down": {"uv": [8.5, 2, 9.5, 3], "texture": "#s"}
}
},
{
"from": [6.5, 4, 14],
"to": [7.5, 5, 15],
"rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [9, 0, 10, 0], "rotation": 180, "texture": "#b"},
"east": {"uv": [0, 4, 0, 6], "rotation": 270, "texture": "#s"},
"south": {"uv": [8, 14, 9, 15], "texture": "#t"},
"west": {"uv": [15, 4, 16, 6], "rotation": 90, "texture": "#s"},
"up": {"uv": [6, 4, 7, 6], "rotation": 180, "texture": "#s"},
"down": {"uv": [9, 4, 10, 6], "texture": "#s"}
}
},
{
"from": [8.5, 4, 14],
"to": [9.5, 5, 15],
"rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [11, 0, 12, 0], "rotation": 180, "texture": "#b"},
"east": {"uv": [0, 4, 1, 6], "rotation": 270, "texture": "#s"},
"south": {"uv": [10, 14, 11, 15], "texture": "#t"},
"west": {"uv": [16, 4, 16, 6], "rotation": 90, "texture": "#s"},
"up": {"uv": [4, 4, 5, 6], "rotation": 180, "texture": "#s"},
"down": {"uv": [11, 4, 12, 6], "texture": "#s"}
}
},
{
"from": [8.5, 2, 14],
"to": [9.5, 3, 15],
"rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [11, 0, 12, 0], "rotation": 180, "texture": "#b"},
"east": {"uv": [0, 4, 1, 6], "rotation": 270, "texture": "#s"},
"south": {"uv": [10, 14, 11, 15], "texture": "#t"},
"west": {"uv": [16, 4, 16, 6], "rotation": 90, "texture": "#s"},
"up": {"uv": [4, 4, 5, 6], "rotation": 180, "texture": "#s"},
"down": {"uv": [11, 4, 12, 6], "texture": "#s"}
}
},
{
"from": [6.5, 2, 14],
"to": [7.5, 3, 15],
"rotation": {"angle": 0, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [9, 0, 10, 0], "rotation": 180, "texture": "#b"},
"east": {"uv": [0, 4, 0, 6], "rotation": 270, "texture": "#s"},
"south": {"uv": [8, 13, 9, 14], "texture": "#t"},
"west": {"uv": [15, 4, 16, 6], "rotation": 90, "texture": "#s"},
"up": {"uv": [6, 4, 7, 6], "rotation": 180, "texture": "#s"},
"down": {"uv": [9, 4, 10, 6], "texture": "#s"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [73, 180, 0],
"translation": [0, -1.75, -1.5],
"scale": [0.2, 0.2, 0.2]
},
"firstperson_righthand": {
"rotation": [18, 22, 0],
"translation": [1.25, 0, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 1.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {
"rotation": [30, 40, 0],
"translation": [0.5, -0.25, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"rotation": [0, 180, 0],
"translation": [0, 0, -3.25],
"scale": [0.5, 0.5, 0.5]
}
}
}

View file

@ -0,0 +1,271 @@
{
"parent": "block/cube",
"textures": {
"s": "engineersdecor:blocks/device/tree_cutter_side",
"particle": "engineersdecor:blocks/device/tree_cutter_side",
"t": "engineersdecor:blocks/device/tree_cutter_top",
"b": "engineersdecor:blocks/device/tree_cutter_bottom"
},
"elements": [
{
"from": [0, 0, 0],
"to": [16, 1, 13],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 8, -2]},
"faces": {
"north": {"uv": [0, 15, 16, 16], "texture": "#s"},
"east": {"uv": [3, 15, 16, 16], "texture": "#s"},
"south": {"uv": [0, 15, 16, 16], "texture": "#s"},
"west": {"uv": [0, 15, 13, 16], "texture": "#s"},
"up": {"uv": [0, 0, 16, 13], "texture": "#t"},
"down": {"uv": [0, 3, 16, 16], "texture": "#b"}
}
},
{
"from": [0, 14, 0],
"to": [16, 16, 13],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 23, -2]},
"faces": {
"north": {"uv": [0, 0, 16, 2], "texture": "#s"},
"east": {"uv": [3, 0, 16, 2], "texture": "#s"},
"south": {"uv": [0, 0, 16, 2], "texture": "#s"},
"west": {"uv": [0, 0, 13, 2], "texture": "#s"},
"up": {"uv": [0, 0, 16, 13], "texture": "#t"},
"down": {"uv": [0, 3, 16, 16], "texture": "#b"}
}
},
{
"from": [0, 1, 1],
"to": [1, 14, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [5, 7.5, 5.5]},
"faces": {
"north": {"uv": [15, 2, 16, 15], "texture": "#s"},
"east": {"uv": [5, 2, 15, 15], "texture": "#s"},
"south": {"uv": [0, 2, 1, 15], "texture": "#s"},
"west": {"uv": [1, 2, 11, 15], "texture": "#s"},
"up": {"uv": [0, 1, 1, 11], "texture": "#t"},
"down": {"uv": [0, 5, 1, 15], "texture": "#b"}
}
},
{
"from": [1, 1, 0],
"to": [15, 14, 10],
"rotation": {"angle": 0, "axis": "y", "origin": [6, 7.5, 5.5]},
"faces": {
"north": {"uv": [1, 2, 15, 15], "texture": "#s"},
"east": {"uv": [6, 2, 16, 15], "texture": "#s"},
"south": {"uv": [1, 2, 15, 15], "texture": "#s"},
"west": {"uv": [0, 2, 10, 15], "texture": "#s"},
"up": {"uv": [1, 0, 15, 10], "texture": "#t"},
"down": {"uv": [1, 6, 15, 16], "texture": "#b"}
}
},
{
"from": [6, 1, 10],
"to": [10, 14, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 7.5, 15.5]},
"faces": {
"north": {"uv": [6, 2, 10, 15], "texture": "#s"},
"east": {"uv": [5, 2, 6, 15], "texture": "#s"},
"south": {"uv": [6, 2, 10, 15], "texture": "#s"},
"west": {"uv": [10, 2, 11, 15], "texture": "#s"},
"up": {"uv": [6, 10, 10, 11], "texture": "#t"},
"down": {"uv": [6, 5, 10, 6], "texture": "#b"}
}
},
{
"from": [15, 1, 1],
"to": [16, 14, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [13.5, 7.5, 9]},
"faces": {
"north": {"uv": [0, 2, 1, 15], "texture": "#s"},
"east": {"uv": [5, 2, 15, 15], "texture": "#s"},
"south": {"uv": [15, 2, 16, 15], "texture": "#s"},
"west": {"uv": [1, 2, 11, 15], "texture": "#s"},
"up": {"uv": [15, 1, 16, 11], "texture": "#t"},
"down": {"uv": [15, 5, 16, 15], "texture": "#b"}
}
},
{
"from": [8.5, 10, 11],
"to": [9.5, 13, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [8.5, 19, 9]},
"faces": {
"north": {"uv": [6.5, 3, 7.5, 6], "texture": "#s"},
"east": {"uv": [1, 3, 5, 6], "texture": "#s"},
"south": {"uv": [8.5, 3, 9.5, 6], "texture": "#s"},
"west": {"uv": [11, 3, 15, 6], "texture": "#s"},
"up": {"uv": [8.5, 11, 9.5, 15], "texture": "#t"},
"down": {"uv": [8.5, 1, 9.5, 5], "texture": "#b"}
}
},
{
"from": [8.5, 13, 11],
"to": [9.5, 14, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8.5, 20, 9]},
"faces": {
"north": {"uv": [6.5, 2, 7.5, 3], "texture": "#s"},
"east": {"uv": [2, 2, 5, 3], "texture": "#s"},
"south": {"uv": [8.5, 2, 9.5, 3], "texture": "#s"},
"west": {"uv": [11, 2, 14, 3], "texture": "#s"},
"up": {"uv": [8.5, 11, 9.5, 14], "texture": "#t"},
"down": {"uv": [8.5, 2, 9.5, 5], "texture": "#b"}
}
},
{
"from": [6.5, 13, 11],
"to": [7.5, 14, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, 20, 9]},
"faces": {
"north": {"uv": [8.5, 2, 9.5, 3], "texture": "#s"},
"east": {"uv": [2, 2, 5, 3], "texture": "#s"},
"south": {"uv": [6.5, 2, 7.5, 3], "texture": "#s"},
"west": {"uv": [11, 2, 14, 3], "texture": "#s"},
"up": {"uv": [6.5, 11, 7.5, 14], "texture": "#t"},
"down": {"uv": [6.5, 2, 7.5, 5], "texture": "#b"}
}
},
{
"from": [6.5, 10, 11],
"to": [7.5, 13, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [6.5, 19, 9]},
"faces": {
"north": {"uv": [8.5, 3, 9.5, 6], "texture": "#s"},
"east": {"uv": [1, 3, 5, 6], "texture": "#s"},
"south": {"uv": [6.5, 3, 7.5, 6], "texture": "#s"},
"west": {"uv": [11, 3, 15, 6], "texture": "#s"},
"up": {"uv": [6.5, 11, 7.5, 15], "texture": "#t"},
"down": {"uv": [6.5, 1, 7.5, 5], "texture": "#b"}
}
},
{
"from": [7.5, 10, 11],
"to": [8.5, 13, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [7.5, 19, 9]},
"faces": {
"north": {"uv": [7.5, 3, 8.5, 6], "texture": "#s"},
"east": {"uv": [4, 3, 5, 6], "texture": "#s"},
"south": {"uv": [7.5, 3, 8.5, 6], "texture": "#s"},
"west": {"uv": [11, 3, 12, 6], "texture": "#s"},
"up": {"uv": [7.5, 11, 8.5, 12], "texture": "#t"},
"down": {"uv": [7.5, 4, 8.5, 5], "texture": "#b"}
}
},
{
"from": [7.5, 10, 12],
"to": [8.5, 12, 22],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [5, 6, 6, 8], "texture": "#s"},
"east": {"uv": [0, 6, 8, 8], "texture": "#s"},
"south": {"uv": [10, 6, 11, 8], "texture": "#s"},
"west": {"uv": [6, 6, 16, 8], "texture": "#s"},
"up": {"uv": [2, 4, 3, 13], "texture": "#t"},
"down": {"uv": [13, 3, 14, 10], "texture": "#b"}
}
},
{
"from": [8.5, 11, 19],
"to": [9.5, 12, 22],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [8.5, 13, 9.5, 14], "texture": "#s"},
"east": {"uv": [2, 11, 3, 14], "rotation": 90, "texture": "#s"},
"south": {"uv": [8.5, 2, 9.5, 3], "texture": "#s"},
"west": {"uv": [13, 11, 14, 14], "texture": "#s"},
"up": {"uv": [8.5, 11, 9.5, 14], "texture": "#t"},
"down": {"uv": [6.5, 11, 7.5, 14], "texture": "#b"}
}
},
{
"from": [8.5, 12, 19],
"to": [9.5, 13, 20],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [4, 4, 5, 6], "texture": "#s"},
"east": {"uv": [0, 4, 1, 6], "texture": "#s"},
"south": {"uv": [11, 4, 12, 6], "texture": "#s"},
"west": {"uv": [16, 4, 16, 6], "texture": "#s"},
"up": {"uv": [10, 14, 11, 15], "texture": "#t"},
"down": {"uv": [11, 0, 12, 0], "texture": "#b"}
}
},
{
"from": [8.5, 12, 21],
"to": [9.5, 13, 22],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [4, 4, 5, 6], "texture": "#s"},
"east": {"uv": [0, 4, 1, 6], "texture": "#s"},
"south": {"uv": [11, 4, 12, 6], "texture": "#s"},
"west": {"uv": [16, 4, 16, 6], "texture": "#s"},
"up": {"uv": [10, 14, 11, 15], "texture": "#t"},
"down": {"uv": [11, 0, 12, 0], "texture": "#b"}
}
},
{
"from": [6.5, 11, 19],
"to": [7.5, 12, 22],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [6.5, 13, 7.5, 14], "texture": "#s"},
"east": {"uv": [2, 11, 3, 14], "texture": "#s"},
"south": {"uv": [6.5, 2, 7.5, 3], "texture": "#s"},
"west": {"uv": [13, 11, 14, 14], "rotation": 270, "texture": "#s"},
"up": {"uv": [6.5, 11, 7.5, 14], "texture": "#t"},
"down": {"uv": [8.5, 11, 9.5, 14], "texture": "#b"}
}
},
{
"from": [6.5, 12, 21],
"to": [7.5, 13, 22],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [6, 4, 7, 6], "texture": "#s"},
"east": {"uv": [0, 4, 0, 6], "texture": "#s"},
"south": {"uv": [9, 4, 10, 6], "texture": "#s"},
"west": {"uv": [15, 4, 16, 6], "texture": "#s"},
"up": {"uv": [8, 13, 9, 14], "texture": "#t"},
"down": {"uv": [9, 0, 10, 0], "texture": "#b"}
}
},
{
"from": [6.5, 12, 19],
"to": [7.5, 13, 20],
"rotation": {"angle": 22.5, "axis": "x", "origin": [8, 11, 13]},
"faces": {
"north": {"uv": [6, 4, 7, 6], "texture": "#s"},
"east": {"uv": [0, 4, 0, 6], "texture": "#s"},
"south": {"uv": [9, 4, 10, 6], "texture": "#s"},
"west": {"uv": [15, 4, 16, 6], "texture": "#s"},
"up": {"uv": [8, 14, 9, 15], "texture": "#t"},
"down": {"uv": [9, 0, 10, 0], "texture": "#b"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [57, 82, -38],
"translation": [2.25, -0.5, -2],
"scale": [0.35, 0.35, 0.35]
},
"firstperson_righthand": {
"rotation": [18, 22, 0],
"translation": [1.25, 0, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 1.75, 0],
"scale": [0.2, 0.2, 0.2]
},
"gui": {
"rotation": [30, 40, 0],
"translation": [1.25, -1, 0],
"scale": [0.625, 0.625, 0.625]
},
"fixed": {
"rotation": [0, 180, 0],
"translation": [0, 0, -3.25],
"scale": [0.5, 0.5, 0.5]
}
}
}

View file

@ -0,0 +1,37 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"result": "engineersdecor:small_milking_machine",
"missing": ["immersiveengineering:material"]
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"PPP",
"PAO",
"PRP"
],
"key": {
"O": {
"item": "minecraft:observer",
"data": 0
},
"P": {
"item": "#ingotIron",
"data": 0
},
"A": {
"item": "minecraft:milk_bucket",
"data": 0
},
"R": {
"item": "minecraft:redstone_block",
"data": 0
}
},
"result": {
"item": "engineersdecor:small_milking_machine",
"count": 1
}
}

View file

@ -0,0 +1,41 @@
{
"conditions": [
{
"type": "engineersdecor:grc",
"result": "engineersdecor:small_milking_machine",
"required": ["immersiveengineering:material"]
}
],
"type": "minecraft:crafting_shaped",
"pattern": [
"PPP",
"PAO",
"CRC"
],
"key": {
"O": {
"item": "minecraft:observer",
"data": 0
},
"P": {
"item": "#plateAnyFerroMetal",
"data": 0
},
"A": {
"item": "minecraft:milk_bucket",
"data": 0
},
"R": {
"item": "minecraft:redstone_block",
"data": 0
},
"C": {
"item": "#anyMechanicalComponent",
"data": 0
}
},
"result": {
"item": "engineersdecor:small_milking_machine",
"count": 1
}
}

View file

@ -23,6 +23,6 @@
},
"result": {
"item": "engineersdecor:clinker_brick_block",
"count": 4
"count": 8
}
}