diff --git a/src/generated/resources/assets/enderio/blockstates/farming_station.json b/src/generated/resources/assets/enderio/blockstates/farming_station.json new file mode 100644 index 0000000000..d379f9d30a --- /dev/null +++ b/src/generated/resources/assets/enderio/blockstates/farming_station.json @@ -0,0 +1,19 @@ +{ + "variants": { + "facing=east": { + "model": "enderio:block/farming_station_combined", + "y": 90 + }, + "facing=north": { + "model": "enderio:block/farming_station_combined" + }, + "facing=south": { + "model": "enderio:block/farming_station_combined", + "y": 180 + }, + "facing=west": { + "model": "enderio:block/farming_station_combined", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/enderio/lang/en_ud.json b/src/generated/resources/assets/enderio/lang/en_ud.json index 54ae62999d..ed53eba440 100644 --- a/src/generated/resources/assets/enderio/lang/en_ud.json +++ b/src/generated/resources/assets/enderio/lang/en_ud.json @@ -83,6 +83,7 @@ "block.enderio.energetic_alloy_block": "ʞɔoןᗺ ʎoןןⱯ ɔıʇǝbɹǝuƎ", "block.enderio.energetic_photovoltaic_module": "ǝןnpoW ɔıɐʇןoʌoʇoɥԀ ɔıʇǝbɹǝuƎ", "block.enderio.ensouled_chassis": "sıssɐɥƆ pǝןnosuƎ", + "block.enderio.farming_station": "uoıʇɐʇS buıɯɹɐℲ", "block.enderio.fire_water": "ɹǝʇɐM ǝɹıℲ", "block.enderio.fluid_tank": "ʞuɐ⟘ pınןℲ", "block.enderio.fused_quartz": "zʇɹɐnὉ pǝsnℲ", diff --git a/src/generated/resources/assets/enderio/lang/en_us.json b/src/generated/resources/assets/enderio/lang/en_us.json index bf07fb6dac..f1c0a8c9a0 100644 --- a/src/generated/resources/assets/enderio/lang/en_us.json +++ b/src/generated/resources/assets/enderio/lang/en_us.json @@ -83,6 +83,7 @@ "block.enderio.energetic_alloy_block": "Energetic Alloy Block", "block.enderio.energetic_photovoltaic_module": "Energetic Photovoltaic Module", "block.enderio.ensouled_chassis": "Ensouled Chassis", + "block.enderio.farming_station": "Farming Station", "block.enderio.fire_water": "Fire Water", "block.enderio.fluid_tank": "Fluid Tank", "block.enderio.fused_quartz": "Fused Quartz", diff --git a/src/generated/resources/assets/enderio/models/block/farming_station_combined.json b/src/generated/resources/assets/enderio/models/block/farming_station_combined.json new file mode 100644 index 0000000000..3d8a233c9f --- /dev/null +++ b/src/generated/resources/assets/enderio/models/block/farming_station_combined.json @@ -0,0 +1,16 @@ +{ + "parent": "minecraft:block/block", + "children": { + "machine": { + "parent": "enderio:block/farming_station" + }, + "overlay": { + "parent": "enderio:block/io_overlay" + } + }, + "item_render_order": [ + "machine", + "overlay" + ], + "loader": "forge:composite" +} \ No newline at end of file diff --git a/src/generated/resources/assets/enderio/models/item/farming_station.json b/src/generated/resources/assets/enderio/models/item/farming_station.json new file mode 100644 index 0000000000..ce56437eed --- /dev/null +++ b/src/generated/resources/assets/enderio/models/item/farming_station.json @@ -0,0 +1,38 @@ +{ + "parent": "enderio:block/farming_station", + "textures": { + "particle": "enderio:block/farming_station" + }, + "display": { + "gui": { + "rotation": [ 30, 45, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.625, 0.625, 0.625 ] + }, + "ground": { + "rotation": [ 0, 0, 0 ], + "translation": [ 0, 3, 0], + "scale":[ 0.25, 0.25, 0.25 ] + }, + "head": { + "rotation": [ 0, 180, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 1, 1, 1] + }, + "fixed": { + "rotation": [ 0, 180, 0 ], + "translation": [ 0, 0, 0], + "scale":[ 0.5, 0.5, 0.5 ] + }, + "thirdperson_righthand": { + "rotation": [ 75, 315, 0 ], + "translation": [ 0, 2.5, 0], + "scale": [ 0.375, 0.375, 0.375 ] + }, + "firstperson_righthand": { + "rotation": [ 0, 315, 0 ], + "translation": [ 0, 0, 0], + "scale": [ 0.4, 0.4, 0.4 ] + } + } +} \ No newline at end of file diff --git a/src/generated/resources/data/enderio/loot_tables/blocks/farming_station.json b/src/generated/resources/data/enderio/loot_tables/blocks/farming_station.json new file mode 100644 index 0000000000..68bc4d91c1 --- /dev/null +++ b/src/generated/resources/data/enderio/loot_tables/blocks/farming_station.json @@ -0,0 +1,29 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "functions": [ + { + "function": "minecraft:copy_nbt", + "ops": [ + { + "op": "replace", + "source": "", + "target": "BlockEntityTag" + } + ], + "source": "block_entity" + } + ], + "name": "enderio:farming_station" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "enderio:blocks/farming_station" +} \ No newline at end of file diff --git a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json index 3027e7460a..670479463a 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json +++ b/src/generated/resources/data/minecraft/tags/blocks/mineable/pickaxe.json @@ -47,6 +47,7 @@ "enderio:slice_and_splice", "enderio:impulse_hopper", "enderio:soul_binder", + "enderio:farming_station", "enderio:powered_spawner", "enderio:vacuum_chest", "enderio:xp_vacuum", diff --git a/src/generated/resources/data/minecraft/tags/blocks/needs_iron_tool.json b/src/generated/resources/data/minecraft/tags/blocks/needs_iron_tool.json index a7e24fbdce..fbf1e910e0 100644 --- a/src/generated/resources/data/minecraft/tags/blocks/needs_iron_tool.json +++ b/src/generated/resources/data/minecraft/tags/blocks/needs_iron_tool.json @@ -18,6 +18,7 @@ "enderio:slice_and_splice", "enderio:impulse_hopper", "enderio:soul_binder", + "enderio:farming_station", "enderio:powered_spawner", "enderio:vacuum_chest", "enderio:xp_vacuum", diff --git a/src/machines/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java b/src/machines/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java new file mode 100644 index 0000000000..ab83f43791 --- /dev/null +++ b/src/machines/java/com/enderio/machines/client/gui/screen/FarmingStationScreen.java @@ -0,0 +1,55 @@ +package com.enderio.machines.client.gui.screen; + +import com.enderio.EnderIO; +import com.enderio.api.misc.Vector2i; +import com.enderio.base.common.lang.EIOLang; +import com.enderio.core.client.gui.screen.EIOScreen; +import com.enderio.core.client.gui.widgets.EnumIconWidget; +import com.enderio.core.client.gui.widgets.ToggleImageButton; +import com.enderio.machines.client.gui.widget.CapacitorEnergyWidget; +import com.enderio.machines.client.gui.widget.FluidStackWidget; +import com.enderio.machines.client.gui.widget.ProgressWidget; +import com.enderio.machines.client.gui.widget.ioconfig.IOConfigButton; +import com.enderio.machines.common.menu.FarmingStationMenu; +import com.enderio.machines.common.menu.WiredChargerMenu; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; + +public class FarmingStationScreen extends EIOScreen { + + private static final ResourceLocation BG_TEXTURE = EnderIO.loc("textures/gui/farming_station.png"); + private static final ResourceLocation RANGE_BUTTON_TEXTURE = EnderIO.loc("textures/gui/icons/range_buttons.png"); + public FarmingStationScreen(FarmingStationMenu pMenu, Inventory pPlayerInventory, Component pTitle) { + super(pMenu, pPlayerInventory, pTitle); + } + + @Override + protected void init() { + super.init(); + + addRenderableOnly(new CapacitorEnergyWidget(this, getMenu().getBlockEntity()::getEnergyStorage, getMenu().getBlockEntity()::isCapacitorInstalled, 16 + leftPos + 42, 14 + topPos, 9, 45)); + + addRenderableWidget(new EnumIconWidget<>(this, leftPos + imageWidth - 8 - 12, topPos + 6, () -> menu.getBlockEntity().getRedstoneControl(), + control -> menu.getBlockEntity().setRedstoneControl(control), EIOLang.REDSTONE_MODE)); + + addRenderableWidget(new IOConfigButton<>(this, leftPos + imageWidth - 6 - 16, topPos + 22, 16, 16, menu, this::addRenderableWidget, font)); + + + addRenderableWidget(new ToggleImageButton<>(this, leftPos + imageWidth - 6 - 16, topPos + 40, 16, 16, 0, 0, 16, 0, RANGE_BUTTON_TEXTURE, + () -> menu.getBlockEntity().isRangeVisible(), state -> menu.getBlockEntity().setIsRangeVisible(state), + () -> menu.getBlockEntity().isRangeVisible() ? EIOLang.HIDE_RANGE : EIOLang.SHOW_RANGE)); + + addRenderableOnly(new FluidStackWidget(this, getMenu().getBlockEntity()::getFluidTank, 7 + leftPos, 14 + topPos, 16, 47)); + } + + @Override + public ResourceLocation getBackgroundImage() { + return BG_TEXTURE; + } + + @Override + protected Vector2i getBackgroundImageSize() { + return new Vector2i(227, 169); + } +} diff --git a/src/machines/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java b/src/machines/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java index 826f8b9dac..31d6039c20 100644 --- a/src/machines/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java +++ b/src/machines/java/com/enderio/machines/common/blockentity/base/MachineBlockEntity.java @@ -267,6 +267,7 @@ public int getRange() { public void setRange(int range) { if (level != null && level.isClientSide()) { clientUpdateSlot(rangeDataSlot, range); + this.range = range; } else this.range = range; } diff --git a/src/machines/java/com/enderio/machines/common/blockentity/farming/FarmingOperation.java b/src/machines/java/com/enderio/machines/common/blockentity/farming/FarmingOperation.java new file mode 100644 index 0000000000..4049f32c68 --- /dev/null +++ b/src/machines/java/com/enderio/machines/common/blockentity/farming/FarmingOperation.java @@ -0,0 +1,8 @@ +package com.enderio.machines.common.blockentity.farming; + +public enum FarmingOperation { + TILL, + PLANT, + CHOP, + MISC +} diff --git a/src/machines/java/com/enderio/machines/common/blockentity/farming/FarmingStationBlockEntity.java b/src/machines/java/com/enderio/machines/common/blockentity/farming/FarmingStationBlockEntity.java new file mode 100644 index 0000000000..c0da7e4e2a --- /dev/null +++ b/src/machines/java/com/enderio/machines/common/blockentity/farming/FarmingStationBlockEntity.java @@ -0,0 +1,338 @@ +package com.enderio.machines.common.blockentity.farming; + +import com.enderio.api.capacitor.CapacitorModifier; +import com.enderio.api.capacitor.QuadraticScalable; +import com.enderio.api.io.energy.EnergyIOMode; +import com.enderio.core.common.network.slot.BooleanNetworkDataSlot; +import com.enderio.core.common.network.slot.IntegerNetworkDataSlot; +import com.enderio.machines.common.blockentity.base.PoweredMachineBlockEntity; +import com.enderio.machines.common.blockentity.farming.farmers.IFarmer; +import com.enderio.machines.common.blockentity.farming.farmers.PlantFarmer; +import com.enderio.machines.common.blockentity.farming.farmers.PumpkinFarmer; +import com.enderio.machines.common.config.MachinesConfig; +import com.enderio.machines.common.io.item.MachineInventoryLayout; +import com.enderio.machines.common.io.item.MultiSlotAccess; +import com.enderio.machines.common.io.item.SingleSlotAccess; +import com.enderio.machines.common.menu.FarmingStationMenu; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.tags.FluidTags; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.*; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.common.IPlantable; +import net.minecraftforge.common.util.FakePlayerFactory; +import net.minecraftforge.fluids.capability.IFluidHandler; +import net.minecraftforge.fluids.capability.templates.FluidTank; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class FarmingStationBlockEntity extends PoweredMachineBlockEntity { + + public static final QuadraticScalable CAPACITY = new QuadraticScalable(CapacitorModifier.ENERGY_CAPACITY, MachinesConfig.COMMON.ENERGY.WIRED_CHARGER_CAPACITY); + + public static final QuadraticScalable USAGE = new QuadraticScalable(CapacitorModifier.ENERGY_USE, MachinesConfig.COMMON.ENERGY.WIRED_CHARGER_USAGE); + + public static final SingleSlotAccess HOE = new SingleSlotAccess(); + + public static final SingleSlotAccess AXE = new SingleSlotAccess(); + + public static final SingleSlotAccess SHEARS = new SingleSlotAccess(); + + public static final MultiSlotAccess FERTILIZERS = new MultiSlotAccess(); + + public static final MultiSlotAccess INPUTS = new MultiSlotAccess(); + + public static final MultiSlotAccess OUTPUT = new MultiSlotAccess(); + + //Should be dynamically increased with a better capacitor + public static final int TICK_PER_OPERATION = 1; + + public static final int GET_WATER_PER_OPERATION = 20; + + private int completedTicks = 0; + private int counter = 0; + + private List blocksInRange; + + + public FarmingStationBlockEntity(BlockEntityType type, BlockPos worldPosition, BlockState blockState) { + super(EnergyIOMode.Input, CAPACITY, USAGE, type, worldPosition, blockState); + setRange(getRange()); + blocksInRange = getBlocksInRange(); + + rangeDataSlot = new IntegerNetworkDataSlot(this::getRange, r -> this.range = r); + addDataSlot(rangeDataSlot); + + rangeVisibleDataSlot = new BooleanNetworkDataSlot(this::isRangeVisible, b -> this.rangeVisible = b); + addDataSlot(rangeVisibleDataSlot); + } + + + @Override + public @Nullable MachineInventoryLayout getInventoryLayout() { + return MachineInventoryLayout.builder() + .inputSlot(4, (slot, stack) -> acceptInput(stack)) + .slotAccess(INPUTS) + .setStackLimit(1) // Reset stack limit + .inputSlot((slot, stack) -> stack.getItem() instanceof HoeItem) + .slotAccess(HOE) + .inputSlot((slot, stack) -> stack.getItem() instanceof AxeItem) + .slotAccess(AXE) + .inputSlot((slot, stack) -> stack.getItem() instanceof ShearsItem) + .slotAccess(SHEARS) + .setStackLimit(64) // Reset stack limit + .inputSlot(2, (slot, stack) -> stack.getItem() instanceof BoneMealItem) + .slotAccess(FERTILIZERS) + .outputSlot(6) + .slotAccess(OUTPUT) + .capacitor() + .build(); + } + + @Override + protected boolean isActive() { + return false; + } + + @Override + public void serverTick() { + super.serverTick(); + if (canAct()) { + + completedTicks = (completedTicks + 1) % TICK_PER_OPERATION; + if (completedTicks == 0) { + if (counter < blocksInRange.size()) { + till(blocksInRange.get(counter).below()); + plant(blocksInRange.get(counter)); + boneMealBlock(); + waterSoil(); + collect(blocksInRange.get(counter)); + increasePointer(); + } + } + } else { + completedTicks = 0; + resetCounter(); + } + + } + + @Nullable + @Override + public AbstractContainerMenu createMenu(int pContainerId, Inventory pPlayerInventory, Player player) { + return new FarmingStationMenu(this, pPlayerInventory, pContainerId); + } + + @Override + protected @Nullable FluidTank createFluidTank() { + return new FluidTank(2000, f -> f.getFluid().is(FluidTags.WATER)); + } + + + + //region operations + + //Randomly choose a crop and apply bone meal on it + public void boneMealBlock() { + ItemStack boneMealItemStack = getFirstNonEmptyItemStack(FERTILIZERS); + if (!boneMealItemStack.equals(ItemStack.EMPTY) && getEnergyStorage().getEnergyStored() >= getEnergyStorage().getMaxEnergyUse()) { + Random random = new Random(); + int chosenCrop = random.nextInt(blocksInRange.size()); + BoneMealItem.applyBonemeal(boneMealItemStack, level, blocksInRange.get(chosenCrop), FakePlayerFactory.getMinecraft((net.minecraft.server.level.ServerLevel) level)); + } + } + + //Randomly makes farmland wet + public void waterSoil() { + Random random = new Random(); + int chosenBlock = random.nextInt(blocksInRange.size()); + + BlockPos pos = getBlocksInRange().get(chosenBlock); + BlockState blockState = level.getBlockState(pos.below()); + + if (blockState.getBlock().equals(Blocks.FARMLAND) + && GET_WATER_PER_OPERATION <= getFluidTank().getFluidAmount() + && getEnergyStorage().getEnergyStored() >= getEnergyStorage().getMaxEnergyUse() + ) { + this.level.setBlockAndUpdate(pos.below(), blockState.setValue(FarmBlock.MOISTURE, 7)); + getFluidTank().drain(GET_WATER_PER_OPERATION, IFluidHandler.FluidAction.EXECUTE); + } + } + + + public void till(BlockPos pos) { + ItemStack hoe = getInventory().getStackInSlot(HOE.getIndex()); + + if (!hoe.isEmpty() && getEnergyStorage().getEnergyStored() >= getEnergyStorage().getMaxEnergyUse()) { + BlockState blockState = level.getBlockState(pos); + if (blockState.getBlock().equals(Blocks.DIRT) || blockState.getBlock().equals(Blocks.GRASS_BLOCK)) { + this.level.setBlockAndUpdate(pos, Blocks.FARMLAND.defaultBlockState()); + level.playSound(null, pos, SoundEvents.HOE_TILL, SoundSource.BLOCKS, 1.0f, 1.0f); + hoe.hurt(1, level.getRandom(), null); + getEnergyStorage().consumeEnergy(getEnergyStorage().getMaxEnergyUse(), false); + } + } + } + + public void plant(BlockPos pos) { + ItemStack inputItemStack = getFirstNonEmptyItemStack(INPUTS); + + if (!inputItemStack.equals(ItemStack.EMPTY)) { + + //If an item is a crop or everything that can grow + if (inputItemStack.getItem() instanceof BlockItem && ((BlockItem) inputItemStack.getItem()).getBlock() instanceof IPlantable) { + Block block = ((BlockItem) inputItemStack.getItem()).getBlock(); + + //If the seed / sapling can be planted on the block + if (this.level.getBlockState(pos.below()).canSustainPlant(level, pos.below(), Direction.UP, (IPlantable) block) + && block.canSurvive(this.level.getBlockState(pos), this.getLevel(), pos)) { + + //If the block isn't already planted + if (this.level.getBlockState(pos).getBlock().equals(Blocks.AIR)) { + + //Plant it and update corresponding machine slots + if (this.level.setBlockAndUpdate(pos, ((IPlantable) block).getPlant(level, pos))) { + inputItemStack.shrink(1); + getEnergyStorage().consumeEnergy(getEnergyStorage().getMaxEnergyUse(), false); + } + } + } + } + } + } + + public void collect(BlockPos pos) { + Block block = getLevel().getBlockState(pos).getBlock(); + IFarmer farmer = null; + + //We look for the good operation to do + if (block instanceof CropBlock) + farmer = new PlantFarmer(); + else if (block instanceof PumpkinBlock || block instanceof MelonBlock) + farmer = new PumpkinFarmer(); + + + //If a block can be harvested, do the operation + if (farmer != null) { + List items = farmer.doOperation(getLevel(), pos, this.level.getBlockState(pos), true); + getEnergyStorage().consumeEnergy(farmer.getCostPerOperation(), false); + + boolean canOutput = canOutput(items); + + if (canOutput) { + farmer.doOperation(getLevel(), pos, this.level.getBlockState(pos), false); + for (ItemStack loot : items) { + + for (SingleSlotAccess outputSlot : OUTPUT.getAccesses()) { + + ItemStack simulated = outputSlot.insertItem(getInventory(), loot, true); + if (simulated.isEmpty()) { + outputSlot.insertItem(getInventory(), loot, false); + break; + } + } + } + } + } + } + + + public void increasePointer() { + this.counter = (counter + 1) % blocksInRange.size(); + } + + public void resetCounter() { + this.counter = 0; + } + + //endregion + + //region inventory update + + //Get all blocks that are around the farming station at the same y level (sometimes need to get pos.below) + List getBlocksInRange() { + BlockPos farmerPos = getBlockPos(); + + Stream blocks = BlockPos.betweenClosedStream(farmerPos.getX() - getRange(), farmerPos.getY(), farmerPos.getZ() - getRange(), + farmerPos.getX() + getRange(), farmerPos.getY(), farmerPos.getZ() + getRange()); + + return blocks + .map(BlockPos::immutable) + .distinct() + .collect(Collectors.toList()); + } + + public ItemStack getFirstNonEmptyItemStack(MultiSlotAccess slot) { + for (int i = 0; i < slot.size(); i++) { + ItemStack slotItemStack = slot.get(i).getItemStack(getInventory()); + if (slotItemStack.isEmpty()) { + return slot.get(i).getItemStack(getInventory()); + } + } + return ItemStack.EMPTY; + } + + + @Override + public int getRange() { + if (requiresCapacitor() && isCapacitorInstalled()) { + if (getCapacitorData().getBase() <= 1) + return 4; + else if (getCapacitorData().getBase() <= 2) + return 6; + else if (getCapacitorData().getBase() <= 3) + return 10; + } + return 0; + } + + @Override + public int getMaxRange() { + return 10; + } + + @Override + protected void onInventoryContentsChanged(int slot) { + super.onInventoryContentsChanged(slot); + setRange(getRange()); + blocksInRange = getBlocksInRange(); + } + + public boolean acceptInput(ItemStack stack) { + return stack.getItem() instanceof BlockItem && ((BlockItem) stack.getItem()).getBlock() instanceof IPlantable; + } + + public boolean canOutput(List items) { + boolean canOutput = true; + + for (ItemStack loot : items) { + canOutput = false; + + for (SingleSlotAccess outputSlot : OUTPUT.getAccesses()) { + + ItemStack simulated = outputSlot.insertItem(getInventory(), loot, true); + if (simulated.isEmpty()) { + canOutput = true; + break; + } + } + + if (!canOutput) + break; + } + + return canOutput; + } + //endregion +} \ No newline at end of file diff --git a/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/IFarmer.java b/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/IFarmer.java new file mode 100644 index 0000000000..17729236f3 --- /dev/null +++ b/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/IFarmer.java @@ -0,0 +1,39 @@ +package com.enderio.machines.common.blockentity.farming.farmers; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.NonNullList; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.List; + +public interface IFarmer { + + boolean canHarvest(Level level, BlockPos pos, BlockState blockState); + + default List doOperation(Level level, BlockPos pos, BlockState blockState, boolean simulate) { + NonNullList items = NonNullList.create(); + + if (canHarvest(level, pos, blockState)) { + items.addAll(Block.getDrops(blockState, (ServerLevel) level, pos, null)); + if (!simulate) { + level.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState()); + level.playSound(null, pos, getHarvestSound(), SoundSource.BLOCKS, 1.0f, 1.0f); + } + } + return items; + } + + default int getCostPerOperation() { + return 120; + } + SoundEvent getHarvestSound(); + +} diff --git a/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/PlantFarmer.java b/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/PlantFarmer.java new file mode 100644 index 0000000000..7bf4ce2e37 --- /dev/null +++ b/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/PlantFarmer.java @@ -0,0 +1,22 @@ +package com.enderio.machines.common.blockentity.farming.farmers; + +import net.minecraft.core.BlockPos; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.CropBlock; +import net.minecraft.world.level.block.NetherWartBlock; +import net.minecraft.world.level.block.state.BlockState; + +public class PlantFarmer implements IFarmer{ + + @Override + public boolean canHarvest(Level level, BlockPos pos, BlockState blockState) { + return level != null && blockState.getBlock() instanceof CropBlock && ((CropBlock) blockState.getBlock()).isMaxAge(blockState); + } + + @Override + public SoundEvent getHarvestSound() { + return SoundEvents.CROP_BREAK; + } +} diff --git a/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/PumpkinFarmer.java b/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/PumpkinFarmer.java new file mode 100644 index 0000000000..2a7d5930a9 --- /dev/null +++ b/src/machines/java/com/enderio/machines/common/blockentity/farming/farmers/PumpkinFarmer.java @@ -0,0 +1,22 @@ +package com.enderio.machines.common.blockentity.farming.farmers; + +import net.minecraft.core.BlockPos; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.MelonBlock; +import net.minecraft.world.level.block.PumpkinBlock; +import net.minecraft.world.level.block.state.BlockState; + +public class PumpkinFarmer implements IFarmer { + + @Override + public boolean canHarvest(Level level, BlockPos pos, BlockState blockState) { + return level != null && blockState.getBlock() instanceof PumpkinBlock || blockState.getBlock() instanceof MelonBlock; + } + + @Override + public SoundEvent getHarvestSound() { + return SoundEvents.WOOD_BREAK; + } +} diff --git a/src/machines/java/com/enderio/machines/common/init/MachineBlockEntities.java b/src/machines/java/com/enderio/machines/common/init/MachineBlockEntities.java index ecf5f3e1a6..12910a9f76 100644 --- a/src/machines/java/com/enderio/machines/common/init/MachineBlockEntities.java +++ b/src/machines/java/com/enderio/machines/common/init/MachineBlockEntities.java @@ -4,6 +4,7 @@ import com.enderio.machines.common.blockentity.*; import com.enderio.machines.common.blockentity.capacitorbank.CapacitorBankBlockEntity; import com.enderio.machines.common.blockentity.capacitorbank.CapacitorTier; +import com.enderio.machines.common.blockentity.farming.FarmingStationBlockEntity; import com.enderio.machines.common.blockentity.solar.SolarPanelBlockEntity; import com.enderio.machines.common.blockentity.solar.SolarPanelTier; import com.google.common.collect.ImmutableMap; @@ -63,6 +64,7 @@ public class MachineBlockEntities { public static final BlockEntityEntry PAINTING_MACHINE = register("painting_machine", PaintingMachineBlockEntity::new, MachineBlocks.PAINTING_MACHINE); public static final BlockEntityEntry POWERED_SPAWNER = register("powered_spawner", PoweredSpawnerBlockEntity::new, MachineBlocks.POWERED_SPAWNER); + public static final BlockEntityEntry FARMING_STATION = register("farming_station", FarmingStationBlockEntity::new, MachineBlocks.FARMING_STATION); public static final Map> SOLAR_PANELS = Util.make(() -> { Map> map = new HashMap<>(); diff --git a/src/machines/java/com/enderio/machines/common/init/MachineBlocks.java b/src/machines/java/com/enderio/machines/common/init/MachineBlocks.java index 92c90726f9..bb775371fb 100644 --- a/src/machines/java/com/enderio/machines/common/init/MachineBlocks.java +++ b/src/machines/java/com/enderio/machines/common/init/MachineBlocks.java @@ -123,6 +123,9 @@ public class MachineBlocks { .lang("Soul Binder") .register(); + public static final BlockEntry FARMING_STATION = machine("farming_station", () -> MachineBlockEntities.FARMING_STATION) + .register(); + public static final BlockEntry POWERED_SPAWNER = REGISTRATE .block("powered_spawner", properties -> new ProgressMachineBlock(properties, MachineBlockEntities.POWERED_SPAWNER)) .loot((l,t) -> MachinesLootTable.copyNBTSingleCap(l, t, "EntityStorage")) diff --git a/src/machines/java/com/enderio/machines/common/init/MachineMenus.java b/src/machines/java/com/enderio/machines/common/init/MachineMenus.java index 53b840b5bd..2fc49edd07 100644 --- a/src/machines/java/com/enderio/machines/common/init/MachineMenus.java +++ b/src/machines/java/com/enderio/machines/common/init/MachineMenus.java @@ -26,6 +26,7 @@ private MachineMenus() {} public static final MenuEntry CRAFTER = REGISTRATE.menu("crafter", CrafterMenu::factory, () -> CrafterScreen::new).register(); public static final MenuEntry WIRED_CHARGER = REGISTRATE.menu("wired_charger", WiredChargerMenu::factory, () -> WiredChargerScreen::new).register(); public static final MenuEntry PAINTING_MACHINE = REGISTRATE.menu("painting_machine", PaintingMachineMenu::factory, () -> PaintingMachineScreen::new).register(); + public static final MenuEntry FARMING_STATION = REGISTRATE.menu("farming_station", FarmingStationMenu::factory, () -> FarmingStationScreen::new).register(); public static final MenuEntry CAPACITOR_BANK = REGISTRATE .menu("capacitor_bank", CapacitorBankMenu::factory, () -> CapacitorBankScreen::new) .register(); diff --git a/src/machines/java/com/enderio/machines/common/menu/FarmingStationMenu.java b/src/machines/java/com/enderio/machines/common/menu/FarmingStationMenu.java new file mode 100644 index 0000000000..6384eda3dc --- /dev/null +++ b/src/machines/java/com/enderio/machines/common/menu/FarmingStationMenu.java @@ -0,0 +1,61 @@ +package com.enderio.machines.common.menu; + +import com.enderio.machines.common.blockentity.farming.FarmingStationBlockEntity; +import com.enderio.machines.common.init.MachineMenus; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.MenuType; +import net.minecraft.world.level.block.entity.BlockEntity; +import org.apache.logging.log4j.LogManager; +import org.jetbrains.annotations.Nullable; + +public class FarmingStationMenu extends MachineMenu { + + public static final ResourceLocation BLOCK_ATLAS = new ResourceLocation("textures/atlas/blocks.png"); + public static final ResourceLocation EMPTY_HOE = new ResourceLocation("item/empty_slot_hoe"); + public static final ResourceLocation EMPTY_AXE = new ResourceLocation("item/empty_slot_axe"); + public static final ResourceLocation EMPTY_SHEARS = new ResourceLocation("item/empty_slot_shears"); + public FarmingStationMenu(@Nullable FarmingStationBlockEntity blockEntity, Inventory inventory, int pContainerId) { + super(blockEntity, inventory, MachineMenus.FARMING_STATION.get(), pContainerId); + if (blockEntity != null) { + + addSlot(new MachineSlot(blockEntity.getInventory(), blockEntity.getCapacitorSlot(), 12 + 42, 60)); + + //Tool slots + addSlot(new MachineSlot(blockEntity.getInventory(), FarmingStationBlockEntity.HOE, 44 + 42, 19) + .setBackground(BLOCK_ATLAS, EMPTY_HOE)); + + addSlot(new MachineSlot(blockEntity.getInventory(), FarmingStationBlockEntity.AXE, 62 + 42, 19) + .setBackground(BLOCK_ATLAS, EMPTY_AXE)); + + addSlot(new MachineSlot(blockEntity.getInventory(), FarmingStationBlockEntity.SHEARS, 80 + 42, 19)); + + + //Bonemeal slots + for (int i = 0; i < 2; i++) { + addSlot(new MachineSlot(blockEntity.getInventory(), FarmingStationBlockEntity.FERTILIZERS.get(i), 116 + 42 + 18 * i, 19)); + } + + //Seed slots + for (int i = 0; i < 4; i++) { + addSlot(new MachineSlot(blockEntity.getInventory(), FarmingStationBlockEntity.INPUTS.get(i), 53 + 42 + 18 * (i % 2), i < 2 ? 44 : 62)); + } + + //Output, seeds / trees harvested + for (int i = 0; i < 6; i++) { + addSlot(new MachineSlot(blockEntity.getInventory(), FarmingStationBlockEntity.OUTPUT.get(i), 107 + 42 + 18 * (i % 3), i < 3 ? 44 : 62)); + } + } + addInventorySlots(8 + 42, 87); + } + + public static FarmingStationMenu factory(@Nullable MenuType pMenuType, int pContainerId, Inventory inventory, FriendlyByteBuf buf) { + BlockEntity entity = inventory.player.level().getBlockEntity(buf.readBlockPos()); + if (entity instanceof FarmingStationBlockEntity castBlockEntity) + return new FarmingStationMenu(castBlockEntity, inventory, pContainerId); + LogManager.getLogger().warn("couldn't find BlockEntity"); + return new FarmingStationMenu(null, inventory, pContainerId); + } + +} diff --git a/src/machines/resources/assets/enderio/models/block/farming_station.json b/src/machines/resources/assets/enderio/models/block/farming_station.json new file mode 100644 index 0000000000..2d6ea712a4 --- /dev/null +++ b/src/machines/resources/assets/enderio/models/block/farming_station.json @@ -0,0 +1,308 @@ +{ +"credit": "Designed by Henryloenwind with BDcraft Cubik PRO 0.95 Beta - http://bdcraft.net", +"textures": { + "farmSide": "enderio:block/farm_side", + "farmHatBottom": "enderio:block/farm_hat_bottom", + "farmCore": "enderio:block/farm_core", + "machineBottom": "enderio:block/machine_bottom", + "machineTop": "enderio:block/machine_top", + "farmBaseTop": "enderio:block/farm_base_top" +}, +"elements": [ +{ + "__comment": "base", + "from": [ 0.25, 0.25, 0.25 ], + "to": [ 15.75, 10.75, 15.75 ], + "faces": { + "down": { "uv": [ 15.74, 15.74, 0.26, 0.26 ], "texture": "#machineBottom", "cullface": "down" }, + "up": { "uv": [ 0.26, 0.26, 15.74, 15.74 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.26, 5.26, 15.74, 15.74 ], "texture": "#farmSide", "cullface": "north" }, + "south": { "uv": [ 0.26, 5.26, 15.74, 15.74 ], "texture": "#farmSide", "cullface": "south" }, + "west": { "uv": [ 0.26, 5.26, 15.74, 15.74 ], "texture": "#farmSide", "cullface": "west" }, + "east": { "uv": [ 0.26, 5.26, 15.74, 15.74 ], "texture": "#farmSide", "cullface": "east" } + } +}, +{ + "__comment": "top", + "from": [ 0.25, 15.25, 0 ], + "to": [ 15.75, 15.75, 16 ], + "faces": { + "down": { "uv": [ 15.74, 15.99, 0.26, 0.01 ], "texture": "#farmHatBottom" }, + "up": { "uv": [ 0.26, 0.01, 15.74, 15.99 ], "texture": "#machineTop", "cullface": "up" }, + "north": { "uv": [ 0.26, 0.26, 15.74, 0.74 ], "texture": "#farmSide", "cullface": "north" }, + "south": { "uv": [ 0.26, 0.26, 15.74, 0.74 ], "texture": "#farmSide", "cullface": "south" }, + "west": { "uv": [ 0.01, 0.26, 15.99, 0.74 ], "texture": "#farmSide", "cullface": "west" }, + "east": { "uv": [ 0.01, 0.26, 15.99, 0.74 ], "texture": "#farmSide", "cullface": "east" } + } +}, +{ + "__comment": "center", + "from": [ 3, 11, 3 ], + "to": [ 13, 15, 13 ], + "faces": { + "north": { "uv": [ 3.01, 1.01, 12.99, 4.99 ], "texture": "#farmCore" }, + "south": { "uv": [ 3.01, 1.01, 12.99, 4.99 ], "texture": "#farmCore" }, + "west": { "uv": [ 3.01, 1.01, 12.99, 4.99 ], "texture": "#farmCore" }, + "east": { "uv": [ 3.01, 1.01, 12.99, 4.99 ], "texture": "#farmCore" } + } +}, +{ + "__comment": "rod1", + "from": [ 1, 10.75, 1 ], + "to": [ 2, 15.25, 2 ], + "faces": { + "north": { "uv": [ 14.01, 0.76, 14.99, 5.24 ], "texture": "#farmSide" }, + "south": { "uv": [ 1.01, 0.76, 1.99, 5.24 ], "texture": "#farmSide" }, + "west": { "uv": [ 1.01, 0.76, 1.99, 5.24 ], "texture": "#farmSide" }, + "east": { "uv": [ 14.01, 0.76, 14.99, 5.24 ], "texture": "#farmSide" } + } +}, +{ + "__comment": "rod2", + "from": [ 14, 10.75, 1 ], + "to": [ 15, 15.25, 2 ], + "faces": { + "north": { "uv": [ 1.01, 0.76, 1.99, 5.24 ], "texture": "#farmSide" }, + "south": { "uv": [ 14.01, 0.76, 14.99, 5.24 ], "texture": "#farmSide" }, + "west": { "uv": [ 1.01, 0.76, 1.99, 5.24 ], "texture": "#farmSide" }, + "east": { "uv": [ 14.01, 0.76, 14.99, 5.24 ], "texture": "#farmSide" } + } +}, +{ + "__comment": "rod3", + "from": [ 14, 10.75, 14 ], + "to": [ 15, 15.25, 15 ], + "faces": { + "north": { "uv": [ 1.01, 0.76, 1.99, 5.24 ], "texture": "#farmSide" }, + "south": { "uv": [ 14.01, 0.76, 14.99, 5.24 ], "texture": "#farmSide" }, + "west": { "uv": [ 14.01, 0.76, 14.99, 5.24 ], "texture": "#farmSide" }, + "east": { "uv": [ 1.01, 0.76, 1.99, 5.24 ], "texture": "#farmSide" } + } +}, +{ + "__comment": "rod4", + "from": [ 1, 10.75, 14 ], + "to": [ 2, 15.25, 15 ], + "faces": { + "north": { "uv": [ 14.01, 0.76, 14.99, 5.24 ], "texture": "#farmSide" }, + "south": { "uv": [ 1.01, 0.76, 1.99, 5.24 ], "texture": "#farmSide" }, + "west": { "uv": [ 14.01, 0.76, 14.99, 5.24 ], "texture": "#farmSide" }, + "east": { "uv": [ 1.01, 0.76, 1.99, 5.24 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 10, 15 ], + "to": [ 16, 11, 16 ], + "faces": { + "down": { "uv": [ 15.99, 15.99, 0.01, 15.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 0.01, 15.01, 15.99, 15.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.01, 5.01, 15.99, 5.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 5.01, 15.99, 5.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 15.01, 5.01, 15.99, 5.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 0.01, 5.01, 0.99, 5.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 0, 15 ], + "to": [ 16, 1, 16 ], + "faces": { + "down": { "uv": [ 15.99, 15.99, 0.01, 15.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 0.01, 15.01, 15.99, 15.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.01, 15.01, 15.99, 15.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 15.01, 15.99, 15.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 15.01, 15.01, 15.99, 15.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 0.01, 15.01, 0.99, 15.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 0, 0 ], + "to": [ 16, 1, 1 ], + "faces": { + "down": { "uv": [ 15.99, 0.99, 0.01, 0.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 0.01, 0.01, 15.99, 0.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.01, 15.01, 15.99, 15.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 15.01, 15.99, 15.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 0.01, 15.01, 0.99, 15.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 15.01, 15.01, 15.99, 15.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 10, 0 ], + "to": [ 16, 11, 1 ], + "faces": { + "down": { "uv": [ 15.99, 0.99, 0.01, 0.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 0.01, 0.01, 15.99, 0.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.01, 5.01, 15.99, 5.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 5.01, 15.99, 5.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 0.01, 5.01, 0.99, 5.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 15.01, 5.01, 15.99, 5.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 15, 0, 1 ], + "to": [ 16, 1, 15 ], + "faces": { + "down": { "uv": [ 0.99, 14.99, 0.01, 1.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 15.01, 1.01, 15.99, 14.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.01, 15.01, 0.99, 15.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 15.01, 15.01, 15.99, 15.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 1.01, 15.01, 14.99, 15.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 1.01, 15.01, 14.99, 15.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 0, 1 ], + "to": [ 1, 1, 15 ], + "faces": { + "down": { "uv": [ 15.99, 14.99, 15.01, 1.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 0.01, 1.01, 0.99, 14.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 15.01, 15.01, 15.99, 15.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 15.01, 0.99, 15.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 1.01, 15.01, 14.99, 15.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 1.01, 15.01, 14.99, 15.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 10, 1 ], + "to": [ 1, 11, 15 ], + "faces": { + "down": { "uv": [ 15.99, 14.99, 15.01, 1.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 0.01, 1.01, 0.99, 14.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 15.01, 5.01, 15.99, 5.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 5.01, 0.99, 5.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 1.01, 5.01, 14.99, 5.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 1.01, 5.01, 14.99, 5.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 15, 10, 1 ], + "to": [ 16, 11, 15 ], + "faces": { + "down": { "uv": [ 0.99, 14.99, 0.01, 1.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 15.01, 1.01, 15.99, 14.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.01, 5.01, 0.99, 5.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 15.01, 5.01, 15.99, 5.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 1.01, 5.01, 14.99, 5.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 1.01, 5.01, 14.99, 5.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 15, 1, 15 ], + "to": [ 16, 10, 16 ], + "faces": { + "down": { "uv": [ 0.99, 15.99, 0.01, 15.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 15.01, 15.01, 15.99, 15.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.01, 6.01, 0.99, 14.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 15.01, 6.01, 15.99, 14.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 15.01, 6.01, 15.99, 14.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 0.01, 6.01, 0.99, 14.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 1, 15 ], + "to": [ 1, 10, 16 ], + "faces": { + "down": { "uv": [ 15.99, 15.99, 15.01, 15.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 0.01, 15.01, 0.99, 15.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 15.01, 6.01, 15.99, 14.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 6.01, 0.99, 14.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 15.01, 6.01, 15.99, 14.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 0.01, 6.01, 0.99, 14.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 15, 1, 0 ], + "to": [ 16, 10, 1 ], + "faces": { + "down": { "uv": [ 0.99, 0.99, 0.01, 0.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 15.01, 0.01, 15.99, 0.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 0.01, 6.01, 0.99, 14.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 15.01, 6.01, 15.99, 14.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 0.01, 6.01, 0.99, 14.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 15.01, 6.01, 15.99, 14.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 1, 0 ], + "to": [ 1, 10, 1 ], + "faces": { + "down": { "uv": [ 15.99, 0.99, 15.01, 0.01 ], "texture": "#machineBottom" }, + "up": { "uv": [ 0.01, 0.01, 0.99, 0.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 15.01, 6.01, 15.99, 14.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 6.01, 0.99, 14.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 0.01, 6.01, 0.99, 14.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 15.01, 6.01, 15.99, 14.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 1, 15, 15 ], + "to": [ 15, 16, 16 ], + "faces": { + "down": { "uv": [ 14.99, 15.99, 1.01, 15.01 ], "texture": "#farmHatBottom" }, + "up": { "uv": [ 1.01, 15.01, 14.99, 15.99 ], "texture": "#machineTop" }, + "north": { "uv": [ 1.01, 0.01, 14.99, 0.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 1.01, 0.01, 14.99, 0.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 15.01, 0.01, 15.99, 0.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 0.01, 0.01, 0.99, 0.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 1, 15, 0 ], + "to": [ 15, 16, 1 ], + "faces": { + "down": { "uv": [ 14.99, 0.99, 1.01, 0.01 ], "texture": "#farmHatBottom" }, + "up": { "uv": [ 1.01, 0.01, 14.99, 0.99 ], "texture": "#machineTop" }, + "north": { "uv": [ 1.01, 0.01, 14.99, 0.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 1.01, 0.01, 14.99, 0.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 0.01, 0.01, 0.99, 0.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 15.01, 0.01, 15.99, 0.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 15, 15, 0 ], + "to": [ 16, 16, 16 ], + "faces": { + "down": { "uv": [ 0.99, 15.99, 0.01, 0.01 ], "texture": "#farmHatBottom" }, + "up": { "uv": [ 15.01, 0.01, 15.99, 15.99 ], "texture": "#machineTop" }, + "north": { "uv": [ 0.01, 0.01, 0.99, 0.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 15.01, 0.01, 15.99, 0.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 0.01, 0.01, 15.99, 0.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 0.01, 0.01, 15.99, 0.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 0, 15, 0 ], + "to": [ 1, 16, 16 ], + "faces": { + "down": { "uv": [ 15.99, 15.99, 15.01, 0.01 ], "texture": "#farmHatBottom" }, + "up": { "uv": [ 0.01, 0.01, 0.99, 15.99 ], "texture": "#machineTop" }, + "north": { "uv": [ 15.01, 0.01, 15.99, 0.99 ], "texture": "#farmSide" }, + "south": { "uv": [ 0.01, 0.01, 0.99, 0.99 ], "texture": "#farmSide" }, + "west": { "uv": [ 0.01, 0.01, 15.99, 0.99 ], "texture": "#farmSide" }, + "east": { "uv": [ 0.01, 0.01, 15.99, 0.99 ], "texture": "#farmSide" } + } +}, +{ + "from": [ 2, 10.75, 2 ], + "to": [ 14, 11, 14 ], + "faces": { + "up": { "uv": [ 2.01, 2.01, 13.99, 13.99 ], "texture": "#farmBaseTop" }, + "north": { "uv": [ 2.01, 2.01, 13.99, 2.99 ], "texture": "#farmBaseTop" }, + "south": { "uv": [ 2.01, 13.01, 13.99, 13.99 ], "texture": "#farmBaseTop" }, + "west": { "uv": [ 2.01, 13.01, 13.99, 13.99 ], "texture": "#farmBaseTop" }, + "east": { "uv": [ 2.01, 2.01, 13.99, 2.99 ], "texture": "#farmBaseTop" } + } +}, +{ + "from": [ 2, 15, 2 ], + "to": [ 14, 15.25, 14 ], + "faces": { + "down": { "uv": [ 13.99, 13.99, 2.01, 2.01 ], "texture": "#farmHatBottom" }, + "north": { "uv": [ 2.01, 2.01, 13.99, 2.99 ], "texture": "#farmHatBottom" }, + "south": { "uv": [ 2.01, 13.01, 13.99, 13.99 ], "texture": "#farmHatBottom" }, + "west": { "uv": [ 2.01, 13.01, 13.99, 13.99 ], "texture": "#farmHatBottom" }, + "east": { "uv": [ 2.01, 2.01, 13.99, 2.99 ], "texture": "#farmHatBottom" } + } +} +] +} \ No newline at end of file diff --git a/src/machines/resources/assets/enderio/textures/block/farm_base_top.png b/src/machines/resources/assets/enderio/textures/block/farm_base_top.png new file mode 100644 index 0000000000..1785b2b9f8 Binary files /dev/null and b/src/machines/resources/assets/enderio/textures/block/farm_base_top.png differ diff --git a/src/machines/resources/assets/enderio/textures/block/farm_core.png b/src/machines/resources/assets/enderio/textures/block/farm_core.png new file mode 100644 index 0000000000..6ebf9ab693 Binary files /dev/null and b/src/machines/resources/assets/enderio/textures/block/farm_core.png differ diff --git a/src/machines/resources/assets/enderio/textures/block/farm_hat_bottom.png b/src/machines/resources/assets/enderio/textures/block/farm_hat_bottom.png new file mode 100644 index 0000000000..4259c7ad1d Binary files /dev/null and b/src/machines/resources/assets/enderio/textures/block/farm_hat_bottom.png differ diff --git a/src/machines/resources/assets/enderio/textures/block/farm_side.png b/src/machines/resources/assets/enderio/textures/block/farm_side.png new file mode 100644 index 0000000000..5fce227ef2 Binary files /dev/null and b/src/machines/resources/assets/enderio/textures/block/farm_side.png differ diff --git a/src/main/resources/assets/enderio/textures/gui/farm_station.png b/src/main/resources/assets/enderio/textures/gui/farm_station.png deleted file mode 100644 index 8bb36ed64a..0000000000 Binary files a/src/main/resources/assets/enderio/textures/gui/farm_station.png and /dev/null differ diff --git a/src/main/resources/assets/enderio/textures/gui/farming_station.png b/src/main/resources/assets/enderio/textures/gui/farming_station.png new file mode 100644 index 0000000000..f628239389 Binary files /dev/null and b/src/main/resources/assets/enderio/textures/gui/farming_station.png differ