diff --git a/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java b/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java index 5ea8858..1b452de 100644 --- a/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java +++ b/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java @@ -58,10 +58,14 @@ public class BuildConfig { @Comment({"Show a block preview if you have a block in hand on build mode Normal"}) public boolean alwaysShowBlockPreview = false; + @Comment({"How long the dissolve effect takes when placing blocks, in ticks."}) + public int dissolveTime = 40; + + @Comment({"Switch to using the simple performance shader when placing more than so many blocks."}) + public int shaderTreshold = 1500; + @Comment({"Use fancy shaders while placing blocks"}) public boolean useShaders = true; - @Comment({"How long the dissolve effect takes when placing blocks, in ticks."}) - public int dissolveTime = 60; } } diff --git a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java index 913e6f5..0928aa8 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java @@ -23,8 +23,10 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; +import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.capability.ModeCapabilityManager; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; +import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.network.BlockPlacedMessage; import nl.requios.effortlessbuilding.network.RequestLookAtMessage; @@ -83,22 +85,31 @@ public class EventHandler //Only called serverside public static void onBlockPlaced(BlockEvent.PlaceEvent event) { //Cancel event if necessary - BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(event.getPlayer()).getBuildMode(); - if (buildMode != BuildModes.BuildModeEnum.Normal) { + EntityPlayer player = event.getPlayer(); + BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); + ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); + + if (buildMode != BuildModes.BuildModeEnum.Normal || modifierSettings.doQuickReplace()) { event.setCanceled(true); } else { + //Normal mode, let vanilla handle block placing + //But modifiers should still work + //Send message to client, which sends message back with raytrace info - EffortlessBuilding.packetHandler.sendTo(new RequestLookAtMessage(), (EntityPlayerMP) event.getPlayer()); + EffortlessBuilding.packetHandler.sendTo(new RequestLookAtMessage(), (EntityPlayerMP) player); } } @SubscribeEvent public static void onBlockBroken(BlockEvent.BreakEvent event) { //Cancel event if necessary + //If cant break far then dont cancel event ever BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(event.getPlayer()).getBuildMode(); - if (buildMode != BuildModes.BuildModeEnum.Normal) { + if (buildMode != BuildModes.BuildModeEnum.Normal && ReachHelper.canBreakFar(event.getPlayer())) { event.setCanceled(true); } else { + //Normal mode, let vanilla handle block breaking + //But modifiers should still work BuildModes.onBlockBroken(event); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java index e0939e7..d6e013b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java @@ -5,23 +5,26 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraft.world.World; import net.minecraftforge.event.world.BlockEvent; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.relauncher.Side; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.*; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.helper.ReachHelper; -import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.network.BlockBrokenMessage; import nl.requios.effortlessbuilding.network.BlockPlacedMessage; import java.util.ArrayList; +import java.util.Dictionary; +import java.util.Hashtable; import java.util.List; public class BuildModes { + //Static variables are shared between client and server in singleplayer + //We need them separate + public static Dictionary currentlyBreakingClient = new Hashtable<>(); + public static Dictionary currentlyBreakingServer = new Hashtable<>(); + public enum BuildModeEnum { Normal ("Normal", new Normal()), NormalPlus ("Normal+", new NormalPlus()), @@ -47,6 +50,14 @@ public class BuildModes { //Raytraceresult is needed for sideHit and hitVec public static void onBlockPlacedMessage(EntityPlayer player, BlockPlacedMessage message) { + //Check if not in the middle of breaking + Dictionary currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; + if (currentlyBreaking.get(player) != null && currentlyBreaking.get(player)) { + //Cancel breaking + initializeMode(player); + return; + } + ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); BuildModeEnum buildMode = modeSettings.getBuildMode(); @@ -74,14 +85,20 @@ public class BuildModes { return; } } + //Even when no starting block is found, call buildmode instance //We might want to place things in the air - List posList = buildMode.instance.onRightClick(player, startPos, message.getSideHit(), message.getHitVec()); + List coordinates = buildMode.instance.onRightClick(player, startPos, message.getSideHit(), message.getHitVec(), modifierSettings.doQuickReplace()); + + if (coordinates.isEmpty()) { + currentlyBreaking.put(player, false); + return; + } //Limit number of blocks you can place int limit = ReachHelper.getMaxBlocksPlacedAtOnce(player); - if (posList.size() > limit) { - posList = posList.subList(0, limit); + if (coordinates.size() > limit) { + coordinates = coordinates.subList(0, limit); } EnumFacing sideHit = buildMode.instance.getSideHit(player); @@ -90,11 +107,14 @@ public class BuildModes { Vec3d hitVec = buildMode.instance.getHitVec(player); if (hitVec == null) hitVec = message.getHitVec(); - BuildModifiers.onBlockPlaced(player, posList, sideHit, hitVec); + BuildModifiers.onBlockPlaced(player, coordinates, sideHit, hitVec); + + //Only works when finishing a buildmode is equal to placing some blocks + //No intermediate blocks allowed + currentlyBreaking.remove(player); } - //Use a network message to break blocks in the distance using clientside mouse input public static void onBlockBrokenMessage(EntityPlayer player, BlockBrokenMessage message) { BlockPos blockPos = message.getBlockPos(); @@ -108,31 +128,45 @@ public class BuildModes { } public static void onBlockBroken(BlockEvent.BreakEvent event) { - World world = event.getWorld(); EntityPlayer player = event.getPlayer(); BlockPos pos = event.getPos(); - if (world.isRemote) return; + //Check if not in the middle of placing + Dictionary currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; + if (currentlyBreaking.get(player) != null && !currentlyBreaking.get(player)) { + //Cancel placing + initializeMode(player); + return; + } //get coordinates ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); BuildModeEnum buildMode = modeSettings.getBuildMode(); - List coordinates = buildMode.instance.onRightClick(player, pos, EnumFacing.UP, Vec3d.ZERO); + List coordinates = buildMode.instance.onRightClick(player, pos, EnumFacing.UP, Vec3d.ZERO, true); + + if (coordinates.isEmpty()) { + currentlyBreaking.put(player, true); + return; + } //let buildmodifiers break blocks BuildModifiers.onBlockBroken(player, coordinates); } - public static List findCoordinates(EntityPlayer player, BlockPos startPos) { + public static List findCoordinates(EntityPlayer player, BlockPos startPos, boolean skipRaytrace) { List coordinates = new ArrayList<>(); ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); - coordinates.addAll(modeSettings.getBuildMode().instance.findCoordinates(player, startPos)); + coordinates.addAll(modeSettings.getBuildMode().instance.findCoordinates(player, startPos, skipRaytrace)); return coordinates; } public static void initializeMode(EntityPlayer player) { + //Resetting mode, so not placing or breaking + Dictionary currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; + currentlyBreaking.remove(player); + ModeSettingsManager.getModeSettings(player).getBuildMode().instance.initialize(player); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Cube.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Cube.java index 0719dcc..29206f8 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Cube.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/Cube.java @@ -15,12 +15,12 @@ public class Cube implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { return new ArrayList<>(); } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { return new ArrayList<>(); } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalLine.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalLine.java index c830c83..1823ad5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalLine.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalLine.java @@ -15,12 +15,12 @@ public class DiagonalLine implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { return new ArrayList<>(); } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { return new ArrayList<>(); } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalWall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalWall.java index aa9f6eb..5f25335 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalWall.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/DiagonalWall.java @@ -15,12 +15,12 @@ public class DiagonalWall implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { return new ArrayList<>(); } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { return new ArrayList<>(); } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java index 014b12c..c038ca1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java @@ -28,7 +28,7 @@ public class Floor implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { List list = new ArrayList<>(); Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; @@ -51,7 +51,7 @@ public class Floor implements IBuildMode { } else { //Second click, place wall - list = findCoordinates(player, blockPos); + list = findCoordinates(player, blockPos, skipRaytrace); rightClickTable.put(player.getUniqueID(), 0); } @@ -59,7 +59,7 @@ public class Floor implements IBuildMode { } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { List list = new ArrayList<>(); Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; int rightClickNr = rightClickTable.get(player.getUniqueID()); @@ -98,10 +98,12 @@ public class Floor implements IBuildMode { if (selected == null) return list; //check if it doesnt go through blocks - RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false); - if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { - //return empty list - return list; + if (!skipRaytrace) { + RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false); + if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { + //return empty list + return list; + } } BlockPos secondPos = new BlockPos(selected); diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/IBuildMode.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/IBuildMode.java index ba724e0..f455641 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/IBuildMode.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/IBuildMode.java @@ -14,10 +14,10 @@ public interface IBuildMode { //Fired when a block would be placed //Return a list of coordinates where you want to place blocks - List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec); + List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace); //Fired continuously for visualization purposes - List findCoordinates(EntityPlayer player, BlockPos blockPos); + List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace); EnumFacing getSideHit(EntityPlayer player); diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Line.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Line.java index a8099c1..e2c88cd 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Line.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/Line.java @@ -28,7 +28,7 @@ public class Line implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { List list = new ArrayList<>(); Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; @@ -51,7 +51,7 @@ public class Line implements IBuildMode { } else { //Second click, place wall - list = findCoordinates(player, blockPos); + list = findCoordinates(player, blockPos, skipRaytrace); rightClickTable.put(player.getUniqueID(), 0); } @@ -59,7 +59,7 @@ public class Line implements IBuildMode { } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { List list = new ArrayList<>(); Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; int rightClickNr = rightClickTable.get(player.getUniqueID()); @@ -155,25 +155,31 @@ public class Line implements IBuildMode { if (selected == null) return list; //check if it doesnt go through blocks - RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false); - if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { - //return empty list - return list; + if (!skipRaytrace) { + RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false); + if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { + //return empty list + return list; + } } BlockPos secondPos = new BlockPos(selected); + int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); + //Add whole line int x1 = firstPos.getX(), x2 = secondPos.getX(); int y1 = firstPos.getY(), y2 = secondPos.getY(); int z1 = firstPos.getZ(), z2 = secondPos.getZ(); + outerloop: for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { for (int m = y1; y1 < y2 ? m <= y2 : m >= y2; m += y1 < y2 ? 1 : -1) { + if (list.size() >= axisLimit) break outerloop; list.add(new BlockPos(l, m, n)); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Normal.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Normal.java index 8fcfcee..f602376 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Normal.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/Normal.java @@ -15,14 +15,14 @@ public class Normal implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { List list = new ArrayList<>(); list.add(blockPos); return list; } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { List list = new ArrayList<>(); list.add(blockPos); return list; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/NormalPlus.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/NormalPlus.java index 7aaf1bb..f800bfb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/NormalPlus.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/NormalPlus.java @@ -15,14 +15,14 @@ public class NormalPlus implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { List list = new ArrayList<>(); list.add(blockPos); return list; } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { List list = new ArrayList<>(); list.add(blockPos); return list; diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/SlopeFloor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/SlopeFloor.java index 77f93e3..b3c3d74 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/SlopeFloor.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/SlopeFloor.java @@ -15,12 +15,12 @@ public class SlopeFloor implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { return new ArrayList<>(); } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { return new ArrayList<>(); } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java index d5a4fee..c15b3a5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java @@ -5,7 +5,6 @@ import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.Vec3d; -import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.helper.ReachHelper; import java.util.*; @@ -29,7 +28,7 @@ public class Wall implements IBuildMode { } @Override - public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec) { + public List onRightClick(EntityPlayer player, BlockPos blockPos, EnumFacing sideHit, Vec3d hitVec, boolean skipRaytrace) { List list = new ArrayList<>(); Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; @@ -52,7 +51,7 @@ public class Wall implements IBuildMode { } else { //Second click, place wall - list = findCoordinates(player, blockPos); + list = findCoordinates(player, blockPos, skipRaytrace); rightClickTable.put(player.getUniqueID(), 0); } @@ -60,7 +59,7 @@ public class Wall implements IBuildMode { } @Override - public List findCoordinates(EntityPlayer player, BlockPos blockPos) { + public List findCoordinates(EntityPlayer player, BlockPos blockPos, boolean skipRaytrace) { List list = new ArrayList<>(); Dictionary rightClickTable = player.world.isRemote ? rightClickClientTable : rightClickServerTable; int rightClickNr = rightClickTable.get(player.getUniqueID()); @@ -123,10 +122,12 @@ public class Wall implements IBuildMode { if (selected == null) return list; //check if it doesnt go through blocks - RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false); - if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { - //return empty list - return list; + if (!skipRaytrace) { + RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false); + if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { + //return empty list + return list; + } } BlockPos secondPos = new BlockPos(selected); @@ -134,11 +135,20 @@ public class Wall implements IBuildMode { //Add whole wall //Limit amount of blocks you can place per row int limit = ReachHelper.getMaxBlocksPlacedAtOnce(player); + int axisLimit = ReachHelper.getMaxBlocksPerAxis(player); int x1 = firstPos.getX(), x2 = secondPos.getX(); int y1 = firstPos.getY(), y2 = secondPos.getY(); int z1 = firstPos.getZ(), z2 = secondPos.getZ(); + //limit axis + if (x2 - x1 > axisLimit) x2 = x1 + axisLimit; + if (x1 - x2 > axisLimit) x2 = x1 - axisLimit; + if (y2 - y1 > axisLimit) y2 = y1 + axisLimit; + if (y1 - y2 > axisLimit) y2 = y1 - axisLimit; + if (z2 - z1 > axisLimit) z2 = z1 + axisLimit; + if (z1 - z2 > axisLimit) z2 = z1 - axisLimit; + for (int l = x1; x1 < x2 ? l <= x2 : l >= x2; l += x1 < x2 ? 1 : -1) { for (int n = z1; z1 < z2 ? n <= z2 : n >= z2; n += z1 < z2 ? 1 : -1) { diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java index d15e7b7..9cb6712 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java @@ -25,7 +25,7 @@ import java.util.List; public class BuildModifiers { //Called from BuildModes - public static void onBlockPlaced(EntityPlayer player, List posList, EnumFacing sideHit, Vec3d hitVec) { + public static void onBlockPlaced(EntityPlayer player, List startCoordinates, EnumFacing sideHit, Vec3d hitVec) { World world = player.world; ItemRandomizerBag.renewRandomness(); @@ -33,9 +33,9 @@ public class BuildModifiers { hitVec = new Vec3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), Math.abs(hitVec.z - ((int) hitVec.z))); //find coordinates and blockstates - List coordinates = findCoordinates(player, posList); + List coordinates = findCoordinates(player, startCoordinates); List itemStacks = new ArrayList<>(); - List blockStates = findBlockStates(player, posList, hitVec, sideHit, itemStacks); + List blockStates = findBlockStates(player, startCoordinates, hitVec, sideHit, itemStacks); //check if valid blockstates if (blockStates.size() == 0 || coordinates.size() != blockStates.size()) return; @@ -54,7 +54,7 @@ public class BuildModifiers { if (world.isBlockLoaded(blockPos, true)) { //check itemstack empty if (itemStack.isEmpty()) continue; - SurvivalHelper.placeBlock(world, player, blockPos, blockState, itemStack, EnumFacing.UP, hitVec, true, false); + SurvivalHelper.placeBlock(world, player, blockPos, blockState, itemStack, EnumFacing.UP, hitVec, false, false); } } @@ -67,6 +67,11 @@ public class BuildModifiers { if (coordinates.isEmpty()) return; + if (world.isRemote) { + BlockPreviewRenderer.onBlocksBroken(); + return; + } + //If the player is going to instabreak grass or a plant, only break other instabreaking things boolean onlyInstaBreaking = world.getBlockState(posList.get(0)).getBlockHardness(world, posList.get(0)) == 0f; @@ -122,10 +127,11 @@ public class BuildModifiers { ItemStack itemBlock = ItemStack.EMPTY; if (itemStack.getItem() instanceof ItemBlock) itemBlock = itemStack; else itemBlock = CompatHelper.getItemBlockFromStack(itemStack); + ItemRandomizerBag.resetRandomness(); //Add blocks in posList first for (BlockPos blockPos : posList) { - //if (itemStack.getItem() instanceof ItemRandomizerBag) itemBlock = ItemRandomizerBag.pickRandomStack(ItemRandomizerBag.getBagInventory(itemStack)); + if (!(itemStack.getItem() instanceof ItemBlock)) itemBlock = CompatHelper.getItemBlockFromStack(itemStack); IBlockState blockState = getBlockStateFromItem(itemBlock, player, blockPos, facing, hitVec, EnumHand.MAIN_HAND); blockStates.add(blockState); itemStacks.add(itemBlock); diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java index 5b8b9b3..34a9b21 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java @@ -41,7 +41,7 @@ public class Mirror { } public int getReach() { - return radius * 2; + return radius * 2; //Change ModifierSettings#setReachUpgrade too } } @@ -114,8 +114,7 @@ public class Mirror { //Randomizer bag synergy if (bagInventory != null) { itemStack = ItemRandomizerBag.pickRandomStack(bagInventory); - oldBlockState = BuildModifiers - .getBlockStateFromItem(itemStack, player, oldBlockPos, EnumFacing.UP, new Vec3d(0, 0, 0), hand); + oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, EnumFacing.UP, new Vec3d(0, 0, 0), hand); } //Find blockstate diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java index 46f3c56..d5bfe3d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java @@ -5,6 +5,7 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.PlayerEvent; +import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.helper.ReachHelper; @@ -161,6 +162,20 @@ public class ModifierSettingsManager { public void setReachUpgrade(int reachUpgrade) { this.reachUpgrade = reachUpgrade; + //Set mirror radius to max + int reach = 10; + switch (reachUpgrade) { + case 0: reach = BuildConfig.reach.maxReachLevel0; break; + case 1: reach = BuildConfig.reach.maxReachLevel1; break; + case 2: reach = BuildConfig.reach.maxReachLevel2; break; + case 3: reach = BuildConfig.reach.maxReachLevel3; break; + } + + if (this.mirrorSettings != null) + this.mirrorSettings.radius = reach / 2; + if (this.radialMirrorSettings != null) + this.radialMirrorSettings.radius = reach / 2; + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java index ca05445..d7273dc 100644 --- a/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/compatibility/CompatHelper.java @@ -49,7 +49,6 @@ public class CompatHelper { public static ItemStack getItemBlockFromStack(ItemStack stack) { Item item = stack.getItem(); if(item instanceof ItemRandomizerBag) { - ItemRandomizerBag.resetRandomness(); return ItemRandomizerBag.pickRandomStack(ItemRandomizerBag.getBagInventory(stack)); } else if(item == dankNullItem) { int index = 0; diff --git a/src/main/java/nl/requios/effortlessbuilding/helper/ReachHelper.java b/src/main/java/nl/requios/effortlessbuilding/helper/ReachHelper.java index 46d4944..e350a53 100644 --- a/src/main/java/nl/requios/effortlessbuilding/helper/ReachHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/helper/ReachHelper.java @@ -1,6 +1,7 @@ package nl.requios.effortlessbuilding.helper; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.MathHelper; import nl.requios.effortlessbuilding.BuildConfig; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; @@ -27,7 +28,12 @@ public class ReachHelper { public static int getMaxBlocksPlacedAtOnce(EntityPlayer player) { if (player.isCreative()) return 1000000; - return getMaxReach(player) / 2; + return getMaxReach(player) * 5; + } + + public static int getMaxBlocksPerAxis(EntityPlayer player) { + if (player.isCreative()) return 2000; + return MathHelper.ceil(MathHelper.sqrt(getMaxReach(player))); } public static boolean canBreakFar(EntityPlayer player) { diff --git a/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java b/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java index d284f21..ca29a30 100644 --- a/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/helper/SurvivalHelper.java @@ -10,8 +10,10 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.Enchantments; +import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; +import net.minecraft.stats.StatList; import net.minecraft.util.EnumFacing; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.AxisAlignedBB; @@ -26,6 +28,7 @@ import nl.requios.effortlessbuilding.compatibility.CompatHelper; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import java.util.ArrayList; import java.util.List; public class SurvivalHelper { @@ -49,24 +52,12 @@ public class SurvivalHelper { if (canPlace(world, player, pos, blockState, itemstack, skipCollisionCheck, facing.getOpposite())) { //Drop existing block - //TODO check if can replace dropBlock(world, player, pos); boolean placed = ((ItemBlock) itemstack.getItem()).placeBlockAt(itemstack, player, world, pos, facing, (float) hitVec.x, (float) hitVec.y, (float) hitVec.z, blockState); if (!placed) return false; -// //From ItemBlock#placeBlockAt -// if (!world.setBlockState(pos, blockState, 11)) return false; -// IBlockState afterState = world.getBlockState(pos); -// if (afterState.getBlock() == block) -// { -// ((ItemBlock) itemstack.getItem()).setTileEntityNBT(world, player, pos, itemstack); -// block.onBlockPlacedBy(world, pos, afterState, player, itemstack); -// -//// if (player instanceof EntityPlayerMP) -//// CriteriaTriggers.PLACED_BLOCK.trigger((EntityPlayerMP)player, pos, itemstack); -// } if (playSound) { SoundType soundtype = afterState.getBlock().getSoundType(afterState, world, pos, player); @@ -90,6 +81,9 @@ public class SurvivalHelper { //Check if can break if (canBreak(world, player, pos)) { + player.addStat(StatList.getBlockStats(world.getBlockState(pos).getBlock())); + player.addExhaustion(0.005F); + //Drop existing block dropBlock(world, player, pos); @@ -107,13 +101,38 @@ public class SurvivalHelper { if (player.isCreative()) return; IBlockState blockState = world.getBlockState(pos); + Block block = blockState.getBlock(); - int fortune = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, player.getHeldItemMainhand()); - List drops = blockState.getBlock().getDrops(world, pos, blockState, fortune); - for (ItemStack drop : drops) - { - ItemHandlerHelper.giveItemToPlayer(player, drop); - } + block.harvestBlock(world, player, pos, blockState, world.getTileEntity(pos), player.getHeldItemMainhand()); + + //TODO drop items in inventory instead of world + +// List drops = new ArrayList<>(); +// +// //From Block#harvestBlock +// int silktouch = EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, player.getHeldItemMainhand()); +// if (block.canSilkHarvest(world, pos, blockState, player) && silktouch > 0) { +// +// //From Block#getSilkTouchDrop (protected) +// Item item = Item.getItemFromBlock(block); +// int i = 0; +// +// if (item.getHasSubtypes()) +// { +// i = block.getMetaFromState(blockState); +// } +// +// drops.add(new ItemStack(item, 1, i)); +// +// net.minecraftforge.event.ForgeEventFactory.fireBlockHarvesting(drops, world, pos, blockState, 0, 1.0f, true, player); +// } +// +// int fortune = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, player.getHeldItemMainhand()); +// drops.addAll(block.getDrops(world, pos, blockState, fortune)); +// for (ItemStack drop : drops) +// { +// ItemHandlerHelper.giveItemToPlayer(player, drop); +// } } /** @@ -132,8 +151,9 @@ public class SurvivalHelper { //Check if itemstack is correct if (!(itemStack.getItem() instanceof ItemBlock) || Block.getBlockFromItem(itemStack.getItem()) != newBlockState.getBlock()) { - EffortlessBuilding.log(player, "Cannot (re)place block", true); - EffortlessBuilding.log("SurvivalHelper#placeBlock: itemstack " + itemStack.toString() + " does not match blockstate " + newBlockState.toString()); +// EffortlessBuilding.log(player, "Cannot (re)place block", true); +// EffortlessBuilding.log("SurvivalHelper#canPlace: itemstack " + itemStack.toString() + " does not match blockstate " + newBlockState.toString()); + //Happens when breaking blocks, no need to notify in that case return false; } @@ -175,9 +195,9 @@ public class SurvivalHelper { private 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); + AxisAlignedBB axisalignedbb = skipCollisionCheck ? Block.NULL_AABB : blockIn.getDefaultState().getCollisionBoundingBox(world, pos); - if (axisalignedbb != Block.NULL_AABB && !world.checkNoEntityCollision(axisalignedbb.offset(pos), placer)) + if (axisalignedbb != Block.NULL_AABB && !world.checkNoEntityCollision(axisalignedbb.offset(pos))) { return false; } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java index ca210ca..2bfbf9b 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java @@ -186,11 +186,12 @@ public class ClientProxy implements IProxy { if (breakCooldown <= 0) { breakCooldown = 6; RayTraceResult lookingAt = getLookingAt(player); - if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK) { - BuildModes.onBlockBrokenMessage(player, new BlockBrokenMessage(lookingAt)); - EffortlessBuilding.packetHandler.sendToServer(new BlockBrokenMessage(lookingAt)); - //play sound + BuildModes.onBlockBrokenMessage(player, new BlockBrokenMessage(lookingAt)); + EffortlessBuilding.packetHandler.sendToServer(new BlockBrokenMessage(lookingAt)); + + //play sound + if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK) { BlockPos blockPos = lookingAt.getBlockPos(); IBlockState state = player.world.getBlockState(blockPos); SoundType soundtype = state.getBlock().getSoundType(state, player.world, blockPos, player); diff --git a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java index a5e8f4d..ee3e3c3 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java @@ -55,14 +55,17 @@ public class BlockPreviewRenderer { List itemStacks; BlockPos firstPos; BlockPos secondPos; + boolean breaking; - public PlacedData(float time, List coordinates, List blockStates, List itemStacks, BlockPos firstPos, BlockPos secondPos) { + public PlacedData(float time, List coordinates, List blockStates, + List itemStacks, BlockPos firstPos, BlockPos secondPos, boolean breaking) { this.time = time; this.coordinates = coordinates; this.blockStates = blockStates; this.itemStacks = itemStacks; this.firstPos = firstPos; this.secondPos = secondPos; + this.breaking = breaking; } } @@ -73,17 +76,18 @@ public class BlockPreviewRenderer { public static void render(EntityPlayer player, ModifierSettings modifierSettings, ModeSettings modeSettings) { //Render placed blocks with dissolve effect - for (int i = 0; i < placedDataList.size(); i++) { - PlacedData placed = placedDataList.get(i); - if (placed.coordinates != null && !placed.coordinates.isEmpty()) { + //Use fancy shader if config allows, otherwise no dissolve + if (BuildConfig.visuals.useShaders) { + RenderHandler.beginBlockPreviews(); + for (int i = 0; i < placedDataList.size(); i++) { + PlacedData placed = placedDataList.get(i); + if (placed.coordinates != null && !placed.coordinates.isEmpty()) { - RenderHandler.beginBlockPreviews(); - - float dissolve = (ClientProxy.ticksInGame - placed.time) / (float) BuildConfig.visuals.dissolveTime; - renderBlockPreviews(placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false); - - RenderHandler.endBlockPreviews(); + float dissolve = (ClientProxy.ticksInGame - placed.time) / (float) BuildConfig.visuals.dissolveTime; + renderBlockPreviews(placed.coordinates, placed.blockStates, placed.itemStacks, dissolve, placed.firstPos, placed.secondPos, false, placed.breaking); + } } + RenderHandler.endBlockPreviews(); } //Expire placedDataList.removeIf(placed -> placed.time + BuildConfig.visuals.dissolveTime < ClientProxy.ticksInGame); @@ -122,16 +126,17 @@ public class BlockPreviewRenderer { //Unless alwaysShowBlockPreview is true in config if (doRenderBlockPreviews(modifierSettings, modeSettings, startPos)) { - RenderHandler.beginBlockPreviews(); - IBuildMode buildModeInstance = modeSettings.getBuildMode().instance; if (buildModeInstance.getSideHit(player) != null) sideHit = buildModeInstance.getSideHit(player); if (buildModeInstance.getHitVec(player) != null) hitVec = buildModeInstance.getHitVec(player); if (sideHit != null) { + //Should be red? + boolean breaking = BuildModes.currentlyBreakingClient.get(player) != null && BuildModes.currentlyBreakingClient.get(player); + //get coordinates - List startCoordinates = BuildModes.findCoordinates(player, startPos); + List startCoordinates = BuildModes.findCoordinates(player, startPos, breaking || modifierSettings.doQuickReplace()); BlockPos firstPos = BlockPos.ORIGIN, secondPos = BlockPos.ORIGIN; //Remember first and last pos for the shader @@ -157,8 +162,19 @@ public class BlockPreviewRenderer { hitVec = new Vec3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), Math.abs(hitVec.z - ((int) hitVec.z))); + + //Get blockstates List itemStacks = new ArrayList<>(); - List blockStates = BuildModifiers.findBlockStates(player, startCoordinates, hitVec, sideHit, itemStacks); + List blockStates = new ArrayList<>(); + if (breaking) { + //Find blockstate of world + for (BlockPos coordinate : newCoordinates) { + blockStates.add(player.world.getBlockState(coordinate)); + } + } else { + blockStates = BuildModifiers.findBlockStates(player, startCoordinates, hitVec, sideHit, itemStacks); + } + //Check if they are different from previous //TODO fix triggering when moving player @@ -173,7 +189,7 @@ public class BlockPreviewRenderer { //if so, renew randomness of randomizer bag ItemRandomizerBag.renewRandomness(); //and play sound (max once every tick) - if (newCoordinates.size() > 1 && blockStates.size() > 1 && soundTime < ClientProxy.ticksInGame - 0) { + if (startCoordinates.size() > 1 && blockStates.size() > 1 && soundTime < ClientProxy.ticksInGame - 0) { soundTime = ClientProxy.ticksInGame; //player.playSound(EffortlessBuilding.SOUND_BUILD_CLICK, 0.2f, 1f); player.playSound(blockStates.get(0).getBlock().getSoundType(blockStates.get(0), player.world, @@ -183,12 +199,30 @@ public class BlockPreviewRenderer { //Render block previews if (blockStates.size() != 0 && newCoordinates.size() == blockStates.size()) { - renderBlockPreviews(newCoordinates, blockStates, itemStacks, 0f, firstPos, secondPos, true); + //Use fancy shader if config allows, otherwise outlines + if (BuildConfig.visuals.useShaders && newCoordinates.size() < BuildConfig.visuals.shaderTreshold) { + + RenderHandler.beginBlockPreviews(); + + renderBlockPreviews(newCoordinates, blockStates, itemStacks, 0f, firstPos, secondPos, !breaking, breaking); + + RenderHandler.endBlockPreviews(); + } else { + + RenderHandler.beginLines(); + + Vec3d color = new Vec3d(1f, 1f, 1f); + if (breaking) color = new Vec3d(1f, 0f, 0f); + + for (int i = newCoordinates.size() - 1; i >= 0; i--) { + RenderHandler.renderBlockOutline(newCoordinates.get(i), color); + } + + RenderHandler.endLines(); + } } } - RenderHandler.endBlockPreviews(); - RenderHandler.beginLines(); //Draw outlines if tool in hand //Find proper raytrace: either normal range or increased range depending on canBreakFar @@ -205,7 +239,7 @@ public class BlockPreviewRenderer { IBlockState blockState = player.world.getBlockState(coordinate); if (!blockState.getBlock().isAir(blockState, player.world, coordinate)) { if (SurvivalHelper.canBreak(player.world, player, coordinate) || i == 0) { - RenderHandler.renderBlockOutline(coordinate); + RenderHandler.renderBlockOutline(coordinate, new Vec3d(0f, 0f, 0f)); } } } @@ -214,6 +248,7 @@ public class BlockPreviewRenderer { } } + //Whether to draw any block previews or outlines public static boolean doRenderBlockPreviews(ModifierSettings modifierSettings, ModeSettings modeSettings, BlockPos startPos) { return modeSettings.getBuildMode() != BuildModes.BuildModeEnum.Normal || (startPos != null && BuildModifiers.isEnabled(modifierSettings, startPos)) || @@ -222,8 +257,9 @@ public class BlockPreviewRenderer { protected static void renderBlockPreviews(List coordinates, List blockStates, List itemStacks, float dissolve, BlockPos firstPos, - BlockPos secondPos, boolean checkCanPlace) { + BlockPos secondPos, boolean checkCanPlace, boolean red) { EntityPlayer player = Minecraft.getMinecraft().player; + ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher(); if (coordinates.isEmpty()) return; @@ -231,22 +267,21 @@ public class BlockPreviewRenderer { for (int i = coordinates.size() - 1; i >= 0; i--) { BlockPos blockPos = coordinates.get(i); IBlockState blockState = blockStates.get(i); - ItemStack itemstack = itemStacks.get(i); - if(CompatHelper.isItemBlockProxy(itemstack)) + ItemStack itemstack = itemStacks.isEmpty() ? ItemStack.EMPTY : itemStacks.get(i); + if (CompatHelper.isItemBlockProxy(itemstack)) itemstack = CompatHelper.getItemBlockByState(itemstack, blockState); //Check if can place //If check is turned off, check if blockstate is the same (for dissolve effect) - if (SurvivalHelper.canPlace(player.world, player, blockPos, blockState, itemstack, true, EnumFacing.UP) || - (!checkCanPlace && player.world.getBlockState(blockPos) == blockState)) { + if ((!checkCanPlace /*&& player.world.getBlockState(blockPos) == blockState*/) || + SurvivalHelper.canPlace(player.world, player, blockPos, blockState, itemstack, modifierSettings.doQuickReplace(), EnumFacing.UP)) { ShaderHandler.useShader(ShaderHandler.dissolve, generateShaderCallback(dissolve, new Vec3d(blockPos), new Vec3d(firstPos), new Vec3d(secondPos), - blockPos == secondPos)); + blockPos == secondPos, red)); RenderHandler.renderBlockPreview(dispatcher, blockPos, blockState); } } - } public static void onBlocksPlaced() { @@ -256,18 +291,45 @@ public class BlockPreviewRenderer { //Check if block previews are enabled if (doRenderBlockPreviews(modifierSettings, modeSettings, previousFirstPos)) { + //Save current coordinates, blockstates and itemstacks - placedDataList.add(new PlacedData(ClientProxy.ticksInGame, previousCoordinates, previousBlockStates, - previousItemStacks, previousFirstPos, previousSecondPos)); + if (!previousCoordinates.isEmpty() && previousBlockStates.size() == previousCoordinates.size() && + previousCoordinates.size() < BuildConfig.visuals.shaderTreshold) { + + placedDataList.add(new PlacedData(ClientProxy.ticksInGame, previousCoordinates, previousBlockStates, + previousItemStacks, previousFirstPos, previousSecondPos, false)); + } } } - private static Consumer generateShaderCallback(final float dissolve, final Vec3d blockpos, final Vec3d firstpos, final Vec3d secondpos, final boolean highlight) { + public static void onBlocksBroken() { + EntityPlayerSP player = Minecraft.getMinecraft().player; + ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); + ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); + + //Check if block previews are enabled + if (doRenderBlockPreviews(modifierSettings, modeSettings, previousFirstPos)) { + + //Save current coordinates, blockstates and itemstacks + if (!previousCoordinates.isEmpty() && previousBlockStates.size() == previousCoordinates.size() && + previousCoordinates.size() < BuildConfig.visuals.shaderTreshold) { + + placedDataList.add(new PlacedData(ClientProxy.ticksInGame, previousCoordinates, previousBlockStates, + previousItemStacks, previousFirstPos, previousSecondPos, true)); + } + } + + } + + private static Consumer generateShaderCallback(final float dissolve, final Vec3d blockpos, + final Vec3d firstpos, final Vec3d secondpos, + final boolean highlight, final boolean red) { Minecraft mc = Minecraft.getMinecraft(); return (Integer shader) -> { int percentileUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "dissolve"); int highlightUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "highlight"); + int redUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "red"); int blockposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "blockpos"); int firstposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "firstpos"); int secondposUniform = ARBShaderObjects.glGetUniformLocationARB(shader, "secondpos"); @@ -298,6 +360,8 @@ public class BlockPreviewRenderer { ARBShaderObjects.glUniform1fARB(percentileUniform, dissolve); //highlight ARBShaderObjects.glUniform1iARB(highlightUniform, highlight ? 1 : 0); + //red + ARBShaderObjects.glUniform1iARB(redUniform, red ? 1 : 0); }; } } diff --git a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java index 3293ddb..816439f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java @@ -200,17 +200,17 @@ public class RenderHandler implements IWorldEventListener { GlStateManager.popMatrix(); } - protected static void renderBlockOutline(BlockPos pos) { - renderBlockOutline(pos, pos); + protected static void renderBlockOutline(BlockPos pos, Vec3d color) { + renderBlockOutline(pos, pos, color); } //Renders outline. Pos1 has to be minimal x,y,z and pos2 maximal x,y,z - protected static void renderBlockOutline(BlockPos pos1, BlockPos pos2) { + protected static void renderBlockOutline(BlockPos pos1, BlockPos pos2, Vec3d color) { GL11.glLineWidth(2); AxisAlignedBB aabb = new AxisAlignedBB(pos1, pos2.add(1, 1, 1)).grow(0.0020000000949949026); - RenderGlobal.drawSelectionBoundingBox(aabb, 0f, 0f, 0f, 0.4f); + RenderGlobal.drawSelectionBoundingBox(aabb, (float) color.x, (float) color.y, (float) color.z, 0.4f); } diff --git a/src/main/resources/assets/effortlessbuilding/shaders/dissolve.frag b/src/main/resources/assets/effortlessbuilding/shaders/dissolve.frag index 1a34ca8..7377da6 100644 --- a/src/main/resources/assets/effortlessbuilding/shaders/dissolve.frag +++ b/src/main/resources/assets/effortlessbuilding/shaders/dissolve.frag @@ -4,6 +4,7 @@ uniform int time; // Passed in, see ShaderHelper.java uniform float dissolve; // Passed in via Callback uniform int highlight; +uniform int red; uniform vec3 blockpos; uniform vec3 firstpos; uniform vec3 secondpos; @@ -87,10 +88,12 @@ void main() { color.rgb -= 0.05; - if(highlight == 1 && dissolve == 0.0) { - color.r += 0.0; - color.g += 0.1; - color.b -= 0.2; + if (highlight == 1 && dissolve == 0.0) { + color.rgb += vec3(0.0, 0.1, -0.2); + } + + if (red == 1) { + color.rgb += vec3(0.4, -0.3, -0.5); } color.r = max(0, min(1, color.r)); diff --git a/src/main/resources/assets/effortlessbuilding/shaders/dissolve.vert b/src/main/resources/assets/effortlessbuilding/shaders/dissolve.vert index f147aa0..c3975f6 100644 --- a/src/main/resources/assets/effortlessbuilding/shaders/dissolve.vert +++ b/src/main/resources/assets/effortlessbuilding/shaders/dissolve.vert @@ -1,14 +1,5 @@ #version 120 -uniform int time; // Passed in, see ShaderHelper.java - -uniform float dissolve; // Passed in via Callback -uniform int highlight; -uniform vec3 blockpos; -uniform vec3 firstpos; -uniform vec3 secondpos; -uniform sampler2D mask; - varying vec4 position; varying vec3 normal;