diff --git a/build.gradle b/build.gradle index 87cac77..3505fa0 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge' //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. -version = "1.12.2-2.2" +version = "1.12.2-2.4" group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "effortlessbuilding" diff --git a/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java b/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java index 8fd5101..b9fc71f 100644 --- a/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java +++ b/src/main/java/nl/requios/effortlessbuilding/BuildConfig.java @@ -55,7 +55,7 @@ public class BuildConfig { } public static class Visuals { - @Comment({"Show a block preview if you have a block in hand on build mode Normal"}) + @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.", diff --git a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java index 18c80ce..d914fe4 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java +++ b/src/main/java/nl/requios/effortlessbuilding/EffortlessBuilding.java @@ -39,7 +39,7 @@ public class EffortlessBuilding { public static final String MODID = "effortlessbuilding"; public static final String NAME = "Effortless Building"; - public static final String VERSION = "1.12.2-2.2"; + public static final String VERSION = "1.12.2-2.4"; @Mod.Instance(EffortlessBuilding.MODID) public static EffortlessBuilding instance; @@ -86,14 +86,17 @@ public class EffortlessBuilding EffortlessBuilding.packetHandler.registerMessage(ModeSettingsMessage.MessageHandler.class, ModeSettingsMessage.class, 1, Side.SERVER); EffortlessBuilding.packetHandler.registerMessage(ModeSettingsMessage.MessageHandler.class, ModeSettingsMessage.class, 1, Side.CLIENT); - EffortlessBuilding.packetHandler.registerMessage(BlockPlacedMessage.MessageHandler.class, BlockPlacedMessage.class, 2, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(BlockPlacedMessage.MessageHandler.class, BlockPlacedMessage.class, 2, Side.CLIENT); + EffortlessBuilding.packetHandler.registerMessage(ModeActionMessage.MessageHandler.class, ModeActionMessage.class, 2, Side.SERVER); + EffortlessBuilding.packetHandler.registerMessage(ModeActionMessage.MessageHandler.class, ModeActionMessage.class, 2, Side.CLIENT); - EffortlessBuilding.packetHandler.registerMessage(BlockBrokenMessage.MessageHandler.class, BlockBrokenMessage.class, 3, Side.SERVER); + EffortlessBuilding.packetHandler.registerMessage(BlockPlacedMessage.MessageHandler.class, BlockPlacedMessage.class, 3, Side.SERVER); + EffortlessBuilding.packetHandler.registerMessage(BlockPlacedMessage.MessageHandler.class, BlockPlacedMessage.class, 3, Side.CLIENT); - EffortlessBuilding.packetHandler.registerMessage(CancelModeMessage.MessageHandler.class, CancelModeMessage.class, 4, Side.SERVER); + EffortlessBuilding.packetHandler.registerMessage(BlockBrokenMessage.MessageHandler.class, BlockBrokenMessage.class, 4, Side.SERVER); - EffortlessBuilding.packetHandler.registerMessage(RequestLookAtMessage.MessageHandler.class, RequestLookAtMessage.class, 5, Side.CLIENT); + EffortlessBuilding.packetHandler.registerMessage(CancelModeMessage.MessageHandler.class, CancelModeMessage.class, 5, Side.SERVER); + + EffortlessBuilding.packetHandler.registerMessage(RequestLookAtMessage.MessageHandler.class, RequestLookAtMessage.class, 6, Side.CLIENT); proxy.preInit(event); } diff --git a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java index 2d349ab..c3d22cb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java @@ -8,7 +8,6 @@ import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.config.Config; @@ -19,7 +18,6 @@ import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.fml.client.event.ConfigChangedEvent; import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.eventhandler.Event; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; @@ -29,7 +27,6 @@ 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; import java.util.List; @@ -87,10 +84,10 @@ public class EventHandler BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); - if (buildMode != BuildModes.BuildModeEnum.Normal || modifierSettings.doQuickReplace()) { + if (buildMode != BuildModes.BuildModeEnum.NORMAL || modifierSettings.doQuickReplace()) { event.setCanceled(true); } else { - //Normal mode, let vanilla handle block placing + //NORMAL mode, let vanilla handle block placing //But modifiers and QuickReplace should still work //Send message to client, which sends message back with raytrace info @@ -105,10 +102,10 @@ public class EventHandler //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 && ReachHelper.canBreakFar(event.getPlayer())) { + if (buildMode != BuildModes.BuildModeEnum.NORMAL && ReachHelper.canBreakFar(event.getPlayer())) { event.setCanceled(true); } else { - //Normal mode, let vanilla handle block breaking + //NORMAL mode, let vanilla handle block breaking //But modifiers and QuickReplace should still work //Dont break the original block yourself, otherwise Tinkers Hammer and Veinminer won't work BuildModes.onBlockBroken(event.getPlayer(), event.getPos(), false); diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java index 5a81d0d..1c6b98d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java @@ -1,12 +1,10 @@ package nl.requios.effortlessbuilding.buildmode; -import net.minecraft.block.state.IBlockState; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; -import net.minecraftforge.event.world.BlockEvent; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.*; import nl.requios.effortlessbuilding.compatibility.CompatHelper; @@ -28,15 +26,15 @@ public class BuildModes { public static Dictionary currentlyBreakingServer = new Hashtable<>(); public enum BuildModeEnum { - Normal ("Normal", new Normal()), - NormalPlus ("Normal+", new NormalPlus()), - Line ("Line", new Line()), - Wall ("Wall", new Wall()), - Floor ("Floor", new Floor()), - DiagonalLine ("", new DiagonalLine()), - DiagonalWall ("", new DiagonalWall()), - SlopeFloor ("", new SlopeFloor()), - Cube ("", new Cube()); + NORMAL("effortlessbuilding.mode.normal", new Normal()), + NORMAL_PLUS("effortlessbuilding.mode.normal_plus", new NormalPlus()), + LINE("effortlessbuilding.mode.line", new Line()), + WALL("effortlessbuilding.mode.wall", new Wall()), + FLOOR("effortlessbuilding.mode.floor", new Floor()), + DIAGONAL_LINE("effortlessbuilding.mode.diagonal_line", new DiagonalLine()), + DIAGONAL_WALL("effortlessbuilding.mode.diagonal_wall", new DiagonalWall()), + SLOPE_FLOOR("effortlessbuilding.mode.slope_floor", new SlopeFloor()), + CUBE("effortlessbuilding.mode.cube", new Cube()); public String name; public IBuildMode instance; @@ -83,7 +81,7 @@ public class BuildModes { //Check if player reach does not exceed startpos int maxReach = ReachHelper.getMaxReach(player); - if (player.getPosition().distanceSq(startPos) > maxReach * maxReach) { + if (buildMode != BuildModeEnum.NORMAL && player.getPosition().distanceSq(startPos) > maxReach * maxReach) { EffortlessBuilding.log(player, "Placement exceeds your reach."); return; } @@ -110,7 +108,7 @@ public class BuildModes { Vec3d hitVec = buildMode.instance.getHitVec(player); if (hitVec == null) hitVec = message.getHitVec(); - BuildModifiers.onBlockPlaced(player, coordinates, sideHit, hitVec); + BuildModifiers.onBlockPlaced(player, coordinates, sideHit, hitVec, message.getPlaceStartPos()); //Only works when finishing a buildmode is equal to placing some blocks //No intermediate blocks allowed diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java index c038ca1..d55b02d 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/Floor.java @@ -98,6 +98,7 @@ public class Floor implements IBuildMode { if (selected == null) return list; //check if it doesnt go through blocks + //TODO collision within a 1 block radius to selected is fine if (!skipRaytrace) { RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false); if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java new file mode 100644 index 0000000..6fd2858 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeOptions.java @@ -0,0 +1,50 @@ +package nl.requios.effortlessbuilding.buildmode; + +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.text.TextFormatting; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; +import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; +import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui; + +public class ModeOptions { + + public enum ActionEnum { + UNDO, + REDO, + REPLACE, + OPEN_MODIFIER_SETTINGS + } + + //Called on both client and server + public static void performAction(EntityPlayer player, ActionEnum action) { + EffortlessBuilding.log("Doing "+action.name()); + + switch (action) { + case UNDO: + break; + case REDO: + break; + case REPLACE: + ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); + modifierSettings.setQuickReplace(!modifierSettings.doQuickReplace()); + EffortlessBuilding.log(player, "Set " + TextFormatting.GOLD + "Quick Replace " + TextFormatting.RESET + ( + modifierSettings.doQuickReplace() ? "on" : "off"), true); + break; + case OPEN_MODIFIER_SETTINGS: + if (player.world.isRemote) + openModifierSettings(); + break; + } + } + + @SideOnly(Side.CLIENT) + private static void openModifierSettings() { + Minecraft.getMinecraft().displayGuiScreen(new ModifierSettingsGui()); + RadialMenu.instance.setVisibility(0f); + } + +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeSettingsManager.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeSettingsManager.java index 50ba186..62009f9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeSettingsManager.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/ModeSettingsManager.java @@ -55,7 +55,7 @@ public class ModeSettingsManager { } public static class ModeSettings { - private BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.Normal; + private BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.NORMAL; public ModeSettings() { } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java index c15b3a5..157622e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/Wall.java @@ -122,6 +122,7 @@ public class Wall implements IBuildMode { if (selected == null) return list; //check if it doesnt go through blocks + //TODO collision within a 1 block radius to selected is fine if (!skipRaytrace) { RayTraceResult rayTraceResult = player.world.rayTraceBlocks(start, selected, false, true, false); if (rayTraceResult != null && rayTraceResult.typeOfHit == RayTraceResult.Type.BLOCK) { diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java index 77d95cf..f154e98 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 startCoordinates, EnumFacing sideHit, Vec3d hitVec) { + public static void onBlockPlaced(EntityPlayer player, List startCoordinates, EnumFacing sideHit, Vec3d hitVec, boolean placeStartPos) { World world = player.world; ItemRandomizerBag.renewRandomness(); @@ -46,7 +46,7 @@ public class BuildModifiers { } //place blocks - for (int i = 0; i < coordinates.size(); i++) { + for (int i = placeStartPos ? 0 : 1; i < coordinates.size(); i++) { BlockPos blockPos = coordinates.get(i); IBlockState blockState = blockStates.get(i); ItemStack itemStack = itemStacks.get(i); diff --git a/src/main/java/nl/requios/effortlessbuilding/capability/ModeCapabilityManager.java b/src/main/java/nl/requios/effortlessbuilding/capability/ModeCapabilityManager.java index 68fd8ed..8002b4e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/capability/ModeCapabilityManager.java +++ b/src/main/java/nl/requios/effortlessbuilding/capability/ModeCapabilityManager.java @@ -3,8 +3,6 @@ package nl.requios.effortlessbuilding.capability; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.CapabilityInject; import net.minecraftforge.common.capabilities.ICapabilitySerializable; @@ -66,7 +64,7 @@ public class ModeCapabilityManager { //TODO add mode settings - ModeSettings modeSettings = new ModeSettings(BuildModes.BuildModeEnum.Normal); + ModeSettings modeSettings = new ModeSettings(BuildModes.BuildModeEnum.NORMAL); instance.setModeData(modeSettings); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java index 66e1d69..f4e5aac 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmode/RadialMenu.java @@ -3,8 +3,13 @@ package nl.requios.effortlessbuilding.gui.buildmode; import java.util.ArrayList; import java.util.concurrent.TimeUnit; +import net.minecraft.client.resources.I18n; +import net.minecraft.util.text.TextFormatting; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.proxy.ClientProxy; +import org.apache.commons.lang3.text.WordUtils; import org.lwjgl.opengl.GL11; import com.google.common.base.Stopwatch; @@ -33,7 +38,7 @@ public class RadialMenu extends GuiScreen { private float visibility = 0.0f; private Stopwatch lastChange = Stopwatch.createStarted(); public BuildModeEnum switchTo = null; - //public ButtonAction doAction = null; + public ModeOptions.ActionEnum doAction = null; public boolean actionUsed = false; private float clampVis(final float f) { @@ -50,6 +55,10 @@ public class RadialMenu extends GuiScreen { lastChange = Stopwatch.createStarted(); } + public void setVisibility(float visibility) { + this.visibility = visibility; + } + public boolean isVisible() { return visibility > 0.001; } @@ -67,34 +76,18 @@ public class RadialMenu extends GuiScreen { public double y1, y2; public boolean highlighted; - //public final ButtonAction action; - public TextureAtlasSprite icon; - public int color; + public final ModeOptions.ActionEnum action; public String name; public EnumFacing textSide; - public MenuButton(final String name, /*final ButtonAction action,*/ final double x, final double y, - final TextureAtlasSprite ico, final EnumFacing textSide) { - this.name = name; - //this.action = action; - x1 = x; - x2 = x + 18; - y1 = y; - y2 = y + 18; - icon = ico; - color = 0xffffff; - this.textSide = textSide; - } - - public MenuButton(final String name, /*final ButtonAction action,*/ final double x, final double y, - final int col, final EnumFacing textSide) { - this.name = name; - //this.action = action; - x1 = x; - x2 = x + 18; - y1 = y; - y2 = y + 18; - color = col; + public MenuButton(final String name, final ModeOptions.ActionEnum action, final double x, final double y, + final EnumFacing textSide) { + this.name = I18n.format(name); + this.action = action; + x1 = x - 10; + x2 = x + 10; + y1 = y - 10; + y2 = y + 10; this.textSide = textSide; } @@ -115,13 +108,7 @@ public class RadialMenu extends GuiScreen { @Override public void drawScreen(final int mouseX, final int mouseY, final float partialTicks) { - //TODO chisels compat -// final ChiselToolType tool = ClientSide.instance.getHeldToolType( EnumHand.MAIN_HAND ); -// -// if ( tool != null ) -// { -// return; -// } + if (!isVisible()) return; GlStateManager.pushMatrix(); GlStateManager.translate( 0.0F, 0.0F, 200.0F ); @@ -150,7 +137,8 @@ public class RadialMenu extends GuiScreen { final double ringInnerEdge = 20; final double ringOuterEdge = 50; - final double textDistance = 65; + final double textDistance = 60; + final double buttonDistance = 90; final double quarterCircle = Math.PI / 2.0; if ( mouseRadians < -quarterCircle ) { @@ -160,15 +148,17 @@ public class RadialMenu extends GuiScreen { final ArrayList modes = new ArrayList(); final ArrayList buttons = new ArrayList(); -// buttons.add( new MenuButton( "mod.chiselsandbits.other.undo", ButtonAction.UNDO, textDistance, -20, ClientSide.undoIcon, EnumFacing.EAST ) ); -// buttons.add( new MenuButton( "mod.chiselsandbits.other.redo", ButtonAction.REDO, textDistance, 4, ClientSide.redoIcon, EnumFacing.EAST ) ); + buttons.add(new MenuButton("effortlessbuilding.action.undo", ModeOptions.ActionEnum.UNDO, -buttonDistance - 26, -13, EnumFacing.UP)); + buttons.add(new MenuButton("effortlessbuilding.action.redo", ModeOptions.ActionEnum.REDO, -buttonDistance, -13, EnumFacing.UP)); + buttons.add(new MenuButton("effortlessbuilding.action.open_modifier_settings", ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS, -buttonDistance - 26, 13, EnumFacing.DOWN)); + buttons.add(new MenuButton("effortlessbuilding.action.replace", ModeOptions.ActionEnum.REPLACE, -buttonDistance, 13, EnumFacing.DOWN)); for (final BuildModeEnum mode : BuildModeEnum.values()) { modes.add(new MenuRegion(mode)); } switchTo = null; - //doAction = null; + doAction = null; if (!modes.isEmpty()) { final int totalModes = Math.max( 3, modes.size() ); @@ -217,9 +207,9 @@ public class RadialMenu extends GuiScreen { || inTriangle(x1m1, y1m1, x1m2, y1m2, x2m2, y2m2, mouseXCenter, mouseYCenter); if (beginRadians <= mouseRadians && mouseRadians <= endRadians && isMouseInQuad) { - r = 0.6f;//0.6f; - g = 0.8f;//0.3f; - b = 1f;//0.0f; + r = 0.6f; + g = 0.8f; + b = 1f; a = 0.6f; menuRegion.highlighted = true; switchTo = menuRegion.mode; @@ -235,19 +225,24 @@ public class RadialMenu extends GuiScreen { } for (final MenuButton btn : buttons) { - final float a = 0.5f; - float f = 0f; + float r = 0.8f; + float g = 0.8f; + float b = 0.8f; + float a = 0.5f; if (btn.x1 <= mouseXCenter && btn.x2 >= mouseXCenter && btn.y1 <= mouseYCenter && btn.y2 >= mouseYCenter) { - f = 1; + r = 0.0f; + g = 0.5f; + b = 1f; + a = 0.6f; btn.highlighted = true; - //doAction = btn.action; + doAction = btn.action; } - buffer.pos(middleX + btn.x1, middleY + btn.y1, zLevel).color(f, f, f, a).endVertex(); - buffer.pos(middleX + btn.x1, middleY + btn.y2, zLevel).color(f, f, f, a).endVertex(); - buffer.pos(middleX + btn.x2, middleY + btn.y2, zLevel).color(f, f, f, a).endVertex(); - buffer.pos(middleX + btn.x2, middleY + btn.y1, zLevel).color(f, f, f, a).endVertex(); + buffer.pos(middleX + btn.x1, middleY + btn.y1, zLevel).color(r, g, b, a).endVertex(); + buffer.pos(middleX + btn.x1, middleY + btn.y2, zLevel).color(r, g, b, a).endVertex(); + buffer.pos(middleX + btn.x2, middleY + btn.y2, zLevel).color(r, g, b, a).endVertex(); + buffer.pos(middleX + btn.x2, middleY + btn.y1, zLevel).color(r, g, b, a).endVertex(); } tessellator.draw(); @@ -263,12 +258,12 @@ public class RadialMenu extends GuiScreen { buffer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); - for (final MenuRegion mnuRgn : modes) { + for (final MenuRegion menuRegion : modes) { - final double x = (mnuRgn.x1 + mnuRgn.x2) * 0.5 * (ringOuterEdge * 0.6 + 0.4 * ringInnerEdge); - final double y = (mnuRgn.y1 + mnuRgn.y2) * 0.5 * (ringOuterEdge * 0.6 + 0.4 * ringInnerEdge); + final double x = (menuRegion.x1 + menuRegion.x2) * 0.5 * (ringOuterEdge * 0.6 + 0.4 * ringInnerEdge); + final double y = (menuRegion.y1 + menuRegion.y2) * 0.5 * (ringOuterEdge * 0.6 + 0.4 * ringInnerEdge); - final TextureAtlasSprite sprite = ClientProxy.getBuildModeIcon(mnuRgn.mode); + final TextureAtlasSprite sprite = ClientProxy.getBuildModeIcon(menuRegion.mode); final double scalex = 16 * 0.5; final double scaley = 16 * 0.5; @@ -280,55 +275,53 @@ public class RadialMenu extends GuiScreen { final float f = 1f; final float a = 1f; - final double u1 = 0f; - final double u2 = 16f; - final double v1 = 0f; - final double v2 = 16f; + final double u1 = 0; + final double u2 = 16; + final double v1 = 0; + final double v2 = 16; - buffer.pos(middleX + x1, middleY + y1, zLevel).tex( sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex(); - buffer.pos(middleX + x1, middleY + y2, zLevel).tex( sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex(); - buffer.pos(middleX + x2, middleY + y2, zLevel).tex( sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex(); - buffer.pos(middleX + x2, middleY + y1, zLevel).tex( sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex(); + buffer.pos(middleX + x1, middleY + y1, zLevel).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex(); + buffer.pos(middleX + x1, middleY + y2, zLevel).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex(); + buffer.pos(middleX + x2, middleY + y2, zLevel).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex(); + buffer.pos(middleX + x2, middleY + y1, zLevel).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex(); } - for (final MenuButton btn : buttons) { + for (final MenuButton button : buttons) { - final float f = switchTo == null ? 1.0f : 0.5f; - final float a = 1.0f; + final float f = 1f; + final float a = 1f; final double u1 = 0; final double u2 = 16; final double v1 = 0; final double v2 = 16; - final TextureAtlasSprite sprite = btn.icon == null ? Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(ModelLoader.White.LOCATION.toString()) : btn.icon; + final TextureAtlasSprite sprite = ClientProxy.getModeOptionIcon(button.action); - final double btnx1 = btn.x1 + 1; - final double btnx2 = btn.x2 - 1; - final double btny1 = btn.y1 + 1; - final double btny2 = btn.y2 - 1; + final double btnmiddleX = (button.x1 + button.x2) / 2.0; + final double btnmiddleY = (button.y1 + button.y2) / 2.0; + final double btnx1 = btnmiddleX - 8; + final double btnx2 = btnmiddleX + 8; + final double btny1 = btnmiddleY - 8; + final double btny2 = btnmiddleY + 8; - final float red = f * ((btn.color >> 16 & 0xff) / 255.0f); - final float green = f * ((btn.color >> 8 & 0xff) / 255.0f); - final float blue = f * ((btn.color & 0xff) / 255.0f); - - buffer.pos(middleX + btnx1, middleY + btny1, zLevel).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1)).color(red, green, blue, a).endVertex(); - buffer.pos(middleX + btnx1, middleY + btny2, zLevel).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v2)).color(red, green, blue, a).endVertex(); - buffer.pos(middleX + btnx2, middleY + btny2, zLevel).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v2)).color(red, green, blue, a).endVertex(); - buffer.pos(middleX + btnx2, middleY + btny1, zLevel).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v1)).color(red, green, blue, a).endVertex(); + buffer.pos(middleX + btnx1, middleY + btny1, zLevel).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex(); + buffer.pos(middleX + btnx1, middleY + btny2, zLevel).tex(sprite.getInterpolatedU(u1), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex(); + buffer.pos(middleX + btnx2, middleY + btny2, zLevel).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v2)).color(f, f, f, a).endVertex(); + buffer.pos(middleX + btnx2, middleY + btny1, zLevel).tex(sprite.getInterpolatedU(u2), sprite.getInterpolatedV(v1)).color(f, f, f, a).endVertex(); } tessellator.draw(); - for (final MenuRegion mnuRgn : modes) { + for (final MenuRegion menuRegion : modes) { - if (mnuRgn.highlighted) { - final double x = (mnuRgn.x1 + mnuRgn.x2) * 0.5; - final double y = (mnuRgn.y1 + mnuRgn.y2) * 0.5; + if (menuRegion.highlighted) { + final double x = (menuRegion.x1 + menuRegion.x2) * 0.5; + final double y = (menuRegion.y1 + menuRegion.y2) * 0.5; int fixed_x = (int) (x * textDistance); - final int fixed_y = (int) (y * textDistance); - final String text = mnuRgn.mode.name; + final int fixed_y = (int) (y * textDistance) - fontRenderer.FONT_HEIGHT / 2; + final String text = I18n.format(menuRegion.mode.name); if ( x <= -0.2 ) { fixed_x -= fontRenderer.getStringWidth(text); @@ -340,29 +333,45 @@ public class RadialMenu extends GuiScreen { } } - for (final MenuButton btn : buttons) { - if (btn.highlighted) { - final String text = btn.name; + for (final MenuButton button : buttons) { + if (button.highlighted) { + String text = TextFormatting.AQUA + button.name; + int wrap = 120; + String keybind = TextFormatting.GRAY + "(None)"; - if (btn.textSide == EnumFacing.WEST) { + //Add keybind in brackets + if (button.action == ModeOptions.ActionEnum.REPLACE) { + keybind = TextFormatting.GRAY + " (" + WordUtils.capitalizeFully(ClientProxy.keyBindings[1].getDisplayName().toLowerCase()) + ")"; + } + if (button.action == ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) { + keybind = TextFormatting.GRAY + " (" + WordUtils.capitalizeFully(ClientProxy.keyBindings[0].getDisplayName()) + ")"; + } - fontRenderer.drawStringWithShadow( text, (int) ( middleX + btn.x1 - 8 ) - fontRenderer.getStringWidth( text ), - (int) ( middleY + btn.y1 + 6 ), 0xffffffff ); + if (button.textSide == EnumFacing.WEST) { - } else if (btn.textSide == EnumFacing.EAST) { + fontRenderer.drawSplitString( text, (int) (middleX + button.x1 - 8 ) - fontRenderer.getStringWidth(text), + (int) (middleY + button.y1 + 6), wrap, 0xffffffff); - fontRenderer.drawStringWithShadow( text, (int) ( middleX + btn.x2 + 8 ), - (int) ( middleY + btn.y1 + 6 ), 0xffffffff ); + } else if (button.textSide == EnumFacing.EAST) { - } else if (btn.textSide == EnumFacing.UP) { + fontRenderer.drawSplitString(text, (int) (middleX + button.x2 + 8), + (int) (middleY + button.y1 + 6 ), wrap, 0xffffffff); - fontRenderer.drawStringWithShadow( text, (int) ( middleX + ( btn.x1 + btn.x2 ) * 0.5 - fontRenderer.getStringWidth( text ) * 0.5 ), - (int) ( middleY + btn.y1 - 14 ), 0xffffffff ); + } else if (button.textSide == EnumFacing.UP || button.textSide == EnumFacing.NORTH) { - } else if (btn.textSide == EnumFacing.DOWN) { + fontRenderer.drawSplitString( text, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(text) * 0.5), + (int) (middleY + button.y1 - 26), wrap,0xffffffff); - fontRenderer.drawStringWithShadow( text, (int) ( middleX + ( btn.x1 + btn.x2 ) * 0.5 - fontRenderer.getStringWidth( text ) * 0.5 ), - (int) ( middleY + btn.y1 + 24 ), 0xffffffff ); + fontRenderer.drawSplitString( keybind, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(keybind) * 0.5), + (int) (middleY + button.y1 - 14), wrap,0xffffffff); + + } else if (button.textSide == EnumFacing.DOWN || button.textSide == EnumFacing.SOUTH) { + + fontRenderer.drawSplitString(text, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(text) * 0.5), + (int) (middleY + button.y1 + 24), wrap, 0xffffffff); + + fontRenderer.drawSplitString(keybind, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(keybind) * 0.5), + (int) (middleY + button.y1 + 36), wrap, 0xffffffff); } @@ -387,14 +396,16 @@ public class RadialMenu extends GuiScreen { /** * Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton */ + @Override protected void mouseClicked(int mouseX, int mouseY, int mouseButton ) { - if (mouseButton == 0) { - this.mc.displayGuiScreen(null); - - if (this.mc.currentScreen == null) { - this.mc.setIngameFocus(); - } - } + EffortlessBuilding.log("mouse clicked"); +// if (mouseButton == 0) { +// this.mc.displayGuiScreen(null); +// +// if (this.mc.currentScreen == null) { +// this.mc.setIngameFocus(); +// } +// } } } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArraySettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArraySettingsGui.java index 585fe0d..2f0e867 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArraySettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ArraySettingsGui.java @@ -142,7 +142,7 @@ public class ArraySettingsGui extends GuiCollapsibleScrollEntry { @Override public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) { - super.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY); + super.mousePressed(slotIndex, mouseX, mouseY, mouseEvent, relativeX, relativeY); arrayNumberFieldList.forEach(numberField -> numberField.mouseClicked(mouseX, mouseY, mouseEvent)); boolean insideArrayEnabledLabel = mouseX >= left && mouseX < right && relativeY >= -2 && relativeY < 12; diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiScrollPane.java b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiScrollPane.java index 7cdf5ab..dde35c0 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiScrollPane.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/elements/GuiScrollPane.java @@ -73,22 +73,24 @@ public class GuiScrollPane extends GuiListExtended { int insideLeft = this.left + this.width / 2 - this.getListWidth() / 2 + 2; int insideTop = this.top + 4 - (int)this.amountScrolled; - if (this.hasListHeader) - { + if (this.hasListHeader) { this.drawListHeader(insideLeft, insideTop, tessellator); } //All entries this.drawSelectionBox(insideLeft, insideTop, mouseXIn, mouseYIn, partialTicks); GlStateManager.disableDepth(); + //Dirt overlays on top and bottom // this.overlayBackground(0, this.top, 255, 255); // this.overlayBackground(this.bottom, this.height, 255, 255); + GlStateManager.enableBlend(); GlStateManager.tryBlendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ZERO, GlStateManager.DestFactor.ONE); GlStateManager.disableAlpha(); GlStateManager.shadeModel(7425); GlStateManager.disableTexture2D(); + // //top fade // bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); // bufferbuilder.pos((double)this.left, (double)(this.top + 5), 0.0D).tex(0.0D, 1.0D).color(100, 100, 100, 0).endVertex(); @@ -96,6 +98,7 @@ public class GuiScrollPane extends GuiListExtended { // bufferbuilder.pos((double)this.right, (double)this.top, 0.0D).tex(1.0D, 0.0D).color(100, 100, 100, 100).endVertex(); // bufferbuilder.pos((double)this.left, (double)this.top, 0.0D).tex(0.0D, 0.0D).color(100, 100, 100, 100).endVertex(); // tessellator.draw(); + // //top line // bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); // bufferbuilder.pos((double)this.left, (double)this.top, 0.0D).tex(0.0D, 1.0D).color(20, 20, 20, 255).endVertex(); @@ -103,6 +106,7 @@ public class GuiScrollPane extends GuiListExtended { // bufferbuilder.pos((double)this.right, (double)(this.top - 1), 0.0D).tex(1.0D, 0.0D).color(20, 20, 20, 255).endVertex(); // bufferbuilder.pos((double)this.left, (double)(this.top - 1), 0.0D).tex(0.0D, 0.0D).color(20, 20, 20, 255).endVertex(); // tessellator.draw(); + // //bottom fade // bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); // bufferbuilder.pos((double)this.left, (double)this.bottom, 0.0D).tex(0.0D, 1.0D).color(10, 10, 10, 100).endVertex(); @@ -110,6 +114,7 @@ public class GuiScrollPane extends GuiListExtended { // bufferbuilder.pos((double)this.right, (double)(this.bottom - 5), 0.0D).tex(1.0D, 0.0D).color(10, 10, 10, 0).endVertex(); // bufferbuilder.pos((double)this.left, (double)(this.bottom - 5), 0.0D).tex(0.0D, 0.0D).color(10, 10, 10, 0).endVertex(); // tessellator.draw(); + // //bottom line // bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); // bufferbuilder.pos((double)this.left, (double)(this.bottom + 1), 0.0D).tex(0.0D, 1.0D).color(20, 20, 20, 255).endVertex(); @@ -137,12 +142,14 @@ public class GuiScrollPane extends GuiListExtended { bufferbuilder.pos((double)scrollBarRight, (double)this.top, 0.0D).tex(1.0D, 0.0D).color(0, 0, 0, 255).endVertex(); bufferbuilder.pos((double)scrollBarLeft, (double)this.top, 0.0D).tex(0.0D, 0.0D).color(0, 0, 0, 255).endVertex(); tessellator.draw(); + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); bufferbuilder.pos((double)scrollBarLeft, (double)(l1 + k1), 0.0D).tex(0.0D, 1.0D).color(128, 128, 128, 255).endVertex(); bufferbuilder.pos((double)scrollBarRight, (double)(l1 + k1), 0.0D).tex(1.0D, 1.0D).color(128, 128, 128, 255).endVertex(); bufferbuilder.pos((double)scrollBarRight, (double)l1, 0.0D).tex(1.0D, 0.0D).color(128, 128, 128, 255).endVertex(); bufferbuilder.pos((double)scrollBarLeft, (double)l1, 0.0D).tex(0.0D, 0.0D).color(128, 128, 128, 255).endVertex(); tessellator.draw(); + bufferbuilder.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); bufferbuilder.pos((double)scrollBarLeft, (double)(l1 + k1 - 1), 0.0D).tex(0.0D, 1.0D).color(192, 192, 192, 255).endVertex(); bufferbuilder.pos((double)(scrollBarRight - 1), (double)(l1 + k1 - 1), 0.0D).tex(1.0D, 1.0D).color(192, 192, 192, 255).endVertex(); @@ -184,8 +191,7 @@ public class GuiScrollPane extends GuiListExtended { public int getSlotIndexFromScreenCoords(int posX, int posY) { int left = this.left + (this.width - this.getListWidth()) / 2; int right = this.left + (this.width + this.getListWidth()) / 2; - int relativeMouseY = posY - this.top - this.headerPadding + (int)this.amountScrolled - 4; //click height in content dimensions - //int slotIndex = relativeMouseY / this.slotHeight; + int relativeMouseY = getRelativeMouseY(mouseY, 0); //Iterate over every entry until relativeMouseY falls within its height for (int i = 0; i < listEntries.size(); i++) { @@ -201,25 +207,33 @@ public class GuiScrollPane extends GuiListExtended { @Override public boolean mouseClicked(int mouseX, int mouseY, int mouseEvent) { - if (this.isMouseYWithinSlotBounds(mouseY)) - { - int i = this.getSlotIndexFromScreenCoords(mouseX, mouseY); + int selectedSlot = this.getSlotIndexFromScreenCoords(mouseX, mouseY); + int relativeX = getRelativeMouseX(mouseX); - if (i >= 0) - { - int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2; - int k = this.top + 4 - this.getAmountScrolled() + getContentHeight(i) + this.headerPadding; - int relativeX = mouseX - j; - int relativeY = mouseY - k; - - if (this.getListEntry(i).mousePressed(i, mouseX, mouseY, mouseEvent, relativeX, relativeY)) - { - this.setEnabled(false); - return true; - } - } + //Always pass through mouseclicked, to be able to unfocus textfields + for (int i = 0; i < this.listEntries.size(); i++) { + int relativeY = getRelativeMouseY(mouseY, i); + this.getListEntry(i).mousePressed(selectedSlot, mouseX, mouseY, mouseEvent, relativeX, relativeY); } + +// if (this.isMouseYWithinSlotBounds(mouseY)) +// { +// int i = this.getSlotIndexFromScreenCoords(mouseX, mouseY); +// +// if (i >= 0) +// { +// int relativeX = getRelativeMouseX(mouseX); +// int relativeY = getRelativeMouseY(mouseY, i); +// +// if (this.getListEntry(i).mousePressed(i, mouseX, mouseY, mouseEvent, relativeX, relativeY)) +// { +// this.setEnabled(false); +// return true; +// } +// } +// } + return false; } @@ -228,10 +242,8 @@ public class GuiScrollPane extends GuiListExtended { { for (int i = 0; i < this.getSize(); ++i) { - int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2; - int k = this.top + 4 - this.getAmountScrolled() + getContentHeight(i) + this.headerPadding; - int relativeX = x - j; - int relativeY = y - k; + int relativeX = getRelativeMouseX(mouseX); + int relativeY = getRelativeMouseY(mouseY, i); this.getListEntry(i).mouseReleased(i, x, y, mouseEvent, relativeX, relativeY); } @@ -246,9 +258,8 @@ public class GuiScrollPane extends GuiListExtended { this.mouseY <= this.bottom) { int i = this.left + (this.width - this.getListWidth()) / 2; int j = this.left + (this.width + this.getListWidth()) / 2; - int relativeMouseY = this.mouseY - this.top - this.headerPadding + (int) this.amountScrolled - - 4; //click height in content dimensions int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY); + int relativeMouseY = getRelativeMouseY(mouseY, slotIndex); if (slotIndex > -1) { this.elementClicked(slotIndex, false, this.mouseX, this.mouseY); @@ -265,9 +276,8 @@ public class GuiScrollPane extends GuiListExtended { if (this.mouseY >= this.top && this.mouseY <= this.bottom) { int i2 = this.left + (this.width - this.getListWidth()) / 2; int j2 = this.left + (this.width + this.getListWidth()) / 2; - int relativeMouseY = this.mouseY - this.top - this.headerPadding + (int) this.amountScrolled - - 4; //click height in content dimensions int slotIndex = getSlotIndexFromScreenCoords(this.mouseX, this.mouseY); + int relativeMouseY = getRelativeMouseY(mouseY, slotIndex); if (slotIndex > -1) { boolean flag = slotIndex == this.selectedElement && @@ -383,6 +393,26 @@ public class GuiScrollPane extends GuiListExtended { } } + private int getRelativeMouseX(int mouseX) { + int j = this.left + this.width / 2 - this.getListWidth() / 2 + 2; + return mouseX - j; + } + + private int getRelativeMouseY(int mouseY, int contentIndex) { + int k = this.top + 4 - this.getAmountScrolled() + getContentHeight(contentIndex) + this.headerPadding; + int relativeMouseY = mouseY - k; + + //Content might be centered, adjust relative mouse y accordingly + int contentHeight = getContentHeight(); + int insideHeight = this.bottom - this.top - 4; + + if (contentHeight < insideHeight) { + //it fits, so we can center it vertically + relativeMouseY -= (insideHeight - contentHeight) / 2; + } + return relativeMouseY; + } + //PASSTHROUGHS public int initGui(int id, List buttonList) { for (IScrollEntry entry : this.listEntries) { diff --git a/src/main/java/nl/requios/effortlessbuilding/network/BlockPlacedMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/BlockPlacedMessage.java index 3492dd3..a7ef5b2 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/BlockPlacedMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/BlockPlacedMessage.java @@ -25,19 +25,22 @@ public class BlockPlacedMessage implements IMessage { private BlockPos blockPos; private EnumFacing sideHit; private Vec3d hitVec; + private boolean placeStartPos; //prevent double placing in normal mode public BlockPlacedMessage() { this.blockHit = false; this.blockPos = BlockPos.ORIGIN; this.sideHit = EnumFacing.UP; this.hitVec = new Vec3d(0, 0, 0); + this.placeStartPos = true; } - public BlockPlacedMessage(RayTraceResult result) { + public BlockPlacedMessage(RayTraceResult result, boolean placeStartPos) { this.blockHit = result.typeOfHit == RayTraceResult.Type.BLOCK; this.blockPos = result.getBlockPos(); this.sideHit = result.sideHit; this.hitVec = result.hitVec; + this.placeStartPos = placeStartPos; } public boolean isBlockHit() { @@ -56,6 +59,10 @@ public class BlockPlacedMessage implements IMessage { return hitVec; } + public boolean getPlaceStartPos() { + return placeStartPos; + } + @Override public void toBytes(ByteBuf buf) { buf.writeBoolean(blockHit); @@ -66,6 +73,7 @@ public class BlockPlacedMessage implements IMessage { buf.writeDouble(hitVec.x); buf.writeDouble(hitVec.y); buf.writeDouble(hitVec.z); + buf.writeBoolean(placeStartPos); } @Override @@ -74,6 +82,7 @@ public class BlockPlacedMessage implements IMessage { blockPos = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); sideHit = EnumFacing.byIndex(buf.readInt()); hitVec = new Vec3d(buf.readDouble(), buf.readDouble(), buf.readDouble()); + placeStartPos = buf.readBoolean(); } // The params of the IMessageHandler are diff --git a/src/main/java/nl/requios/effortlessbuilding/network/ModeActionMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/ModeActionMessage.java new file mode 100644 index 0000000..bbd9955 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/network/ModeActionMessage.java @@ -0,0 +1,62 @@ +package nl.requios.effortlessbuilding.network; + +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.IThreadListener; +import net.minecraftforge.fml.common.network.simpleimpl.IMessage; +import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; +import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; +import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.buildmode.BuildModes; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; +import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; + +import static nl.requios.effortlessbuilding.buildmode.ModeSettingsManager.*; + +/** + * Shares mode settings (see ModeSettingsManager) between server and client + */ +public class ModeActionMessage implements IMessage { + + private ModeOptions.ActionEnum action; + + public ModeActionMessage() { + } + + public ModeActionMessage(ModeOptions.ActionEnum action) { + this.action = action; + } + + @Override + public void toBytes(ByteBuf buf) { + buf.writeInt(action.ordinal()); + } + + @Override + public void fromBytes(ByteBuf buf) { + action = ModeOptions.ActionEnum.values()[buf.readInt()]; + } + + // The params of the IMessageHandler are + public static class MessageHandler implements IMessageHandler { + // Do note that the default constructor is required, but implicitly defined in this case + + @Override + public IMessage onMessage(ModeActionMessage message, MessageContext ctx) { + //EffortlessBuilding.log("message received on " + ctx.side + " side"); + + // The value that was sent + ModeOptions.ActionEnum action = message.action; + + // Execute the action on the main server thread by adding it as a scheduled task + IThreadListener threadListener = EffortlessBuilding.proxy.getThreadListenerFromContext(ctx); + threadListener.addScheduledTask(() -> { + EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); + + ModeOptions.performAction(player, action); + }); + // No response packet + return null; + } + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/network/ModeSettingsMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/ModeSettingsMessage.java index aaa617c..89d7a04 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/ModeSettingsMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/ModeSettingsMessage.java @@ -29,16 +29,12 @@ public class ModeSettingsMessage implements IMessage { @Override public void toBytes(ByteBuf buf) { buf.writeInt(modeSettings.getBuildMode().ordinal()); - - //TODO add mode settings } @Override public void fromBytes(ByteBuf buf) { BuildModes.BuildModeEnum buildMode = BuildModes.BuildModeEnum.values()[buf.readInt()]; - //TODO add mode settings - modeSettings = new ModeSettings(buildMode); } diff --git a/src/main/java/nl/requios/effortlessbuilding/network/RequestLookAtMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/RequestLookAtMessage.java index 2b0196f..aed5d73 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/RequestLookAtMessage.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/RequestLookAtMessage.java @@ -42,7 +42,8 @@ public class RequestLookAtMessage implements IMessage { if (ctx.side == Side.CLIENT){ //Received clientside //Send back your info - return new BlockPlacedMessage(ClientProxy.previousLookAt); + //Prevent double placing in normal mode with placeStartPos false + return new BlockPlacedMessage(ClientProxy.previousLookAt, false); } return null; } diff --git a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java index b98b683..2869ea6 100644 --- a/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java +++ b/src/main/java/nl/requios/effortlessbuilding/proxy/ClientProxy.java @@ -33,7 +33,6 @@ import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; -import net.minecraftforge.fml.common.eventhandler.Event; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.InputEvent; @@ -42,6 +41,7 @@ import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import net.minecraftforge.fml.relauncher.Side; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmode.BuildModes; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; @@ -67,6 +67,7 @@ public class ClientProxy implements IProxy { public static int ticksInGame = 0; private static final HashMap buildModeIcons = new HashMap<>(); + private static final HashMap modeOptionIcons = new HashMap<>(); @Override public void preInit(FMLPreInitializationEvent event) { @@ -139,12 +140,22 @@ public class ClientProxy implements IProxy { final ResourceLocation sprite = new ResourceLocation("effortlessbuilding", "icons/" + mode.name().toLowerCase()); buildModeIcons.put( mode, map.registerSprite(sprite)); } + + for ( final ModeOptions.ActionEnum action : ModeOptions.ActionEnum.values() ) + { + final ResourceLocation sprite = new ResourceLocation("effortlessbuilding", "icons/" + action.name().toLowerCase()); + modeOptionIcons.put( action, map.registerSprite(sprite)); + } } public static TextureAtlasSprite getBuildModeIcon(BuildModes.BuildModeEnum mode) { return buildModeIcons.get(mode); } + public static TextureAtlasSprite getModeOptionIcon(ModeOptions.ActionEnum action) { + return modeOptionIcons.get(action); + } + @SubscribeEvent public static void onClientTick(TickEvent.ClientTickEvent event) { @@ -189,7 +200,7 @@ public class ClientProxy implements IProxy { BuildModes.BuildModeEnum buildMode = ModeSettingsManager.getModeSettings(player).getBuildMode(); if (Minecraft.getMinecraft().currentScreen != null || - buildMode == BuildModes.BuildModeEnum.Normal || + buildMode == BuildModes.BuildModeEnum.NORMAL || RadialMenu.instance.isVisible()) { return; } @@ -203,17 +214,18 @@ public class ClientProxy implements IProxy { ItemStack currentItemStack = player.getHeldItem(EnumHand.MAIN_HAND); if (currentItemStack.getItem() instanceof ItemBlock || (CompatHelper.isItemBlockProxy(currentItemStack) && !player.isSneaking())) { + ItemStack itemStack = CompatHelper.getItemBlockFromStack(currentItemStack); //find position in distance RayTraceResult lookingAt = getLookingAt(player); - BuildModes.onBlockPlacedMessage(player, lookingAt == null ? new BlockPlacedMessage() : new BlockPlacedMessage(lookingAt)); - EffortlessBuilding.packetHandler.sendToServer(lookingAt == null ? new BlockPlacedMessage() : new BlockPlacedMessage(lookingAt)); + BuildModes.onBlockPlacedMessage(player, lookingAt == null ? new BlockPlacedMessage() : new BlockPlacedMessage(lookingAt, true)); + EffortlessBuilding.packetHandler.sendToServer(lookingAt == null ? new BlockPlacedMessage() : new BlockPlacedMessage(lookingAt, true)); //play sound if further than normal if (lookingAt != null && lookingAt.typeOfHit == RayTraceResult.Type.BLOCK && (lookingAt.hitVec.subtract(player.getPositionEyes(1f))).lengthSquared() > 25f) { - IBlockState state = ((ItemBlock) currentItemStack.getItem()).getBlock().getDefaultState(); + IBlockState state = ((ItemBlock) itemStack.getItem()).getBlock().getDefaultState(); BlockPos blockPos = lookingAt.getBlockPos(); SoundType soundType = state.getBlock().getSoundType(state, player.world, blockPos, player); player.world.playSound(player, player.getPosition(), soundType.getPlaceSound(), SoundCategory.BLOCKS, @@ -221,7 +233,7 @@ public class ClientProxy implements IProxy { player.swingArm(EnumHand.MAIN_HAND); } } - } else if (buildMode == BuildModes.BuildModeEnum.NormalPlus) { + } else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { placeCooldown--; } } else { @@ -250,7 +262,7 @@ public class ClientProxy implements IProxy { 0.4f, soundtype.getPitch() * 1f); player.swingArm(EnumHand.MAIN_HAND); } - } else if (buildMode == BuildModes.BuildModeEnum.NormalPlus) { + } else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { breakCooldown--; } } @@ -260,6 +272,13 @@ public class ClientProxy implements IProxy { } else { breakCooldown = 0; } + + if (mc.gameSettings.keyBindAttack.isPressed()) { + if (RadialMenu.instance.isVisible()) { + EffortlessBuilding.log(player, "mouse click"); + } + } + } @SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true) @@ -267,7 +286,7 @@ public class ClientProxy implements IProxy { EntityPlayerSP player = Minecraft.getMinecraft().player; //Remember to send packet to server if necessary - //Show HUD + //Show Modifier Settings GUI if (keyBindings[0].isPressed()) { //Disabled if max reach is 0, might be set in the config that way. if (ReachHelper.getMaxReach(player) == 0) { diff --git a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java index d682dcc..0992932 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/BlockPreviewRenderer.java @@ -13,7 +13,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraft.util.SoundCategory; -import net.minecraft.util.SoundEvent; import net.minecraft.util.math.*; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -99,7 +98,7 @@ public class BlockPreviewRenderer { //Render block previews RayTraceResult lookingAt = ClientProxy.getLookingAt(player); - if (modeSettings.getBuildMode() == BuildModes.BuildModeEnum.Normal) lookingAt = Minecraft.getMinecraft().objectMouseOver; + if (modeSettings.getBuildMode() == BuildModes.BuildModeEnum.NORMAL) lookingAt = Minecraft.getMinecraft().objectMouseOver; ItemStack mainhand = player.getHeldItemMainhand(); boolean toolInHand = !(!mainhand.isEmpty() && CompatHelper.isItemBlockProxy(mainhand)); @@ -260,9 +259,9 @@ 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)) || - BuildConfig.visuals.alwaysShowBlockPreview; + return modeSettings.getBuildMode() != BuildModes.BuildModeEnum.NORMAL || + (startPos != null && BuildModifiers.isEnabled(modifierSettings, startPos)) || + BuildConfig.visuals.alwaysShowBlockPreview; } protected static void renderBlockPreviews(List coordinates, List blockStates, diff --git a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java index 656100d..03ee075 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java @@ -9,6 +9,7 @@ import net.minecraft.client.renderer.BlockRendererDispatcher; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderGlobal; import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.client.resources.I18n; import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; @@ -28,6 +29,7 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.relauncher.Side; import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.buildmode.ModeOptions; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; @@ -35,6 +37,7 @@ import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper; +import nl.requios.effortlessbuilding.network.ModeActionMessage; import nl.requios.effortlessbuilding.network.ModeSettingsMessage; import nl.requios.effortlessbuilding.proxy.ClientProxy; import org.lwjgl.input.Mouse; @@ -88,19 +91,24 @@ public class RenderHandler implements IWorldEventListener { EffortlessBuilding.log(player, "Build modes are disabled until your reach has increased. Increase your reach with craftable reach upgrades."); } } else { - if ( !RadialMenu.instance.actionUsed ) { + if (!RadialMenu.instance.actionUsed) { ModeSettingsManager.ModeSettings modeSettings = ModeSettingsManager.getModeSettings(player); - if ( RadialMenu.instance.switchTo != null ) { + if (RadialMenu.instance.switchTo != null) { playRadialMenuSound(); modeSettings.setBuildMode(RadialMenu.instance.switchTo); ModeSettingsManager.setModeSettings(player, modeSettings); EffortlessBuilding.packetHandler.sendToServer(new ModeSettingsMessage(modeSettings)); - EffortlessBuilding.log(player, modeSettings.getBuildMode().name, true); + EffortlessBuilding.log(player, I18n.format(modeSettings.getBuildMode().name), true); } - //TODO change buildmode settings + //Perform button action + ModeOptions.ActionEnum action = RadialMenu.instance.doAction; + if (action != null) { + ModeOptions.performAction(player, action); + EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action)); + } playRadialMenuSound(); } @@ -123,12 +131,12 @@ public class RenderHandler implements IWorldEventListener { KeyBinding.unPressAllKeys(); } - final int k1 = Mouse.getX() * res.getScaledWidth() / mc.displayWidth; - final int l1 = res.getScaledHeight() - Mouse.getY() * res.getScaledHeight() / mc.displayHeight - 1; + final int mouseX = Mouse.getX() * res.getScaledWidth() / mc.displayWidth; + final int mouseY = res.getScaledHeight() - Mouse.getY() * res.getScaledHeight() / mc.displayHeight - 1; - net.minecraftforge.client.ForgeHooksClient.drawScreen(RadialMenu.instance, k1, l1, event.getPartialTicks()); + net.minecraftforge.client.ForgeHooksClient.drawScreen(RadialMenu.instance, mouseX, mouseY, event.getPartialTicks()); } else { - if (wasVisible) { + if (wasVisible && RadialMenu.instance.doAction != ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) { mc.setIngameFocus(); } } diff --git a/src/main/resources/assets/effortlessbuilding/lang/en_us.lang b/src/main/resources/assets/effortlessbuilding/lang/en_us.lang index 71d1b34..5dada4d 100644 --- a/src/main/resources/assets/effortlessbuilding/lang/en_us.lang +++ b/src/main/resources/assets/effortlessbuilding/lang/en_us.lang @@ -9,4 +9,19 @@ item.effortlessbuilding:reach_upgrade1.name=Reach Upgrade 1 item.effortlessbuilding:reach_upgrade2.name=Reach Upgrade 2 item.effortlessbuilding:reach_upgrade3.name=Reach Upgrade 3 +effortlessbuilding.mode.normal=Normal +effortlessbuilding.mode.normal_plus=Normal+ +effortlessbuilding.mode.line=Line +effortlessbuilding.mode.wall=Wall +effortlessbuilding.mode.floor=Floor +effortlessbuilding.mode.diagonal_line=Diagonal Line (WIP) +effortlessbuilding.mode.diagonal_wall=Diagonal Wall (WIP) +effortlessbuilding.mode.slope_floor=Slope Floor (WIP) +effortlessbuilding.mode.cube=Cube (WIP) + +effortlessbuilding.action.undo=Undo (WIP) +effortlessbuilding.action.redo=Redo (WIP) +effortlessbuilding.action.replace=Replace +effortlessbuilding.action.open_modifier_settings=Open Modifier Settings + commands.reach.usage=/reach \ No newline at end of file diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/cube.png b/src/main/resources/assets/effortlessbuilding/textures/icons/cube.png index cc18b1f..c9afbbd 100644 Binary files a/src/main/resources/assets/effortlessbuilding/textures/icons/cube.png and b/src/main/resources/assets/effortlessbuilding/textures/icons/cube.png differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/diagonal_line.png b/src/main/resources/assets/effortlessbuilding/textures/icons/diagonal_line.png new file mode 100644 index 0000000..69e565e Binary files /dev/null and b/src/main/resources/assets/effortlessbuilding/textures/icons/diagonal_line.png differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/diagonal_wall.png b/src/main/resources/assets/effortlessbuilding/textures/icons/diagonal_wall.png new file mode 100644 index 0000000..ac20e48 Binary files /dev/null and b/src/main/resources/assets/effortlessbuilding/textures/icons/diagonal_wall.png differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/diagonalline.png b/src/main/resources/assets/effortlessbuilding/textures/icons/diagonalline.png deleted file mode 100644 index 792fc8d..0000000 Binary files a/src/main/resources/assets/effortlessbuilding/textures/icons/diagonalline.png and /dev/null differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/diagonalwall.png b/src/main/resources/assets/effortlessbuilding/textures/icons/diagonalwall.png deleted file mode 100644 index faec81f..0000000 Binary files a/src/main/resources/assets/effortlessbuilding/textures/icons/diagonalwall.png and /dev/null differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/normalplus.png b/src/main/resources/assets/effortlessbuilding/textures/icons/normal_plus.png similarity index 100% rename from src/main/resources/assets/effortlessbuilding/textures/icons/normalplus.png rename to src/main/resources/assets/effortlessbuilding/textures/icons/normal_plus.png diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/open_modifier_settings.png b/src/main/resources/assets/effortlessbuilding/textures/icons/open_modifier_settings.png new file mode 100644 index 0000000..2d846ea Binary files /dev/null and b/src/main/resources/assets/effortlessbuilding/textures/icons/open_modifier_settings.png differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/redo.png b/src/main/resources/assets/effortlessbuilding/textures/icons/redo.png new file mode 100644 index 0000000..2d846ea Binary files /dev/null and b/src/main/resources/assets/effortlessbuilding/textures/icons/redo.png differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/replace.png b/src/main/resources/assets/effortlessbuilding/textures/icons/replace.png new file mode 100644 index 0000000..2d846ea Binary files /dev/null and b/src/main/resources/assets/effortlessbuilding/textures/icons/replace.png differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/slope_floor.png b/src/main/resources/assets/effortlessbuilding/textures/icons/slope_floor.png new file mode 100644 index 0000000..c786eaf Binary files /dev/null and b/src/main/resources/assets/effortlessbuilding/textures/icons/slope_floor.png differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/slopefloor.png b/src/main/resources/assets/effortlessbuilding/textures/icons/slopefloor.png deleted file mode 100644 index f680346..0000000 Binary files a/src/main/resources/assets/effortlessbuilding/textures/icons/slopefloor.png and /dev/null differ diff --git a/src/main/resources/assets/effortlessbuilding/textures/icons/undo.png b/src/main/resources/assets/effortlessbuilding/textures/icons/undo.png new file mode 100644 index 0000000..2d846ea Binary files /dev/null and b/src/main/resources/assets/effortlessbuilding/textures/icons/undo.png differ