diff --git a/build.gradle b/build.gradle index e66ab076d..104fc1a73 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ archivesBaseName = 'create' sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' minecraft { - mappings channel: 'snapshot', version: '20191021-1.14.3' + mappings channel: 'snapshot', version: '20191107-1.14.3' runs { client { @@ -71,7 +71,7 @@ repositories { } dependencies { - minecraft 'net.minecraftforge:forge:1.14.4-28.1.61' + minecraft 'net.minecraftforge:forge:1.14.4-28.1.85' // compile against the JEI API but do not include it at runtime compileOnly fg.deobf("mezz.jei:jei-1.14.4:6.0.0.10:api") diff --git a/src/main/java/com/simibubi/create/Create.java b/src/main/java/com/simibubi/create/Create.java index 653e1e745..8e571000c 100644 --- a/src/main/java/com/simibubi/create/Create.java +++ b/src/main/java/com/simibubi/create/Create.java @@ -56,6 +56,9 @@ public class Create { modEventBus.addGenericListener(IRecipeSerializer.class, Create::registerRecipes); modEventBus.addGenericListener(TileEntityType.class, Create::registerTileEntities); modEventBus.addGenericListener(ContainerType.class, Create::registerContainers); + modEventBus.addGenericListener(VillagerProfession.class, Create::registerVillagerProfessions); + modEventBus.addGenericListener(PointOfInterestType.class, Create::registerPointsOfInterest); + modEventBus.addGenericListener(EntityType.class, Create::registerEntities); modEventBus.addListener(Create::createConfigs); CreateClient.addListeners(modEventBus); @@ -95,12 +98,10 @@ public class Create { AllRecipes.register(event); } - @SubscribeEvent public static void registerEntities(final RegistryEvent.Register> event) { AllEntities.register(event); } - @SubscribeEvent public static void registerVillagerProfessions(RegistryEvent.Register event) { LogisticianHandler.registerVillagerProfessions(event); } @@ -110,7 +111,6 @@ public class Create { LogisticianHandler.registerPointsOfInterest(event); } - @SubscribeEvent public static void createConfigs(ModConfig.ModConfigEvent event) { if (event.getConfig().getSpec() == CreateConfig.specification) config = event.getConfig(); diff --git a/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java b/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java index c5cd0aec3..84c5b77ce 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java +++ b/src/main/java/com/simibubi/create/foundation/utility/TreeCutter.java @@ -66,8 +66,8 @@ public class TreeCutter { visited.add(currentPos); BlockState blockState = reader.getBlockState(currentPos); - boolean isLog = !isLog(blockState); - boolean isLeaf = !isLeaf(blockState); + boolean isLog = isLog(blockState); + boolean isLeaf = isLeaf(blockState); if (!isLog && !isLeaf) continue; @@ -108,7 +108,7 @@ public class TreeCutter { if (!isLog(reader.getBlockState(currentPos))) continue; - if (isLog(reader.getBlockState(currentPos.down()))) + if (!pos.equals(currentPos.down()) && isLog(reader.getBlockState(currentPos.down()))) return false; for (Direction direction : Direction.values()) { @@ -127,7 +127,7 @@ public class TreeCutter { private static void addNeighbours(BlockPos pos, List frontier, Set visited) { BlockPos.getAllInBox(pos.add(-1, -1, -1), pos.add(1, 1, 1)).filter(Predicates.not(visited::contains)) - .forEach(frontier::add); + .forEach(p -> frontier.add(new BlockPos(p))); } private static boolean isLog(BlockState state) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java index e3bb21e9c..f678ae385 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/base/KineticTileEntityRenderer.java @@ -37,7 +37,7 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast cachedBuffers; public static boolean rainbowMode = false; - protected static class BlockModelSpinner extends BufferManipulator { + public static class BlockModelSpinner extends BufferManipulator { public BlockModelSpinner(ByteBuffer original) { super(original); @@ -78,14 +78,19 @@ public class KineticTileEntityRenderer extends TileEntityRendererFast recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CRUSHING, contents, + Optional recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CRUSHING, inventory, world); if (recipe.isPresent()) { - int rolls = contents.getStackInSlot(0).getCount(); - contents.clear(); + int rolls = inventory.getStackInSlot(0).getCount(); + inventory.clear(); for (int roll = 0; roll < rolls; roll++) { List rolledResults = recipe.get().rollResults(); @@ -153,8 +153,8 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen for (int i = 0; i < rolledResults.size(); i++) { ItemStack stack = rolledResults.get(i); - for (int slot = 0; slot < contents.getSizeInventory(); slot++) { - stack = contents.getItems().insertItem(slot, stack, false); + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { + stack = inventory.getItems().insertItem(slot, stack, false); if (stack.isEmpty()) break; @@ -163,7 +163,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen } } else { - contents.clear(); + inventory.clear(); } } @@ -172,7 +172,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen public CompoundNBT write(CompoundNBT compound) { if (hasEntity() && !isFrozen()) compound.put("Entity", NBTUtil.writeUniqueId(entityUUID)); - contents.write(compound); + inventory.write(compound); compound.putFloat("Speed", crushingspeed); return super.write(compound); @@ -187,7 +187,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen this.searchForEntity = true; } crushingspeed = compound.getFloat("Speed"); - contents = ProcessingInventory.read(compound); + inventory = ProcessingInventory.read(compound); } @@ -197,13 +197,13 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen } private void insertItem(ItemEntity entity) { - contents.clear(); - contents.setInventorySlotContents(0, entity.getItem()); - Optional recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CRUSHING, contents, + inventory.clear(); + inventory.setInventorySlotContents(0, entity.getItem()); + Optional recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CRUSHING, inventory, world); - contents.processingDuration = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100; - contents.appliedRecipe = false; + inventory.remainingTime = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100; + inventory.appliedRecipe = false; } public void clear() { @@ -212,7 +212,7 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen } public boolean isOccupied() { - return hasEntity() || !contents.isEmpty(); + return hasEntity() || !inventory.isEmpty(); } public boolean hasEntity() { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java index 8c66ebcd3..4906d93c4 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/ProcessingInventory.java @@ -8,7 +8,8 @@ import net.minecraftforge.items.ItemStackHandler; import net.minecraftforge.items.wrapper.RecipeWrapper; public class ProcessingInventory extends RecipeWrapper { - protected int processingDuration; + protected int remainingTime; + protected int recipeDuration; protected boolean appliedRecipe; public ProcessingInventory() { @@ -18,7 +19,8 @@ public class ProcessingInventory extends RecipeWrapper { @Override public void clear() { super.clear(); - processingDuration = 0; + remainingTime = 0; + recipeDuration = 0; appliedRecipe = false; } @@ -29,7 +31,8 @@ public class ProcessingInventory extends RecipeWrapper { stacks.add(stack); } ItemStackHelper.saveAllItems(nbt, stacks); - nbt.putInt("ProcessingTime", processingDuration); + nbt.putInt("ProcessingTime", remainingTime); + nbt.putInt("RecipeTime", recipeDuration); nbt.putBoolean("AppliedRecipe", appliedRecipe); } @@ -40,7 +43,8 @@ public class ProcessingInventory extends RecipeWrapper { for (int slot = 0; slot < stacks.size(); slot++) inventory.setInventorySlotContents(slot, stacks.get(slot)); - inventory.processingDuration = nbt.getInt("ProcessingTime"); + inventory.remainingTime = nbt.getInt("ProcessingTime"); + inventory.recipeDuration = nbt.getInt("RecipeTime"); inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe"); return inventory; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawBlock.java index 84c2c4c93..c4015e7b8 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawBlock.java @@ -4,6 +4,7 @@ import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.utility.VoxelShapers; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.receivers.constructs.IHaveMovementBehavior; +import com.simibubi.create.modules.logistics.block.IBlockWithFilter; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -11,6 +12,8 @@ import net.minecraft.block.Blocks; import net.minecraft.block.material.PushReaction; import net.minecraft.entity.Entity; import net.minecraft.entity.item.ItemEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.InventoryHelper; import net.minecraft.item.BlockItemUseContext; import net.minecraft.state.BooleanProperty; import net.minecraft.state.StateContainer.Builder; @@ -18,17 +21,20 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.DamageSource; import net.minecraft.util.Direction; +import net.minecraft.util.Hand; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; import net.minecraft.world.World; public class SawBlock extends DirectionalAxisKineticBlock - implements IWithTileEntity, IHaveMovementBehavior { + implements IWithTileEntity, IHaveMovementBehavior, IBlockWithFilter { public static final BooleanProperty RUNNING = BooleanProperty.create("running"); public static DamageSource damageSourceSaw = new DamageSource("create.saw").setDamageBypassesArmor(); @@ -38,6 +44,12 @@ public class SawBlock extends DirectionalAxisKineticBlock setDefaultState(getDefaultState().with(RUNNING, false)); } + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + return handleActivatedFilterSlots(state, worldIn, pos, player, handIn, hit); + } + @Override public BlockRenderLayer getRenderLayer() { return BlockRenderLayer.CUTOUT_MIPPED; @@ -92,7 +104,7 @@ public class SawBlock extends DirectionalAxisKineticBlock if (!(entityIn instanceof ItemEntity)) return; withTileEntityDo(entityIn.world, entityIn.getPosition(), te -> { - + te.insertItem((ItemEntity) entityIn); }); } @@ -116,4 +128,44 @@ public class SawBlock extends DirectionalAxisKineticBlock : super.hasShaftTowards(world, pos, state, face); } + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + if (worldIn.getTileEntity(pos) == null) + return; + + if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { + withTileEntityDo(worldIn, pos, te -> { + for (int slot = 0; slot < te.inventory.getSizeInventory(); slot++) { + InventoryHelper.spawnItemStack(worldIn, pos.getX(), pos.getY(), pos.getZ(), + te.inventory.getStackInSlot(slot)); + } + }); + + worldIn.removeTileEntity(pos); + } + + } + + @Override + public Vec3d getFilterPosition(BlockState state) { + Vec3d x = new Vec3d(8f / 16f, 12.5f / 16f + 1f/256f, 12.25f / 16f); + Vec3d z = new Vec3d(12.25f / 16f, 12.5f / 16f + 1f/256f, 8f / 16f); + return state.get(AXIS_ALONG_FIRST_COORDINATE) ? z : x; + } + + @Override + public float getFilterAngle(BlockState state) { + return 0; + } + + @Override + public boolean isFilterVisible(BlockState state) { + return state.get(FACING) == Direction.UP; + } + + @Override + public Direction getFilterFacing(BlockState state) { + return state.get(AXIS_ALONG_FIRST_COORDINATE) ? Direction.EAST : Direction.SOUTH; + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java index c63007490..623a254f9 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntity.java @@ -2,21 +2,49 @@ package com.simibubi.create.modules.contraptions.receivers; import static com.simibubi.create.modules.contraptions.receivers.SawBlock.RUNNING; -import java.util.Optional; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; import com.simibubi.create.AllRecipes; import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; +import com.simibubi.create.modules.logistics.block.IHaveFilter; import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.BlockItem; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.item.crafting.StonecuttingRecipe; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.particles.BlockParticleData; +import net.minecraft.particles.IParticleData; +import net.minecraft.particles.ItemParticleData; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.Direction; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; -public class SawTileEntity extends KineticTileEntity { +public class SawTileEntity extends KineticTileEntity implements IHaveFilter { public ProcessingInventory inventory; + private int recipeIndex; + private ItemStack filter; public SawTileEntity() { super(AllTileEntities.SAW.type); inventory = new ProcessingInventory(); + inventory.remainingTime = -1; + filter = ItemStack.EMPTY; + recipeIndex = 0; + } + + @Override + public boolean hasFastRenderer() { + return false; } @Override @@ -24,26 +52,198 @@ public class SawTileEntity extends KineticTileEntity { boolean shouldRun = Math.abs(getSpeed()) > 1 / 64f; boolean running = getBlockState().get(RUNNING); if (shouldRun != running) - world.setBlockState(pos, getBlockState().with(RUNNING, shouldRun)); + world.setBlockState(pos, getBlockState().with(RUNNING, shouldRun), 2 | 16); + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + inventory.write(compound); + compound.put("Filter", filter.write(new CompoundNBT())); + compound.putInt("RecipeIndex", recipeIndex); + return super.write(compound); + } + + @Override + public void read(CompoundNBT compound) { + super.read(compound); + inventory = ProcessingInventory.read(compound); + recipeIndex = compound.getInt("RecipeIndex"); + filter = ItemStack.read(compound.getCompound("Filter")); } @Override public void tick() { super.tick(); + if (!canProcess()) + return; + if (getSpeed() == 0) + return; + if (inventory.remainingTime == -1) + return; + + float processingSpeed = MathHelper.clamp(Math.abs(getSpeed()) / 32, 1, 128); + inventory.remainingTime -= processingSpeed; + spawnParticles(inventory.getStackInSlot(0)); + + if (world.isRemote) + return; + + if (inventory.remainingTime < 20 && !inventory.appliedRecipe) { + applyRecipe(); + inventory.appliedRecipe = true; + sendData(); + return; + } + + Vec3d outPos = VecHelper.getCenterOf(pos).add(getItemMovementVec().scale(.5f).add(0, .5, 0)); + Vec3d outMotion = getItemMovementVec().scale(.0625).add(0, .125, 0); + + if (inventory.remainingTime <= 0) { + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { + ItemStack stack = inventory.getStackInSlot(slot); + if (stack.isEmpty()) + continue; + ItemEntity entityIn = new ItemEntity(world, outPos.x, outPos.y, outPos.z, stack); + entityIn.setMotion(outMotion); + world.addEntity(entityIn); + } + inventory.clear(); + inventory.remainingTime = -1; + sendData(); + return; + } + + return; + } + + protected void spawnParticles(ItemStack stack) { + if (stack == null || stack.isEmpty()) + return; + + IParticleData particleData = null; + float speed = 1; + if (stack.getItem() instanceof BlockItem) + particleData = new BlockParticleData(ParticleTypes.BLOCK, + ((BlockItem) stack.getItem()).getBlock().getDefaultState()); + else { + particleData = new ItemParticleData(ParticleTypes.ITEM, stack); + speed = .125f; + } + + Random r = world.rand; + Vec3d vec = getItemMovementVec(); + Vec3d pos = VecHelper.getCenterOf(this.pos); + float offset = inventory.recipeDuration != 0 ? (float) (inventory.remainingTime) / inventory.recipeDuration : 0; + offset -= .5f; + world.addParticle(particleData, pos.getX() + -vec.x * offset, pos.getY() + .45f, pos.getZ() + -vec.z * offset, + vec.x * speed, r.nextFloat() * speed, vec.z * speed); + } + + public Vec3d getItemMovementVec() { + boolean alongX = !getBlockState().get(SawBlock.AXIS_ALONG_FIRST_COORDINATE); + int offset = getSpeed() < 0 ? -1 : 1; + return new Vec3d(offset * (alongX ? 1 : 0), 0, offset * (alongX ? 0 : -1)); + } + + private void applyRecipe() { + List> recipes = getRecipes(); + if (recipes.isEmpty()) + return; + if (recipeIndex >= recipes.size()) + recipeIndex = 0; + + IRecipe recipe = recipes.get(recipeIndex); + + int rolls = inventory.getStackInSlot(0).getCount(); + inventory.clear(); + + for (int roll = 0; roll < rolls; roll++) { + List results = new LinkedList(); + if (recipe instanceof CuttingRecipe) + results = ((CuttingRecipe) recipe).rollResults(); + else if (recipe instanceof StonecuttingRecipe) + results.add(recipe.getRecipeOutput().copy()); + + for (int i = 0; i < results.size(); i++) { + ItemStack stack = results.get(i); + + for (int slot = 0; slot < inventory.getSizeInventory(); slot++) { + stack = inventory.getItems().insertItem(slot, stack, false); + + if (stack.isEmpty()) + break; + } + } + } } + private List> getRecipes() { + List> recipes = world.getRecipeManager().getRecipes().parallelStream() + .filter(r -> r.getType() == IRecipeType.STONECUTTING || r.getType() == AllRecipes.Types.CUTTING) + .filter(r -> filter.isEmpty() || ItemStack.areItemsEqual(filter, r.getRecipeOutput())) + .filter(r -> !r.getIngredients().isEmpty() + && r.getIngredients().get(0).test(inventory.getStackInSlot(0))) + .collect(Collectors.toList()); + return recipes; + } + public void insertItem(ItemEntity entity) { + if (!canProcess()) + return; if (!inventory.isEmpty()) return; + if (world.isRemote) + return; inventory.clear(); inventory.setInventorySlotContents(0, entity.getItem().copy()); - Optional recipe = world.getRecipeManager().getRecipe(AllRecipes.Types.CUTTING, inventory, world); - inventory.processingDuration = recipe.isPresent() ? recipe.get().getProcessingDuration() : 100; + List> recipes = getRecipes(); + boolean valid = !recipes.isEmpty(); + int time = 100; + + if (recipes.isEmpty()) { + inventory.remainingTime = inventory.recipeDuration = 10; + inventory.appliedRecipe = false; + entity.remove(); + sendData(); + return; + } + + if (valid) { + recipeIndex++; + if (recipeIndex >= recipes.size()) + recipeIndex = 0; + } + + IRecipe recipe = recipes.get(recipeIndex); + if (recipe instanceof CuttingRecipe) { + time = ((CuttingRecipe) recipe).getProcessingDuration(); + } + + inventory.remainingTime = time * Math.max(1, (entity.getItem().getCount() / 5)); + inventory.recipeDuration = inventory.remainingTime; inventory.appliedRecipe = false; entity.remove(); + + sendData(); + } + + protected boolean canProcess() { + return getBlockState().get(SawBlock.FACING) == Direction.UP; + } + + @Override + public void setFilter(ItemStack stack) { + filter = stack.copy(); + markDirty(); + sendData(); + } + + @Override + public ItemStack getFilter() { + return filter; } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntityRenderer.java index 83b67b487..5a2a075d1 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/SawTileEntityRenderer.java @@ -3,16 +3,87 @@ package com.simibubi.create.modules.contraptions.receivers; import static net.minecraft.state.properties.BlockStateProperties.AXIS; import static net.minecraft.state.properties.BlockStateProperties.FACING; +import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.utility.TessellatorHelper; import com.simibubi.create.modules.contraptions.base.IRotate; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; +import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer.BlockModelSpinner; +import com.simibubi.create.modules.logistics.block.FilteredTileEntityRenderer; import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.model.IBakedModel; +import net.minecraft.client.renderer.model.ItemCameraTransforms; +import net.minecraft.client.renderer.tileentity.TileEntityRenderer; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.BlockPos; -public class SawTileEntityRenderer extends KineticTileEntityRenderer { +@SuppressWarnings("deprecation") +public class SawTileEntityRenderer extends TileEntityRenderer { + FilteredTileEntityRenderer filterRenderer; + + public SawTileEntityRenderer() { + filterRenderer = new FilteredTileEntityRenderer(); + } + @Override + public void render(SawTileEntity te, double x, double y, double z, float partialTicks, int destroyStage) { + super.render(te, x, y, z, partialTicks, destroyStage); + + boolean processingMode = te.getBlockState().get(SawBlock.FACING) == Direction.UP; + if (processingMode && !te.inventory.isEmpty()) { + boolean alongZ = !te.getBlockState().get(SawBlock.AXIS_ALONG_FIRST_COORDINATE); + GlStateManager.pushMatrix(); + + float offset = te.inventory.recipeDuration != 0 + ? (float) (te.inventory.remainingTime) / te.inventory.recipeDuration + : 0; + if (te.getSpeed() == 0) + offset = .5f; + if (te.getSpeed() < 0 ^ alongZ) + offset = 1 - offset; + + ItemStack stack = te.inventory.getStackInSlot(0); + ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); + IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(stack); + boolean blockItem = modelWithOverrides.isGui3d(); + + GlStateManager.translated(x + (alongZ ? offset : .5), y + (blockItem ? .925f : 13f / 16f), + z + (alongZ ? .5 : offset)); + + GlStateManager.scaled(.5, .5, .5); + if (alongZ) + GlStateManager.rotated(90, 0, 1, 0); + GlStateManager.rotated(90, 1, 0, 0); + itemRenderer.renderItem(stack, ItemCameraTransforms.TransformType.FIXED); + GlStateManager.popMatrix(); + } + + // Filter + filterRenderer.render(te, x, y, z, partialTicks, destroyStage); + + // Kinetic renders + final BlockState state = getRenderedBlockState(te); + KineticTileEntityRenderer.cacheIfMissing(state, getWorld(), BlockModelSpinner::new); + final BlockPos pos = te.getPos(); + Axis axis = ((IRotate) te.getBlockState().getBlock()).getRotationAxis(te.getBlockState()); + float angle = KineticTileEntityRenderer.getAngleForTe(te, pos, axis); + + TessellatorHelper.prepareFastRender(); + TessellatorHelper.begin(DefaultVertexFormats.BLOCK); + KineticTileEntityRenderer.renderFromCache(Tessellator.getInstance().getBuffer(), state, getWorld(), (float) x, + (float) y, (float) z, pos, axis, angle); + TessellatorHelper.draw(); + } + protected BlockState getRenderedBlockState(KineticTileEntity te) { BlockState state = te.getBlockState(); if (state.get(FACING).getAxis().isHorizontal()) { diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MovingConstructHandler.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MovingConstructHandler.java index 4463f285d..fc6904906 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MovingConstructHandler.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/constructs/MovingConstructHandler.java @@ -26,8 +26,6 @@ import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IWorld; import net.minecraft.world.World; -import net.minecraftforge.client.event.RenderWorldLastEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @EventBusSubscriber @@ -166,8 +164,9 @@ public class MovingConstructHandler { return movingPistons.get(mechanicalPistonTileEntity.getWorld()); } - @SubscribeEvent - public static void onRenderWorld(RenderWorldLastEvent event) { +// @SubscribeEvent +// @OnlyIn(value = Dist.CLIENT) +// public static void onRenderWorld(RenderWorldLastEvent event) { // for (AxisAlignedBB bb : renderedBBs) { // TessellatorHelper.prepareForDrawing(); // GlStateManager.disableTexture(); @@ -179,6 +178,6 @@ public class MovingConstructHandler { // GlStateManager.enableTexture(); // TessellatorHelper.cleanUpAfterDrawing(); // } - } +// } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/FilteredTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/block/FilteredTileEntityRenderer.java index 15c31f7b7..909d6d677 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/FilteredTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/FilteredTileEntityRenderer.java @@ -22,6 +22,10 @@ public class FilteredTileEntityRenderer { float partialTicks, int destroyStage) { BlockState state = tileEntityIn.getBlockState(); IBlockWithFilter block = (IBlockWithFilter) state.getBlock(); + + if (!block.isFilterVisible(state)) + return; + Direction facing = block.getFilterFacing(state); float scale = block.getItemHitboxScale(); @@ -31,13 +35,13 @@ public class FilteredTileEntityRenderer { BlockPos pos = tileEntityIn.getPos(); GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); - renderFilterItem(tileEntityIn.getFilter(), position, facing, scale - 2 / 16f); + renderFilterItem(tileEntityIn.getFilter(), position, facing, scale - 2 / 16f, block.getFilterAngle(state)); TessellatorHelper.cleanUpAfterDrawing(); } - private void renderFilterItem(ItemStack stack, Vec3d position, Direction facing, float scaleDiff) { + private void renderFilterItem(ItemStack stack, Vec3d position, Direction facing, float scaleDiff, float angle) { ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); boolean vertical = facing.getAxis().isVertical(); @@ -46,11 +50,11 @@ public class FilteredTileEntityRenderer { float offX = 0; float offY = 0; - float offZ = !blockItem ? 1 / 4f + 2 * scaleDiff - 1/16f : 1/16f; + float offZ = !blockItem ? 1 / 4f + 2 * scaleDiff - 1 / 16f : 1 / 16f; if (vertical) offZ = -offZ; - float rotX = vertical ? 90 : 0 - (blockItem ? -67.5f : 67.5f); + float rotX = vertical ? 90 : 0 - (blockItem ? -90f + angle : 90 - angle); float rotY = vertical ? 0 : facing.getHorizontalAngle() + (blockItem ? 180 : 0); float rotZ = vertical && facing == Direction.DOWN ? 180 : 0; if (facing.getAxis() == Axis.X) { diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFilter.java b/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFilter.java index 1ff2435ee..9cd4aff1c 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFilter.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFilter.java @@ -41,6 +41,14 @@ public interface IBlockWithFilter { return 2 / 16f; } + public default float getFilterAngle(BlockState state) { + return 22.5f; + } + + public default boolean isFilterVisible(BlockState state) { + return true; + } + public default boolean showsCount() { return false; } @@ -50,8 +58,10 @@ public interface IBlockWithFilter { TileEntity te = worldIn.getTileEntity(pos); if (te == null || !(te instanceof IHaveFilter)) return false; - IHaveFilter actor = (IHaveFilter) te; + if (!isFilterVisible(state)) + return false; + IHaveFilter actor = (IHaveFilter) te; Vec3d vec = new Vec3d(pos); Vec3d position = vec.add(getFilterPosition(state)); ItemStack stack = player.getHeldItem(handIn); @@ -86,6 +96,9 @@ public interface IBlockWithFilter { IHaveFilter actor = (IHaveFilter) te; IBlockWithFilter filterBlock = (IBlockWithFilter) state.getBlock(); + if (!filterBlock.isFilterVisible(state)) + return; + Vec3d vec = new Vec3d(pos); Vec3d position = filterBlock.getFilterPosition(state).add(vec); float scale = filterBlock.getItemHitboxScale(); @@ -112,7 +125,8 @@ public interface IBlockWithFilter { Vec3i direction = facing.getDirectionVec(); GlStateManager.pushMatrix(); GlStateManager.translated(position.x, position.y, position.z); - GlStateManager.rotated(22.5f, direction.getZ(), 0, -direction.getX()); + float filterAngle = filterBlock.getFilterAngle(state); + GlStateManager.rotated(filterAngle, direction.getZ(), 0, -direction.getX()); GlStateManager.translated(-center.x, -center.y, -center.z); GlStateManager.translated(-position.x, -position.y, -position.z); @@ -138,7 +152,7 @@ public interface IBlockWithFilter { GlStateManager.rotated(facing.getHorizontalAngle() * (facing.getAxis() == Axis.X ? -1 : 1), 0, 1, 0); GlStateManager.scaled(textScale, -textScale, textScale); GlStateManager.translated(17.5f, -5f, -5f); - GlStateManager.rotated(67.5f, 1, 0, 0); + GlStateManager.rotated(90 - filterAngle, 1, 0, 0); String text = Lang.translate("logistics.filter"); FontRenderer font = Minecraft.getInstance().fontRenderer; @@ -149,7 +163,7 @@ public interface IBlockWithFilter { if (filterBlock.showsCount() && !actor.getFilter().isEmpty()) { String count = actor.getFilter().getCount() + ""; GlStateManager.translated(-7 - font.getStringWidth(count), 10, 10 + 1 / 4f); - GlStateManager.scaled(1.5,1.5, 1.5); + GlStateManager.scaled(1.5, 1.5, 1.5); font.drawString(count, 0, 0, 0xEDEDED); GlStateManager.translated(0, 0, -1 / 4f); font.drawString(count, 1, 1, 0x4F4F4F); diff --git a/src/main/resources/data/create/recipes/cutting/acacia_log.json b/src/main/resources/data/create/recipes/cutting/acacia_log.json new file mode 100644 index 000000000..bc012e2a2 --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/acacia_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:acacia_log" + } + ], + "results": [ + { + "item": "minecraft:stripped_acacia_log", + "count": 1 + } + ], + "processingTime": 50 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/birch_log.json b/src/main/resources/data/create/recipes/cutting/birch_log.json new file mode 100644 index 000000000..f66633e5a --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/birch_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:birch_log" + } + ], + "results": [ + { + "item": "minecraft:stripped_birch_log", + "count": 1 + } + ], + "processingTime": 50 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/dark_oak_log.json b/src/main/resources/data/create/recipes/cutting/dark_oak_log.json new file mode 100644 index 000000000..b19e7ec6d --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/dark_oak_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:dark_oak_log" + } + ], + "results": [ + { + "item": "minecraft:stripped_dark_oak_log", + "count": 1 + } + ], + "processingTime": 50 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/jungle_log.json b/src/main/resources/data/create/recipes/cutting/jungle_log.json new file mode 100644 index 000000000..0a87ccf16 --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/jungle_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:jungle_log" + } + ], + "results": [ + { + "item": "minecraft:stripped_jungle_log", + "count": 1 + } + ], + "processingTime": 50 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/oak_log.json b/src/main/resources/data/create/recipes/cutting/oak_log.json new file mode 100644 index 000000000..e0a934b4c --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/oak_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:oak_log" + } + ], + "results": [ + { + "item": "minecraft:stripped_oak_log", + "count": 1 + } + ], + "processingTime": 50 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/spruce_log.json b/src/main/resources/data/create/recipes/cutting/spruce_log.json new file mode 100644 index 000000000..6404bbc7d --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/spruce_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:spruce_log" + } + ], + "results": [ + { + "item": "minecraft:stripped_spruce_log", + "count": 1 + } + ], + "processingTime": 50 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/stripped_acacia_log.json b/src/main/resources/data/create/recipes/cutting/stripped_acacia_log.json new file mode 100644 index 000000000..5caccc871 --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/stripped_acacia_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:stripped_acacia_log" + } + ], + "results": [ + { + "item": "minecraft:acacia_planks", + "count": 5 + } + ], + "processingTime": 100 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/stripped_birch_log.json b/src/main/resources/data/create/recipes/cutting/stripped_birch_log.json new file mode 100644 index 000000000..85b057727 --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/stripped_birch_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:stripped_birch_log" + } + ], + "results": [ + { + "item": "minecraft:birch_planks", + "count": 5 + } + ], + "processingTime": 100 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/stripped_dark_oak_log.json b/src/main/resources/data/create/recipes/cutting/stripped_dark_oak_log.json new file mode 100644 index 000000000..ce2415689 --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/stripped_dark_oak_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:stripped_dark_oak_log" + } + ], + "results": [ + { + "item": "minecraft:dark_oak_planks", + "count": 5 + } + ], + "processingTime": 100 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/stripped_jungle_log.json b/src/main/resources/data/create/recipes/cutting/stripped_jungle_log.json new file mode 100644 index 000000000..095178c94 --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/stripped_jungle_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:stripped_jungle_log" + } + ], + "results": [ + { + "item": "minecraft:jungle_planks", + "count": 5 + } + ], + "processingTime": 100 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/stripped_oak_log.json b/src/main/resources/data/create/recipes/cutting/stripped_oak_log.json new file mode 100644 index 000000000..a41c57df1 --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/stripped_oak_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:stripped_oak_log" + } + ], + "results": [ + { + "item": "minecraft:oak_planks", + "count": 5 + } + ], + "processingTime": 100 +} \ No newline at end of file diff --git a/src/main/resources/data/create/recipes/cutting/stripped_spruce_log.json b/src/main/resources/data/create/recipes/cutting/stripped_spruce_log.json new file mode 100644 index 000000000..bcea76727 --- /dev/null +++ b/src/main/resources/data/create/recipes/cutting/stripped_spruce_log.json @@ -0,0 +1,16 @@ +{ + "type": "create:cutting", + "group": "minecraft:misc", + "ingredients": [ + { + "item": "minecraft:stripped_spruce_log" + } + ], + "results": [ + { + "item": "minecraft:spruce_planks", + "count": 5 + } + ], + "processingTime": 100 +} \ No newline at end of file