diff --git a/src/main/java/nl/requios/effortlessbuilding/Array.java b/src/main/java/nl/requios/effortlessbuilding/Array.java index 50c4ac2..a3e7a00 100644 --- a/src/main/java/nl/requios/effortlessbuilding/Array.java +++ b/src/main/java/nl/requios/effortlessbuilding/Array.java @@ -89,6 +89,7 @@ public class Array { blockState = BuildModifiers.getBlockStateFromItem(itemStack, player, startPos, EnumFacing.UP, new Vec3d(0, 0, 0), EnumHand.MAIN_HAND); } + //blockState = blockState.getBlock().getStateForPlacement(player.world, pos, ) blockStates.add(blockState); itemStacks.add(itemStack); } diff --git a/src/main/java/nl/requios/effortlessbuilding/BuildModifiers.java b/src/main/java/nl/requios/effortlessbuilding/BuildModifiers.java index 9f25e4d..92883fb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/BuildModifiers.java +++ b/src/main/java/nl/requios/effortlessbuilding/BuildModifiers.java @@ -86,13 +86,17 @@ public class BuildModifiers { public static void onBlockBroken(BlockEvent.BreakEvent event) { if (event.getWorld().isRemote) return; - //get coordinates - List coordinates = findCoordinates(event.getPlayer(), event.getPos()); + BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(event.getPlayer()); + //Only use own break event if anything is enabled + if (isEnabled(buildSettings, event.getPos())) { + //get coordinates + List coordinates = findCoordinates(event.getPlayer(), event.getPos()); - //break all those blocks - for (BlockPos coordinate : coordinates) { - if (event.getWorld().isBlockLoaded(coordinate, false)) { - SurvivalHelper.breakBlock(event.getWorld(), event.getPlayer(), coordinate); + //break all those blocks + for (BlockPos coordinate : coordinates) { + if (event.getWorld().isBlockLoaded(coordinate, false)) { + SurvivalHelper.breakBlock(event.getWorld(), event.getPlayer(), coordinate); + } } } } @@ -102,12 +106,12 @@ public class BuildModifiers { //Add current block being placed too coordinates.add(startPos); - List mirrorCoordinates = Mirror.findCoordinates(player, startPos); - coordinates.addAll(mirrorCoordinates); - coordinates.addAll(Array.findCoordinates(player, startPos)); + List arrayCoordinates = Array.findCoordinates(player, startPos); + coordinates.addAll(arrayCoordinates); + coordinates.addAll(Mirror.findCoordinates(player, startPos)); //get array for each coordinate - for (BlockPos coordinate : mirrorCoordinates) { - coordinates.addAll(Array.findCoordinates(player, coordinate)); + for (BlockPos coordinate : arrayCoordinates) { + coordinates.addAll(Mirror.findCoordinates(player, coordinate)); } return coordinates; @@ -137,17 +141,26 @@ public class BuildModifiers { blockStates.add(blockState); itemStacks.add(itemStack); - List mirrorBlockStates = Mirror.findBlockStates(player, startPos, blockState, itemStack, itemStacks); - blockStates.addAll(mirrorBlockStates); - blockStates.addAll(Array.findBlockStates(player, startPos, blockState, itemStack, itemStacks)); + List arrayBlockStates = Array.findBlockStates(player, startPos, blockState, itemStack, itemStacks); + blockStates.addAll(arrayBlockStates); + blockStates.addAll(Mirror.findBlockStates(player, startPos, blockState, itemStack, itemStacks)); //add array for each mirror coordinate - List findCoordinates = Mirror.findCoordinates(player, startPos); - for (int i = 0; i < findCoordinates.size(); i++) { - BlockPos coordinate = findCoordinates.get(i); - IBlockState blockState1 = mirrorBlockStates.get(i); - blockStates.addAll(Array.findBlockStates(player, coordinate, blockState1, itemStack, itemStacks)); + List arrayCoordinates = Array.findCoordinates(player, startPos); + for (int i = 0; i < arrayCoordinates.size(); i++) { + BlockPos coordinate = arrayCoordinates.get(i); + IBlockState blockState1 = arrayBlockStates.get(i); + blockStates.addAll(Mirror.findBlockStates(player, coordinate, blockState1, itemStack, itemStacks)); } + //Adjust blockstates for torches and ladders etc to place on a valid side + //TODO optimize findCoordinates (done twice now) + //TODO fix mirror +// List coordinates = findCoordinates(player, startPos); +// for (int i = 0; i < blockStates.size(); i++) { +// blockStates.set(i, blockStates.get(i).getBlock().getStateForPlacement(player.world, coordinates.get(i), facing, +// (float) hitVec.x, (float) hitVec.y, (float) hitVec.z, itemStacks.get(i).getMetadata(), player, EnumHand.MAIN_HAND)); +// } + return blockStates; } diff --git a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java index 208d185..ba7361d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java @@ -101,7 +101,7 @@ public class EventHandler IBlockState blockState = world.getBlockState(coordinate); //add hardness for each blockstate, if can break if (SurvivalHelper.canBreak(world, player, coordinate)) - totalBlockHardness += world.getBlockState(coordinate).getBlockHardness(world, coordinate); + totalBlockHardness += blockState.getBlockHardness(world, coordinate); } //Grabbing percentage from config diff --git a/src/main/java/nl/requios/effortlessbuilding/Mirror.java b/src/main/java/nl/requios/effortlessbuilding/Mirror.java index 1522503..cc0c986 100644 --- a/src/main/java/nl/requios/effortlessbuilding/Mirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/Mirror.java @@ -26,7 +26,7 @@ public class Mirror { public Vec3d position = new Vec3d(0.5, 64.5, 0.5); public boolean mirrorX = true, mirrorY = false, mirrorZ = false; public int radius = 20; - public boolean drawLines = true, drawPlanes = false; + public boolean drawLines = true, drawPlanes = true; public MirrorSettings() { } diff --git a/src/main/java/nl/requios/effortlessbuilding/helper/RenderHelper.java b/src/main/java/nl/requios/effortlessbuilding/helper/RenderHelper.java index 5d9aa5c..4c41cc9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/helper/RenderHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/helper/RenderHelper.java @@ -1,20 +1,25 @@ package nl.requios.effortlessbuilding.helper; +import com.google.common.collect.Maps; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.texture.TextureMap; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemTool; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumHand; -import net.minecraft.util.math.*; -import net.minecraftforge.client.ForgeHooksClient; -import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.IWorldEventListener; +import net.minecraft.world.World; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -25,11 +30,13 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL14; import org.lwjgl.util.Color; +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; +import java.util.Map; @Mod.EventBusSubscriber(Side.CLIENT) -public class RenderHelper { +public class RenderHelper implements IWorldEventListener { private static final Color colorX = new Color(255, 72, 52); private static final Color colorY = new Color(67, 204, 51); @@ -76,20 +83,7 @@ public class RenderHelper { Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE); GlStateManager.enableBlend(); GlStateManager.blendFunc(GL11.GL_CONSTANT_ALPHA, GL11.GL_ONE_MINUS_CONSTANT_ALPHA); - GL14.glBlendColor(1F, 1F, 1F, 0.6f); - } - - public static void renderBlockOutline(BlockPos pos) { - renderBlockOutline(pos, pos); - } - - //Renders outline. Pos1 has to be minimal x,y,z and pos2 maximal x,y,z - public static void renderBlockOutline(BlockPos pos1, BlockPos pos2) { - GL11.glLineWidth(2); - - AxisAlignedBB aabb = new AxisAlignedBB(pos1, pos2.add(1, 1, 1)).grow(0.0020000000949949026); - - RenderGlobal.drawSelectionBoundingBox(aabb, 0f, 0f, 0f, 0.4f); + GL14.glBlendColor(1F, 1F, 1F, 0.8f); } private static void endBlockPreviews() { @@ -109,10 +103,23 @@ public class RenderHelper { GlStateManager.rotate(-90.0F, 0.0F, 1.0F, 0.0F); GlStateManager.translate(-0.005f, -0.005f, 0.005f); GlStateManager.scale(1.01f, 1.01f, 1.01f); - dispatcher.renderBlockBrightness(blockState, 1f); + dispatcher.renderBlockBrightness(blockState, 0.85f); GlStateManager.popMatrix(); } + public static void renderBlockOutline(BlockPos pos) { + renderBlockOutline(pos, pos); + } + + //Renders outline. Pos1 has to be minimal x,y,z and pos2 maximal x,y,z + public static void renderBlockOutline(BlockPos pos1, BlockPos pos2) { + GL11.glLineWidth(2); + + AxisAlignedBB aabb = new AxisAlignedBB(pos1, pos2.add(1, 1, 1)).grow(0.0020000000949949026); + + RenderGlobal.drawSelectionBoundingBox(aabb, 0f, 0f, 0f, 0.4f); + } + @SubscribeEvent public static void onRender(RenderWorldLastEvent event) { EntityPlayer player = Minecraft.getMinecraft().player; @@ -170,7 +177,7 @@ public class RenderHelper { //Check if tool (or none) in hand ItemStack mainhand = player.getHeldItemMainhand(); - boolean toolInHand = !mainhand.isEmpty() && mainhand.getItem() instanceof ItemTool; + boolean toolInHand = mainhand.isEmpty() || (!mainhand.isEmpty() && mainhand.getItem() instanceof ItemTool); boolean replaceable = player.world.getBlockState(startPos).getBlock().isReplaceable(player.world, startPos); if (!buildSettings.doQuickReplace() && !toolInHand && !replaceable) { @@ -201,10 +208,16 @@ public class RenderHelper { //check if valid blockstates if (blockStates.size() != 0 && newCoordinates.size() == blockStates.size()) { - for (int i = 0; i < newCoordinates.size(); i++) { + for (int i = newCoordinates.size() - 1; i >= 0; i--) { BlockPos blockPos = newCoordinates.get(i); IBlockState blockState = blockStates.get(i); - renderBlockPreview(dispatcher, blockPos, blockState); + ItemStack itemstack = itemStacks.get(i); + //Check if can place + if (!itemstack.isEmpty() && SurvivalHelper.canPlayerEdit(player, player.world, blockPos, itemstack) && + SurvivalHelper.mayPlace(player.world, Block.getBlockFromItem(itemstack.getItem()), blockState, blockPos, true, EnumFacing.UP, player) && + SurvivalHelper.canReplace(player.world, player, blockPos)) { + renderBlockPreview(dispatcher, blockPos, blockState); + } } } } @@ -217,7 +230,8 @@ public class RenderHelper { BlockPos coordinate = newCoordinates.get(i); IBlockState blockState = player.world.getBlockState(coordinate); - if (!blockState.getBlock().isAir(blockState, player.world, coordinate)) { + if (!blockState.getBlock().isAir(blockState, player.world, coordinate) && + SurvivalHelper.canBreak(player.world, player, coordinate)) { renderBlockOutline(coordinate); } } @@ -312,4 +326,82 @@ public class RenderHelper { tessellator.draw(); } + //IWORLDEVENTLISTENER IMPLEMENTATION + @Override + public void notifyBlockUpdate(World worldIn, BlockPos pos, IBlockState oldState, IBlockState newState, int flags) { + + } + + @Override + public void notifyLightSet(BlockPos pos) { + + } + + @Override + public void markBlockRangeForRenderUpdate(int x1, int y1, int z1, int x2, int y2, int z2) { + + } + + @Override + public void playSoundToAllNearExcept(@Nullable EntityPlayer player, SoundEvent soundIn, SoundCategory category, + double x, double y, double z, float volume, float pitch) { + + } + + @Override + public void playRecord(SoundEvent soundIn, BlockPos pos) { + + } + + @Override + public void spawnParticle(int particleID, boolean ignoreRange, double xCoord, double yCoord, double zCoord, + double xSpeed, double ySpeed, double zSpeed, int... parameters) { + + } + + @Override + public void spawnParticle(int id, boolean ignoreRange, boolean p_190570_3_, double x, double y, double z, + double xSpeed, double ySpeed, double zSpeed, int... parameters) { + + } + + @Override + public void onEntityAdded(Entity entityIn) { + + } + + @Override + public void onEntityRemoved(Entity entityIn) { + + } + + @Override + public void broadcastSound(int soundID, BlockPos pos, int data) { + + } + + @Override + public void playEvent(EntityPlayer player, int type, BlockPos blockPosIn, int data) { + + } + + //Sends breaking progress for all coordinates to renderglobal, so all blocks get visually broken + @Override + public void sendBlockBreakProgress(int breakerId, BlockPos pos, int progress) { + Minecraft mc = Minecraft.getMinecraft(); + + BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(mc.player); + if (!BuildModifiers.isEnabled(buildSettings, pos)) return; + + List coordinates = BuildModifiers.findCoordinates(mc.player, pos); + for (int i = 1; i < coordinates.size(); i++) { + BlockPos coordinate = coordinates.get(i); + if (SurvivalHelper.canBreak(mc.world, mc.player, coordinate)) { + //Send i as entity id because only one block can be broken per id + //Unless i happens to be the player id, then take something else + int fakeId = mc.player.getEntityId() != i ? i : coordinates.size(); + mc.renderGlobal.sendBlockBreakProgress(fakeId, coordinate, progress); + } + } + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java b/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java index 05c33fb..1723181 100644 --- a/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java @@ -1,6 +1,7 @@ package nl.requios.effortlessbuilding.helper; import net.minecraft.block.Block; +import net.minecraft.block.BlockLiquid; import net.minecraft.block.SoundType; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; @@ -20,6 +21,7 @@ import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.ItemHandlerHelper; +import nl.requios.effortlessbuilding.BuildSettingsManager; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.item.ItemRandomizerBag; @@ -108,11 +110,12 @@ public class SurvivalHelper { //Can break using held tool? (or in creative) public static boolean canBreak(World world, EntityPlayer player, BlockPos pos) { + IBlockState blockState = world.getBlockState(pos); + if (blockState.getBlock() instanceof BlockLiquid) return false; + if (player.isCreative()) return true; - IBlockState blockState = world.getBlockState(pos); return canHarvestBlock(blockState.getBlock(), player, world, pos); - } //From ForgeHooks#canHarvestBlock @@ -169,21 +172,23 @@ public class SurvivalHelper { } //From EntityPlayer#canPlayerEdit - private static boolean canPlayerEdit(EntityPlayer player, World world, BlockPos pos, ItemStack stack) + public static boolean canPlayerEdit(EntityPlayer player, World world, BlockPos pos, ItemStack stack) { if (player.capabilities.allowEdit) { + //True in creative and survival mode return true; } else { + //Adventure mode Block block = world.getBlockState(pos).getBlock(); return stack.canPlaceOn(block) || stack.canEditBlocks(); } } //From World#mayPlace - private static boolean mayPlace(World world, Block blockIn, IBlockState newBlockState, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer) + public static boolean mayPlace(World world, Block blockIn, IBlockState newBlockState, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer) { IBlockState iblockstate1 = world.getBlockState(pos); AxisAlignedBB axisalignedbb = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionBoundingBox(world, pos); @@ -204,9 +209,11 @@ public class SurvivalHelper { return true; } - //TODO check config for allow to replace - return true; - //TODO fix check canPlaceBlockOnSide - //return /*iblockstate1.getBlock().isReplaceable(world, pos) &&*/ blockIn.canPlaceBlockOnSide(world, pos, sidePlacedOn); + //Check quickreplace + if (placer instanceof EntityPlayer && BuildSettingsManager.getBuildSettings(((EntityPlayer) placer)).doQuickReplace()) { + return true; + } + + return iblockstate1.getBlock().isReplaceable(world, pos) && blockIn.canPlaceBlockOnSide(world, pos, sidePlacedOn); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java index 126fdc4..68a9f5b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java @@ -2,20 +2,27 @@ package nl.requios.effortlessbuilding.proxy; import net.minecraft.block.Block; import net.minecraft.block.SoundType; +import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.settings.KeyBinding; +import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.util.IThreadListener; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraft.util.text.TextFormatting; +import net.minecraft.world.IWorldEventListener; import net.minecraft.world.World; import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.model.ModelLoader; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.*; @@ -28,8 +35,12 @@ import net.minecraftforge.fml.relauncher.Side; import nl.requios.effortlessbuilding.BuildSettingsManager; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.gui.SettingsGui; +import nl.requios.effortlessbuilding.helper.RenderHelper; import nl.requios.effortlessbuilding.network.BuildSettingsMessage; import org.lwjgl.input.Keyboard; +import scala.collection.parallel.ParIterableLike; + +import javax.annotation.Nullable; @Mod.EventBusSubscriber(Side.CLIENT) public class ClientProxy implements IProxy { @@ -88,6 +99,13 @@ public class ClientProxy implements IProxy { } } + @SubscribeEvent + public static void onEntityJoinWorld(EntityJoinWorldEvent event) { + if (event.getEntity() == Minecraft.getMinecraft().player) { + event.getWorld().addEventListener(new RenderHelper()); + } + } + @SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true) public static void onKeyPress(InputEvent.KeyInputEvent event) { EntityPlayerSP player = Minecraft.getMinecraft().player;