diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/BlockAutoCrafter.java b/src/main/java/de/ellpeck/naturesaura/blocks/BlockAutoCrafter.java new file mode 100644 index 00000000..1053cc99 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/BlockAutoCrafter.java @@ -0,0 +1,43 @@ +package de.ellpeck.naturesaura.blocks; + +import de.ellpeck.naturesaura.blocks.tiles.TileEntityAutoCrafter; +import net.minecraft.block.BlockHorizontal; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.block.properties.PropertyDirection; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class BlockAutoCrafter extends BlockContainerImpl { + public static final PropertyDirection FACING = BlockHorizontal.FACING; + + public BlockAutoCrafter() { + super(Material.WOOD, "auto_crafter", TileEntityAutoCrafter.class, "auto_crafter"); + this.setSoundType(SoundType.WOOD); + this.setHardness(1.5F); + } + + @Override + protected BlockStateContainer createBlockState() { + return new BlockStateContainer(this, FACING); + } + + @Override + public int getMetaFromState(IBlockState state) { + return state.getValue(FACING).getHorizontalIndex(); + } + + @Override + public IBlockState getStateFromMeta(int meta) { + return this.getDefaultState().withProperty(FACING, EnumFacing.byHorizontalIndex(meta)); + } + + @Override + public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) { + return this.getDefaultState().withProperty(FACING, placer.getHorizontalFacing()); + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java index 89c10523..5bdb4251 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/ModBlocks.java @@ -41,4 +41,5 @@ public final class ModBlocks { public static final Block END_FLOWER = new BlockEndFlower(); public static final Block GRATED_CHUTE = new BlockGratedChute(); public static final Block ANIMAL_SPAWNER = new BlockAnimalSpawner(); + public static final Block AUTO_CRAFTER = new BlockAutoCrafter(); } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblocks.java b/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblocks.java index 96b0a5ab..78f9648f 100644 --- a/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblocks.java +++ b/src/main/java/de/ellpeck/naturesaura/blocks/multi/Multiblocks.java @@ -73,4 +73,12 @@ public final class Multiblocks { 'W', ModBlocks.ANCIENT_PLANKS, '0', ModBlocks.ANIMAL_SPAWNER, ' ', Matcher.wildcard()); + public static final IMultiblock AUTO_CRAFTER = NaturesAuraAPI.instance().createMultiblock( + new ResourceLocation(NaturesAura.MOD_ID, "auto_crafter"), + new String[][]{ + {"PPPPPPP", "PLPLPLP", "PPPPPPP", "PLP0PLP", "PPPPPPP", "PLPLPLP", "PPPPPPP"}}, + 'P', ModBlocks.ANCIENT_PLANKS, + 'L', ModBlocks.ANCIENT_LOG, + '0', ModBlocks.AUTO_CRAFTER, + ' ', Matcher.wildcard()); } diff --git a/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityAutoCrafter.java b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityAutoCrafter.java new file mode 100644 index 00000000..fde2daf0 --- /dev/null +++ b/src/main/java/de/ellpeck/naturesaura/blocks/tiles/TileEntityAutoCrafter.java @@ -0,0 +1,104 @@ +package de.ellpeck.naturesaura.blocks.tiles; + +import de.ellpeck.naturesaura.blocks.BlockAutoCrafter; +import de.ellpeck.naturesaura.blocks.multi.Multiblocks; +import de.ellpeck.naturesaura.packet.PacketHandler; +import de.ellpeck.naturesaura.packet.PacketParticles; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.Container; +import net.minecraft.inventory.InventoryCrafting; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.CraftingManager; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.EntitySelectors; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ITickable; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; + +import java.util.List; + +public class TileEntityAutoCrafter extends TileEntityImpl implements ITickable { + public final InventoryCrafting crafting = new InventoryCrafting(new Container() { + @Override + public boolean canInteractWith(EntityPlayer playerIn) { + return false; + } + }, 3, 3); + + + @Override + public void update() { + if (!this.world.isRemote) { + if (this.world.getTotalWorldTime() % 60 != 0) + return; + if (!Multiblocks.AUTO_CRAFTER.isComplete(this.world, this.pos)) + return; + this.crafting.clear(); + + IBlockState state = this.world.getBlockState(this.pos); + EnumFacing facing = state.getValue(BlockAutoCrafter.FACING); + BlockPos middlePos = this.pos.up(); + BlockPos topPos = middlePos.offset(facing, 2); + BlockPos bottomPos = middlePos.offset(facing.getOpposite(), 2); + BlockPos[] poses = new BlockPos[]{ + topPos.offset(facing.rotateYCCW(), 2), + topPos, + topPos.offset(facing.rotateY(), 2), + middlePos.offset(facing.rotateYCCW(), 2), + middlePos, + middlePos.offset(facing.rotateY(), 2), + bottomPos.offset(facing.rotateYCCW(), 2), + bottomPos, + bottomPos.offset(facing.rotateY(), 2) + }; + + EntityItem[] items = new EntityItem[9]; + for (int i = 0; i < poses.length; i++) { + List entities = this.world.getEntitiesWithinAABB( + EntityItem.class, new AxisAlignedBB(poses[i]).grow(0.25), EntitySelectors.IS_ALIVE); + if (entities.size() > 1) + return; + if (entities.isEmpty()) + continue; + EntityItem entity = entities.get(0); + if (entity.cannotPickup()) + return; + ItemStack stack = entity.getItem(); + if (stack.isEmpty()) + return; + items[i] = entity; + this.crafting.setInventorySlotContents(i, stack.copy()); + } + + IRecipe recipe = CraftingManager.findMatchingRecipe(this.crafting, this.world); + if (recipe == null) + return; + + ItemStack result = recipe.getCraftingResult(this.crafting); + if (result.isEmpty()) + return; + EntityItem resultItem = new EntityItem(this.world, + this.pos.getX() + 0.5F, this.pos.getY() - 0.35F, this.pos.getZ() + 0.5F, result.copy()); + resultItem.motionX = resultItem.motionY = resultItem.motionZ = 0; + this.world.spawnEntity(resultItem); + + for (EntityItem item : items) { + if (item == null) + continue; + ItemStack stack = item.getItem(); + if (stack.getCount() <= 1) + item.setDead(); + else { + stack.shrink(1); + item.setItem(stack); + } + + PacketHandler.sendToAllAround(this.world, this.pos, 32, + new PacketParticles((float) item.posX, (float) item.posY, (float) item.posZ, 19)); + } + } + } +} diff --git a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java index 3ee4cb15..6aadbe6a 100644 --- a/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java +++ b/src/main/java/de/ellpeck/naturesaura/packet/PacketParticles.java @@ -312,7 +312,7 @@ public class PacketParticles implements IMessage { world.rand.nextGaussian() * 0.01F, color, 1.5F, 80, 0F, true, true); break; - case 19: // Animal spawner + case 19: // Animal spawner, auto crafter for (int i = world.rand.nextInt(20) + 10; i >= 0; i--) NaturesAuraAPI.instance().spawnMagicParticle( message.posX, message.posY + 0.5F, message.posZ, diff --git a/src/main/resources/assets/naturesaura/blockstates/auto_crafter.json b/src/main/resources/assets/naturesaura/blockstates/auto_crafter.json new file mode 100644 index 00000000..252b5679 --- /dev/null +++ b/src/main/resources/assets/naturesaura/blockstates/auto_crafter.json @@ -0,0 +1,32 @@ +{ + "forge_marker": 1, + "defaults": { + "model": "minecraft:cube", + "textures": { + "particle": "naturesaura:blocks/auto_crafter", + "up": "naturesaura:blocks/auto_crafter_top", + "north": "#particle", + "east": "#particle", + "west": "#particle", + "down": "naturesaura:blocks/auto_crafter_bottom", + "south": "#particle" + }, + "transform": "forge:default-block" + }, + "variants": { + "normal": [{}], + "inventory": [{}], + "facing": { + "north": {}, + "south": { + "y": 180 + }, + "west": { + "y": 270 + }, + "east": { + "y": 90 + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/naturesaura/lang/en_US.lang b/src/main/resources/assets/naturesaura/lang/en_US.lang index 0b1a60af..695ec11f 100644 --- a/src/main/resources/assets/naturesaura/lang/en_US.lang +++ b/src/main/resources/assets/naturesaura/lang/en_US.lang @@ -38,6 +38,7 @@ tile.naturesaura.animal_generator.name=Disentangler of Mortals tile.naturesaura.end_flower.name=Rose of Oblivion tile.naturesaura.grated_chute.name=Adept Hopper tile.naturesaura.animal_spawner.name=Altar of Birthing +tile.naturesaura.auto_crafter.name=Automatic Constructor item.naturesaura.eye.name=Environmental Eye item.naturesaura.eye_improved.name=Environmental Ocular diff --git a/src/main/resources/assets/naturesaura/patchouli_books/book/en_us/entries/devices/auto_crafter.json b/src/main/resources/assets/naturesaura/patchouli_books/book/en_us/entries/devices/auto_crafter.json new file mode 100644 index 00000000..b27cbf65 --- /dev/null +++ b/src/main/resources/assets/naturesaura/patchouli_books/book/en_us/entries/devices/auto_crafter.json @@ -0,0 +1,26 @@ +{ + "name": "Automatic Constructor", + "icon": "naturesaura:auto_crafter", + "category": "devices", + "advancement": "naturesaura:sky_ingot", + "pages": [ + { + "type": "text", + "text": "A big part of any botanist's life is the $(thing)construction$() of items, specifically in a $(item)Crafting Table$(). This, however, can easily become tedious and time consuming, especially for recipes that are created and used on a regular basis. For this, the $(item)Automatic Constructor$() comes in handy: It will create, without the help of anyone required, any item that can regularly be made by crafting." + }, + { + "type": "text", + "text": "To achieve this, first, the $(thing)structure$() on the following page has to be constructed with the $(item)Automatic Constructor$() in the center. When placed, the facing of the arrow indicates the $(thing)top of the recipe$(), as if pointing to the uppermost row of slots in a $(item)Crafting Table$(). The required ingredients then have to be dropped on the $(item)Ancient Logs$() in their normal configuration. Once in place, after a couple of seconds, the resulting item will drop out of $(thing)the bottom$() of the $(item)Automatic Constructor$()." + }, + { + "type": "multiblock", + "multiblock_id": "naturesaura:auto_crafter", + "text": "Creating the structure required for the automatic crafting process" + }, + { + "type": "crafting", + "text": "Creating the $(item)Automatic Constructor$()", + "recipe": "naturesaura:auto_crafter" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/naturesaura/recipes/auto_crafter.json b/src/main/resources/assets/naturesaura/recipes/auto_crafter.json new file mode 100644 index 00000000..b59cd692 --- /dev/null +++ b/src/main/resources/assets/naturesaura/recipes/auto_crafter.json @@ -0,0 +1,29 @@ +{ + "type": "forge:ore_shaped", + "pattern": [ + "AWA", + "ACA", + "ASA" + ], + "key": { + "C": { + "item": "minecraft:crafting_table" + }, + "S": { + "item": "naturesaura:sky_ingot" + }, + "A": { + "item": "naturesaura:ancient_planks" + }, + "W": { + "type": "minecraft:item_nbt", + "item": "naturesaura:aura_bottle", + "nbt": { + "stored_type": "naturesaura:end" + } + } + }, + "result": { + "item": "naturesaura:auto_crafter" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter.png b/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter.png new file mode 100644 index 00000000..43a481c6 Binary files /dev/null and b/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter.png differ diff --git a/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter_bottom.png b/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter_bottom.png new file mode 100644 index 00000000..7b28d803 Binary files /dev/null and b/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter_bottom.png differ diff --git a/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter_top.png b/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter_top.png new file mode 100644 index 00000000..cc3a755f Binary files /dev/null and b/src/main/resources/assets/naturesaura/textures/blocks/auto_crafter_top.png differ