Added undo, redo functionality.
All placements use blocks from entire inventory now. Added block count and dimensions in actionbar when placing/breaking blocks. Added undo, redo, replace and 'open modifier settings' icons. Fixed not being able to break blocks in creative when starting the selection on a tallgrass (instabreaking) block.
@@ -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.4"
|
||||
version = "1.12.2-2.5"
|
||||
group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
|
||||
archivesBaseName = "effortlessbuilding"
|
||||
|
||||
|
||||
@@ -52,6 +52,10 @@ public class BuildConfig {
|
||||
"The block in front of you always counts as 100%."})
|
||||
@RangeInt(min = 0, max = 200)
|
||||
public int miningTimePercentage = 50;
|
||||
|
||||
@Comment({"How many placements are remembered for the undo functionality."})
|
||||
@RequiresMcRestart
|
||||
public int undoStackSize = 5;
|
||||
}
|
||||
|
||||
public static class Visuals {
|
||||
|
||||
@@ -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.4";
|
||||
public static final String VERSION = "1.12.2-2.5";
|
||||
|
||||
@Mod.Instance(EffortlessBuilding.MODID)
|
||||
public static EffortlessBuilding instance;
|
||||
|
||||
@@ -119,8 +119,7 @@ public class BuildModes {
|
||||
//Use a network message to break blocks in the distance using clientside mouse input
|
||||
public static void onBlockBrokenMessage(EntityPlayer player, BlockBrokenMessage message) {
|
||||
|
||||
if (ReachHelper.canBreakFar(player) &&
|
||||
!CompatHelper.chiselsAndBitsProxy.isHoldingChiselTool(EnumHand.MAIN_HAND)) {
|
||||
if (ReachHelper.canBreakFar(player)) {
|
||||
|
||||
BlockPos startPos = message.isBlockHit() ? message.getBlockPos() : null;
|
||||
onBlockBroken(player, startPos, true);
|
||||
@@ -132,7 +131,7 @@ public class BuildModes {
|
||||
//Check if not in the middle of placing
|
||||
Dictionary<EntityPlayer, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer;
|
||||
if (currentlyBreaking.get(player) != null && !currentlyBreaking.get(player)) {
|
||||
//Cancel placing
|
||||
//Cancel breaking
|
||||
initializeMode(player);
|
||||
return;
|
||||
}
|
||||
@@ -177,4 +176,20 @@ public class BuildModes {
|
||||
|
||||
ModeSettingsManager.getModeSettings(player).getBuildMode().instance.initialize(player);
|
||||
}
|
||||
|
||||
public static boolean isCurrentlyPlacing(EntityPlayer player) {
|
||||
Dictionary<EntityPlayer, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer;
|
||||
return currentlyBreaking.get(player) != null && !currentlyBreaking.get(player);
|
||||
}
|
||||
|
||||
public static boolean isCurrentlyBreaking(EntityPlayer player) {
|
||||
Dictionary<EntityPlayer, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer;
|
||||
return currentlyBreaking.get(player) != null && currentlyBreaking.get(player);
|
||||
}
|
||||
|
||||
//Either placing or breaking
|
||||
public static boolean isActive(EntityPlayer player) {
|
||||
Dictionary<EntityPlayer, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer;
|
||||
return currentlyBreaking.get(player) != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ 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.buildmodifier.UndoRedo;
|
||||
import nl.requios.effortlessbuilding.gui.buildmode.RadialMenu;
|
||||
import nl.requios.effortlessbuilding.gui.buildmodifier.ModifierSettingsGui;
|
||||
|
||||
@@ -21,12 +22,15 @@ public class ModeOptions {
|
||||
|
||||
//Called on both client and server
|
||||
public static void performAction(EntityPlayer player, ActionEnum action) {
|
||||
EffortlessBuilding.log("Doing "+action.name());
|
||||
|
||||
switch (action) {
|
||||
case UNDO:
|
||||
UndoRedo.undo(player);
|
||||
EffortlessBuilding.log(player, "Undo", true);
|
||||
break;
|
||||
case REDO:
|
||||
UndoRedo.redo(player);
|
||||
EffortlessBuilding.log(player, "Redo", true);
|
||||
break;
|
||||
case REPLACE:
|
||||
ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package nl.requios.effortlessbuilding.buildmodifier;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BlockSet {
|
||||
private List<BlockPos> coordinates;
|
||||
private List<IBlockState> blockStates;
|
||||
private Vec3d hitVec;
|
||||
private BlockPos firstPos;
|
||||
private BlockPos secondPos;
|
||||
|
||||
public BlockSet(List<BlockPos> coordinates, List<IBlockState> blockStates, Vec3d hitVec,
|
||||
BlockPos firstPos, BlockPos secondPos) {
|
||||
this.coordinates = coordinates;
|
||||
this.blockStates = blockStates;
|
||||
this.hitVec = hitVec;
|
||||
this.firstPos = firstPos;
|
||||
this.secondPos = secondPos;
|
||||
}
|
||||
|
||||
public List<BlockPos> getCoordinates() {
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public List<IBlockState> getBlockStates() {
|
||||
return blockStates;
|
||||
}
|
||||
|
||||
public Vec3d getHitVec() {
|
||||
return hitVec;
|
||||
}
|
||||
|
||||
public BlockPos getFirstPos() {
|
||||
return firstPos;
|
||||
}
|
||||
|
||||
public BlockPos getSecondPos() {
|
||||
return secondPos;
|
||||
}
|
||||
}
|
||||
@@ -11,19 +11,21 @@ import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import nl.requios.effortlessbuilding.BuildConfig;
|
||||
import nl.requios.effortlessbuilding.EffortlessBuilding;
|
||||
import nl.requios.effortlessbuilding.compatibility.CompatHelper;
|
||||
import nl.requios.effortlessbuilding.helper.FixedStack;
|
||||
import nl.requios.effortlessbuilding.helper.InventoryHelper;
|
||||
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
|
||||
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
|
||||
import nl.requios.effortlessbuilding.network.BlockPlacedMessage;
|
||||
import nl.requios.effortlessbuilding.render.BlockPreviewRenderer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class BuildModifiers {
|
||||
|
||||
|
||||
//Called from BuildModes
|
||||
public static void onBlockPlaced(EntityPlayer player, List<BlockPos> startCoordinates, EnumFacing sideHit, Vec3d hitVec, boolean placeStartPos) {
|
||||
World world = player.world;
|
||||
@@ -41,23 +43,33 @@ public class BuildModifiers {
|
||||
if (blockStates.size() == 0 || coordinates.size() != blockStates.size()) return;
|
||||
|
||||
if (world.isRemote) {
|
||||
|
||||
BlockPreviewRenderer.onBlocksPlaced();
|
||||
return;
|
||||
}
|
||||
|
||||
//place blocks
|
||||
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);
|
||||
} else {
|
||||
|
||||
if (world.isBlockLoaded(blockPos, true)) {
|
||||
//check itemstack empty
|
||||
if (itemStack.isEmpty()) continue;
|
||||
SurvivalHelper.placeBlock(world, player, blockPos, blockState, itemStack, EnumFacing.UP, hitVec, false, false);
|
||||
//place blocks
|
||||
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);
|
||||
|
||||
if (world.isBlockLoaded(blockPos, true)) {
|
||||
//check itemstack empty
|
||||
if (itemStack.isEmpty()) {
|
||||
//try to find new stack, otherwise continue
|
||||
itemStack = InventoryHelper.findItemStackInInventory(player, blockState);
|
||||
if (itemStack.isEmpty()) continue;
|
||||
}
|
||||
SurvivalHelper.placeBlock(world, player, blockPos, blockState, itemStack, EnumFacing.UP, hitVec, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//add to undo stack
|
||||
BlockPos firstPos = startCoordinates.get(0);
|
||||
BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1);
|
||||
UndoRedo.addUndo(player, new BlockSet(coordinates, blockStates, hitVec, firstPos, secondPos));
|
||||
}
|
||||
|
||||
public static void onBlockBroken(EntityPlayer player, List<BlockPos> posList, boolean breakStartPos) {
|
||||
@@ -73,7 +85,8 @@ public class BuildModifiers {
|
||||
}
|
||||
|
||||
//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;
|
||||
boolean onlyInstaBreaking = !player.isCreative() &&
|
||||
world.getBlockState(posList.get(0)).getBlockHardness(world, posList.get(0)) == 0f;
|
||||
|
||||
//break all those blocks
|
||||
for (int i = breakStartPos ? 0 : 1; i < coordinates.size(); i++) {
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package nl.requios.effortlessbuilding.buildmodifier;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import nl.requios.effortlessbuilding.BuildConfig;
|
||||
import nl.requios.effortlessbuilding.helper.FixedStack;
|
||||
import nl.requios.effortlessbuilding.helper.InventoryHelper;
|
||||
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
|
||||
import nl.requios.effortlessbuilding.render.BlockPreviewRenderer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class UndoRedo {
|
||||
|
||||
private static Map<UUID, FixedStack<BlockSet>> undoStacks = new HashMap<>();
|
||||
private static Map<UUID, FixedStack<BlockSet>> redoStacks = new HashMap<>();
|
||||
|
||||
//add to undo stack
|
||||
public static void addUndo(EntityPlayer player, BlockSet blockSet) {
|
||||
|
||||
//If no stack exists, make one
|
||||
if (!undoStacks.containsKey(player.getUniqueID())) {
|
||||
undoStacks.put(player.getUniqueID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize]));
|
||||
}
|
||||
|
||||
undoStacks.get(player.getUniqueID()).push(blockSet);
|
||||
}
|
||||
|
||||
private static void addRedo(EntityPlayer player, BlockSet blockSet) {
|
||||
|
||||
//If no stack exists, make one
|
||||
if (!redoStacks.containsKey(player.getUniqueID())) {
|
||||
redoStacks.put(player.getUniqueID(), new FixedStack<>(new BlockSet[BuildConfig.survivalBalancers.undoStackSize]));
|
||||
}
|
||||
|
||||
redoStacks.get(player.getUniqueID()).push(blockSet);
|
||||
}
|
||||
|
||||
public static boolean undo(EntityPlayer player) {
|
||||
if (!undoStacks.containsKey(player.getUniqueID())) return false;
|
||||
|
||||
FixedStack<BlockSet> undoStack = undoStacks.get(player.getUniqueID());
|
||||
|
||||
if (undoStack.isEmpty()) return false;
|
||||
|
||||
BlockSet blockSet = undoStack.pop();
|
||||
List<BlockPos> coordinates = blockSet.getCoordinates();
|
||||
List<IBlockState> blockStates = blockSet.getBlockStates();
|
||||
|
||||
//Find up to date itemstacks in player inventory
|
||||
List<ItemStack> itemStacks = findItemStacksInInventory(player, blockStates);
|
||||
|
||||
//break all those blocks
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
BlockPos coordinate = coordinates.get(i);
|
||||
if (player.world.isBlockLoaded(coordinate, false)) {
|
||||
SurvivalHelper.breakBlock(player.world, player, coordinate);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.world.isRemote)
|
||||
BlockPreviewRenderer.onBlocksBroken(coordinates, itemStacks, blockStates, blockSet.getSecondPos(), blockSet.getFirstPos());
|
||||
|
||||
//add to redo
|
||||
addRedo(player, blockSet);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean redo(EntityPlayer player) {
|
||||
if (!redoStacks.containsKey(player.getUniqueID())) return false;
|
||||
|
||||
FixedStack<BlockSet> redoStack = redoStacks.get(player.getUniqueID());
|
||||
|
||||
if (redoStack.isEmpty()) return false;
|
||||
|
||||
BlockSet blockSet = redoStack.pop();
|
||||
List<BlockPos> coordinates = blockSet.getCoordinates();
|
||||
List<IBlockState> blockStates = blockSet.getBlockStates();
|
||||
Vec3d hitVec = blockSet.getHitVec();
|
||||
|
||||
//Find up to date itemstacks in player inventory
|
||||
List<ItemStack> itemStacks = findItemStacksInInventory(player, blockStates);
|
||||
|
||||
//place blocks
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
BlockPos blockPos = coordinates.get(i);
|
||||
IBlockState blockState = blockStates.get(i);
|
||||
ItemStack itemStack = itemStacks.get(i);
|
||||
|
||||
if (player.world.isBlockLoaded(blockPos, true)) {
|
||||
//check itemstack empty
|
||||
if (itemStack.isEmpty()) continue;
|
||||
SurvivalHelper.placeBlock(player.world, player, blockPos, blockState, itemStack, EnumFacing.UP, hitVec, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (player.world.isRemote)
|
||||
BlockPreviewRenderer.onBlocksPlaced(coordinates, itemStacks, blockStates, blockSet.getFirstPos(), blockSet.getSecondPos());
|
||||
|
||||
//add to undo
|
||||
addUndo(player, blockSet);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static List<ItemStack> findItemStacksInInventory(EntityPlayer player, List<IBlockState> blockStates) {
|
||||
List<ItemStack> itemStacks = new ArrayList<>(blockStates.size());
|
||||
for (IBlockState blockState : blockStates) {
|
||||
itemStacks.add(InventoryHelper.findItemStackInInventory(player, blockState));
|
||||
}
|
||||
return itemStacks;
|
||||
}
|
||||
}
|
||||
@@ -265,12 +265,10 @@ public class RadialMenu extends GuiScreen {
|
||||
|
||||
final TextureAtlasSprite sprite = ClientProxy.getBuildModeIcon(menuRegion.mode);
|
||||
|
||||
final double scalex = 16 * 0.5;
|
||||
final double scaley = 16 * 0.5;
|
||||
final double x1 = x - scalex;
|
||||
final double x2 = x + scalex;
|
||||
final double y1 = y - scaley;
|
||||
final double y2 = y + scaley;
|
||||
final double x1 = x - 8;
|
||||
final double x2 = x + 8;
|
||||
final double y1 = y - 8;
|
||||
final double y2 = y + 8;
|
||||
|
||||
final float f = 1f;
|
||||
final float a = 1f;
|
||||
@@ -298,8 +296,8 @@ public class RadialMenu extends GuiScreen {
|
||||
|
||||
final TextureAtlasSprite sprite = ClientProxy.getModeOptionIcon(button.action);
|
||||
|
||||
final double btnmiddleX = (button.x1 + button.x2) / 2.0;
|
||||
final double btnmiddleY = (button.y1 + button.y2) / 2.0;
|
||||
final double btnmiddleX = (button.x1 + button.x2) / 2 + 0.01;
|
||||
final double btnmiddleY = (button.y1 + button.y2) / 2 + 0.01;
|
||||
final double btnx1 = btnmiddleX - 8;
|
||||
final double btnx2 = btnmiddleX + 8;
|
||||
final double btny1 = btnmiddleY - 8;
|
||||
@@ -337,15 +335,23 @@ public class RadialMenu extends GuiScreen {
|
||||
if (button.highlighted) {
|
||||
String text = TextFormatting.AQUA + button.name;
|
||||
int wrap = 120;
|
||||
String keybind = TextFormatting.GRAY + "(None)";
|
||||
String keybind = "None";
|
||||
|
||||
//Add keybind in brackets
|
||||
if (button.action == ModeOptions.ActionEnum.UNDO) {
|
||||
keybind = ClientProxy.keyBindings[4].getDisplayName();
|
||||
}
|
||||
if (button.action == ModeOptions.ActionEnum.REDO) {
|
||||
String sneak = Minecraft.getMinecraft().gameSettings.keyBindSneak.getDisplayName();
|
||||
keybind = sneak + " + " + ClientProxy.keyBindings[4].getDisplayName();
|
||||
}
|
||||
if (button.action == ModeOptions.ActionEnum.REPLACE) {
|
||||
keybind = TextFormatting.GRAY + " (" + WordUtils.capitalizeFully(ClientProxy.keyBindings[1].getDisplayName().toLowerCase()) + ")";
|
||||
keybind = ClientProxy.keyBindings[1].getDisplayName();
|
||||
}
|
||||
if (button.action == ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) {
|
||||
keybind = TextFormatting.GRAY + " (" + WordUtils.capitalizeFully(ClientProxy.keyBindings[0].getDisplayName()) + ")";
|
||||
keybind = ClientProxy.keyBindings[0].getDisplayName();
|
||||
}
|
||||
String keybindFormatted = TextFormatting.GRAY + " (" + WordUtils.capitalizeFully(keybind) + ")";
|
||||
|
||||
if (button.textSide == EnumFacing.WEST) {
|
||||
|
||||
@@ -362,7 +368,7 @@ public class RadialMenu extends GuiScreen {
|
||||
fontRenderer.drawSplitString( text, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(text) * 0.5),
|
||||
(int) (middleY + button.y1 - 26), wrap,0xffffffff);
|
||||
|
||||
fontRenderer.drawSplitString( keybind, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(keybind) * 0.5),
|
||||
fontRenderer.drawSplitString( keybindFormatted, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(keybindFormatted) * 0.5),
|
||||
(int) (middleY + button.y1 - 14), wrap,0xffffffff);
|
||||
|
||||
} else if (button.textSide == EnumFacing.DOWN || button.textSide == EnumFacing.SOUTH) {
|
||||
@@ -370,7 +376,7 @@ public class RadialMenu extends GuiScreen {
|
||||
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),
|
||||
fontRenderer.drawSplitString(keybindFormatted, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(keybindFormatted) * 0.5),
|
||||
(int) (middleY + button.y1 + 36), wrap, 0xffffffff);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
package nl.requios.effortlessbuilding.helper;
|
||||
|
||||
//Stack with fixed size. Removes (overwrites) oldest element on push.
|
||||
public class FixedStack<T> {
|
||||
private T[] stack;
|
||||
private int size;
|
||||
private int top;
|
||||
private int filled = 0; //how many valid items are in the stack
|
||||
|
||||
public FixedStack(T[] stack) {
|
||||
this.stack = stack;
|
||||
this.top = 0;
|
||||
this.size = stack.length;
|
||||
}
|
||||
|
||||
public void push(T object) {
|
||||
if (top == stack.length)
|
||||
top = 0;
|
||||
|
||||
stack[top] = object;
|
||||
top++;
|
||||
|
||||
if (filled < size - 1)
|
||||
filled++;
|
||||
}
|
||||
|
||||
public T pop() {
|
||||
if (filled <= 0) return null;
|
||||
|
||||
if (top - 1 < 0)
|
||||
top = size;
|
||||
|
||||
top--;
|
||||
T object = stack[top];
|
||||
filled--;
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
top = 0;
|
||||
filled = 0;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return filled <= 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package nl.requios.effortlessbuilding.helper;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public class InventoryHelper {
|
||||
|
||||
public static ItemStack findItemStackInInventory(EntityPlayer player, IBlockState blockState) {
|
||||
for (ItemStack invStack : player.inventory.mainInventory) {
|
||||
if (!invStack.isEmpty() && invStack.getItem() instanceof ItemBlock &&
|
||||
((ItemBlock) invStack.getItem()).getBlock().equals(blockState.getBlock())) {
|
||||
return invStack;
|
||||
}
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
public static int findTotalBlocksInInventory(EntityPlayer player, IBlockState blockState) {
|
||||
int total = 0;
|
||||
for (ItemStack invStack : player.inventory.mainInventory) {
|
||||
if (!invStack.isEmpty() && invStack.getItem() instanceof ItemBlock &&
|
||||
((ItemBlock) invStack.getItem()).getBlock().equals(blockState.getBlock())) {
|
||||
total += invStack.getCount();
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
}
|
||||
@@ -77,14 +77,15 @@ public class ClientProxy implements IProxy {
|
||||
@Override
|
||||
public void init(FMLInitializationEvent event) {
|
||||
// register key bindings
|
||||
keyBindings = new KeyBinding[4];
|
||||
keyBindings = new KeyBinding[5];
|
||||
|
||||
// instantiate the key bindings
|
||||
keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", Keyboard.KEY_ADD, "key.effortlessbuilding.category");
|
||||
keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", Keyboard.KEY_SUBTRACT, "key.effortlessbuilding.category");
|
||||
keyBindings[2] = new KeyBinding("key.effortlessbuilding.creative.desc", Keyboard.KEY_NONE, "key.effortlessbuilding.category");
|
||||
keyBindings[3] = new KeyBinding("key.effortlessbuilding.mode.desc", Keyboard.KEY_LMENU, "key.effortlessbuilding.category");
|
||||
// keyBindings[4] = new KeyBinding("Reload shaders", Keyboard.KEY_TAB, "key.effortlessbuilding.category");
|
||||
keyBindings[4] = new KeyBinding("key.effortlessbuilding.undo.desc", Keyboard.KEY_U, "key.effortlessbuilding.category");
|
||||
// keyBindings[5] = new KeyBinding("Reload shaders", Keyboard.KEY_TAB, "key.effortlessbuilding.category");
|
||||
|
||||
// register all the key bindings
|
||||
for (int i = 0; i < keyBindings.length; ++i) {
|
||||
@@ -318,8 +319,16 @@ public class ClientProxy implements IProxy {
|
||||
}
|
||||
}
|
||||
|
||||
// if (keyBindings[4].isPressed()) {
|
||||
// //TODO remove
|
||||
//Undo
|
||||
if (keyBindings[4].isPressed()) {
|
||||
ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO;
|
||||
if (player.isSneaking()) action = ModeOptions.ActionEnum.REDO;
|
||||
ModeOptions.performAction(player, action);
|
||||
EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action));
|
||||
}
|
||||
|
||||
//For shader development
|
||||
// if (keyBindings[5].isPressed()) {
|
||||
// ShaderHandler.init();
|
||||
// EffortlessBuilding.log(player, "Reloaded shaders");
|
||||
// }
|
||||
|
||||
@@ -26,6 +26,7 @@ import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers;
|
||||
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
|
||||
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings;
|
||||
import nl.requios.effortlessbuilding.compatibility.CompatHelper;
|
||||
import nl.requios.effortlessbuilding.helper.InventoryHelper;
|
||||
import nl.requios.effortlessbuilding.helper.ReachHelper;
|
||||
import nl.requios.effortlessbuilding.helper.SurvivalHelper;
|
||||
import nl.requios.effortlessbuilding.item.ItemRandomizerBag;
|
||||
@@ -158,12 +159,7 @@ public class BlockPreviewRenderer {
|
||||
|
||||
List<BlockPos> newCoordinates = BuildModifiers.findCoordinates(player, startCoordinates);
|
||||
|
||||
Collections.sort(newCoordinates, (lhs, rhs) -> {
|
||||
// -1 - less than, 1 - greater than, 0 - equal
|
||||
double lhsDistanceToPlayer = new Vec3d(lhs).subtract(player.getPositionEyes(1f)).lengthSquared();
|
||||
double rhsDistanceToPlayer = new Vec3d(rhs).subtract(player.getPositionEyes(1f)).lengthSquared();
|
||||
return (int) Math.signum(lhsDistanceToPlayer - rhsDistanceToPlayer);
|
||||
});
|
||||
sortOnDistanceToPlayer(newCoordinates, player);
|
||||
|
||||
hitVec = new Vec3d(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)),
|
||||
Math.abs(hitVec.z - ((int) hitVec.z)));
|
||||
@@ -206,12 +202,14 @@ public class BlockPreviewRenderer {
|
||||
|
||||
//Render block previews
|
||||
if (blockStates.size() != 0 && newCoordinates.size() == blockStates.size()) {
|
||||
int blockCount;
|
||||
|
||||
//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);
|
||||
blockCount = renderBlockPreviews(newCoordinates, blockStates, itemStacks, 0f, firstPos, secondPos, !breaking, breaking);
|
||||
|
||||
RenderHandler.endBlockPreviews();
|
||||
} else {
|
||||
@@ -227,8 +225,27 @@ public class BlockPreviewRenderer {
|
||||
}
|
||||
|
||||
RenderHandler.endLines();
|
||||
|
||||
blockCount = newCoordinates.size();
|
||||
}
|
||||
|
||||
//Display block count and dimensions in actionbar
|
||||
if (BuildModes.isActive(player)) {
|
||||
BlockPos dim = secondPos.subtract(firstPos);
|
||||
dim = new BlockPos(Math.abs(dim.getX()) + 1, Math.abs(dim.getY()) + 1, Math.abs(dim.getZ()) + 1);
|
||||
|
||||
String dimensions = "(";
|
||||
if (dim.getX() > 1) dimensions += dim.getX() + "x";
|
||||
if (dim.getZ() > 1) dimensions += dim.getZ() + "x";
|
||||
if (dim.getY() > 1) dimensions += dim.getY() + "x";
|
||||
dimensions = dimensions.substring(0, dimensions.length() - 1);
|
||||
if (dimensions.length() > 1) dimensions += ")";
|
||||
|
||||
EffortlessBuilding.log(player, blockCount + " blocks " + dimensions, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
RenderHandler.beginLines();
|
||||
@@ -264,14 +281,15 @@ public class BlockPreviewRenderer {
|
||||
BuildConfig.visuals.alwaysShowBlockPreview;
|
||||
}
|
||||
|
||||
protected static void renderBlockPreviews(List<BlockPos> coordinates, List<IBlockState> blockStates,
|
||||
protected static int renderBlockPreviews(List<BlockPos> coordinates, List<IBlockState> blockStates,
|
||||
List<ItemStack> itemStacks, float dissolve, BlockPos firstPos,
|
||||
BlockPos secondPos, boolean checkCanPlace, boolean red) {
|
||||
EntityPlayer player = Minecraft.getMinecraft().player;
|
||||
ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player);
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
|
||||
int blocksValid = 0;
|
||||
|
||||
if (coordinates.isEmpty()) return;
|
||||
if (coordinates.isEmpty()) return blocksValid;
|
||||
|
||||
for (int i = coordinates.size() - 1; i >= 0; i--) {
|
||||
BlockPos blockPos = coordinates.get(i);
|
||||
@@ -289,43 +307,57 @@ public class BlockPreviewRenderer {
|
||||
new Vec3d(blockPos), new Vec3d(firstPos), new Vec3d(secondPos),
|
||||
blockPos == secondPos, red));
|
||||
RenderHandler.renderBlockPreview(dispatcher, blockPos, blockState);
|
||||
blocksValid++;
|
||||
}
|
||||
}
|
||||
return blocksValid;
|
||||
}
|
||||
|
||||
public static void onBlocksPlaced() {
|
||||
onBlocksPlaced(previousCoordinates, previousItemStacks, previousBlockStates, previousFirstPos, previousSecondPos);
|
||||
}
|
||||
|
||||
public static void onBlocksPlaced(List<BlockPos> coordinates, List<ItemStack> itemStacks, List<IBlockState> blockStates,
|
||||
BlockPos firstPos, BlockPos secondPos) {
|
||||
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)) {
|
||||
if (doRenderBlockPreviews(modifierSettings, modeSettings, firstPos)) {
|
||||
|
||||
//Save current coordinates, blockstates and itemstacks
|
||||
if (!previousCoordinates.isEmpty() && previousBlockStates.size() == previousCoordinates.size() &&
|
||||
previousCoordinates.size() > 1 && previousCoordinates.size() < BuildConfig.visuals.shaderTreshold) {
|
||||
if (!coordinates.isEmpty() && blockStates.size() == coordinates.size() &&
|
||||
coordinates.size() > 1 && coordinates.size() < BuildConfig.visuals.shaderTreshold) {
|
||||
|
||||
placedDataList.add(new PlacedData(ClientProxy.ticksInGame, previousCoordinates, previousBlockStates,
|
||||
previousItemStacks, previousFirstPos, previousSecondPos, false));
|
||||
placedDataList.add(new PlacedData(ClientProxy.ticksInGame, coordinates, blockStates,
|
||||
itemStacks, firstPos, secondPos, false));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void onBlocksBroken() {
|
||||
onBlocksBroken(previousCoordinates, previousItemStacks, previousBlockStates, previousFirstPos, previousSecondPos);
|
||||
}
|
||||
|
||||
public static void onBlocksBroken(List<BlockPos> coordinates, List<ItemStack> itemStacks, List<IBlockState> blockStates,
|
||||
BlockPos firstPos, BlockPos secondPos) {
|
||||
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)) {
|
||||
if (doRenderBlockPreviews(modifierSettings, modeSettings, firstPos)) {
|
||||
|
||||
//Save current coordinates, blockstates and itemstacks
|
||||
if (!previousCoordinates.isEmpty() && previousBlockStates.size() == previousCoordinates.size() &&
|
||||
previousCoordinates.size() > 1 && previousCoordinates.size() < BuildConfig.visuals.shaderTreshold) {
|
||||
if (!coordinates.isEmpty() && blockStates.size() == coordinates.size() &&
|
||||
coordinates.size() > 1 && coordinates.size() < BuildConfig.visuals.shaderTreshold) {
|
||||
|
||||
placedDataList.add(new PlacedData(ClientProxy.ticksInGame, previousCoordinates, previousBlockStates,
|
||||
previousItemStacks, previousFirstPos, previousSecondPos, true));
|
||||
sortOnDistanceToPlayer(coordinates, player);
|
||||
|
||||
placedDataList.add(new PlacedData(ClientProxy.ticksInGame, coordinates, blockStates,
|
||||
itemStacks, firstPos, secondPos, true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -373,4 +405,15 @@ public class BlockPreviewRenderer {
|
||||
ARBShaderObjects.glUniform1iARB(redUniform, red ? 1 : 0);
|
||||
};
|
||||
}
|
||||
|
||||
private static void sortOnDistanceToPlayer(List<BlockPos> coordinates, EntityPlayer player) {
|
||||
|
||||
Collections.sort(coordinates, (lhs, rhs) -> {
|
||||
// -1 - less than, 1 - greater than, 0 - equal
|
||||
double lhsDistanceToPlayer = new Vec3d(lhs).subtract(player.getPositionEyes(1f)).lengthSquared();
|
||||
double rhsDistanceToPlayer = new Vec3d(rhs).subtract(player.getPositionEyes(1f)).lengthSquared();
|
||||
return (int) Math.signum(lhsDistanceToPlayer - rhsDistanceToPlayer);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ key.effortlessbuilding.hud.desc=Modifier Menu
|
||||
key.effortlessbuilding.replace.desc=Toggle QuickReplace
|
||||
key.effortlessbuilding.creative.desc=Toggle Survival/Creative Mode
|
||||
key.effortlessbuilding.mode.desc=Radial Menu
|
||||
key.effortlessbuilding.undo.desc=Undo
|
||||
|
||||
item.effortlessbuilding:randomizer_bag.name=Randomizer Bag
|
||||
item.effortlessbuilding:reach_upgrade1.name=Reach Upgrade 1
|
||||
@@ -19,8 +20,8 @@ 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.undo=Undo
|
||||
effortlessbuilding.action.redo=Redo
|
||||
effortlessbuilding.action.replace=Replace
|
||||
effortlessbuilding.action.open_modifier_settings=Open Modifier Settings
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 317 B After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 317 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 317 B After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 317 B After Width: | Height: | Size: 1.2 KiB |