- slight transparancy to block preview.
Changed
 - Walls dont try to place at extreme angles anymore.
 - Lines will now prefer the axis closest to player if there are multiple good options.
 - undo hotkey is now ctrl-z and redo to ctrl-y.
Fixed
 - undo not going past 2.
 - not being able to cancel placement with leftclicking when out of reach.
 - blockstate getting stuck in preview before first rightclick.
This commit is contained in:
Christian Knaapen
2019-03-20 23:47:42 +01:00
parent 25ae75bfb6
commit a4e575e733
19 changed files with 234 additions and 139 deletions

View File

@@ -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. //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
version = "1.12.2-2.5" version = "1.12.2-2.6"
group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html group = "nl.requios.effortlessbuilding" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "effortlessbuilding" archivesBaseName = "effortlessbuilding"

View File

@@ -39,7 +39,7 @@ public class EffortlessBuilding
{ {
public static final String MODID = "effortlessbuilding"; public static final String MODID = "effortlessbuilding";
public static final String NAME = "Effortless Building"; public static final String NAME = "Effortless Building";
public static final String VERSION = "1.12.2-2.5"; public static final String VERSION = "1.12.2-2.6";
@Mod.Instance(EffortlessBuilding.MODID) @Mod.Instance(EffortlessBuilding.MODID)
public static EffortlessBuilding instance; public static EffortlessBuilding instance;

View File

@@ -9,6 +9,7 @@ import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemBlock;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.config.Config; import net.minecraftforge.common.config.Config;
import net.minecraftforge.common.config.ConfigManager; import net.minecraftforge.common.config.ConfigManager;
@@ -21,16 +22,22 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmode.BuildModes;
import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager; import nl.requios.effortlessbuilding.buildmode.ModeSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.BlockSet;
import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.buildmodifier.UndoRedo;
import nl.requios.effortlessbuilding.capability.ModeCapabilityManager; import nl.requios.effortlessbuilding.capability.ModeCapabilityManager;
import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import nl.requios.effortlessbuilding.helper.SurvivalHelper; import nl.requios.effortlessbuilding.helper.SurvivalHelper;
import nl.requios.effortlessbuilding.network.RequestLookAtMessage; import nl.requios.effortlessbuilding.network.RequestLookAtMessage;
import scala.actors.threadpool.Arrays;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import static net.minecraftforge.fml.common.gameevent.PlayerEvent.*;
@Mod.EventBusSubscriber @Mod.EventBusSubscriber
public class EventHandler public class EventHandler
{ {
@@ -91,7 +98,7 @@ public class EventHandler
//But modifiers and QuickReplace should still work //But modifiers and QuickReplace should still work
//Send message to client, which sends message back with raytrace info //Send message to client, which sends message back with raytrace info
EffortlessBuilding.packetHandler.sendTo(new RequestLookAtMessage(), (EntityPlayerMP) player); EffortlessBuilding.packetHandler.sendTo(new RequestLookAtMessage(event.getPos(), event.getState()), (EntityPlayerMP) player);
} }
} }
@@ -148,4 +155,34 @@ public class EventHandler
//EffortlessBuilding.log(player, String.valueOf(event.getNewSpeed())); //EffortlessBuilding.log(player, String.valueOf(event.getNewSpeed()));
} }
@SubscribeEvent
public static void onPlayerLoggedIn(PlayerLoggedInEvent event) {
EntityPlayer player = event.player;
ModifierSettingsManager.handleNewPlayer(player);
ModeSettingsManager.handleNewPlayer(player);
}
@SubscribeEvent
public static void onPlayerLoggedOut(PlayerLoggedOutEvent event) {
UndoRedo.clear(event.player);
//TODO call clientside
}
@SubscribeEvent
public static void onPlayerRespawn(PlayerRespawnEvent event) {
EntityPlayer player = event.player;
ModifierSettingsManager.handleNewPlayer(player);
ModeSettingsManager.handleNewPlayer(player);
}
@SubscribeEvent
public static void onPlayerChangedDimension(PlayerChangedDimensionEvent event) {
EntityPlayer player = event.player;
ModifierSettingsManager.handleNewPlayer(player);
ModeSettingsManager.handleNewPlayer(player);
UndoRedo.clear(event.player);
//TODO call clientside
}
} }

View File

@@ -118,24 +118,22 @@ public class BuildModes {
//Use a network message to break blocks in the distance using clientside mouse input //Use a network message to break blocks in the distance using clientside mouse input
public static void onBlockBrokenMessage(EntityPlayer player, BlockBrokenMessage message) { public static void onBlockBrokenMessage(EntityPlayer player, BlockBrokenMessage message) {
if (ReachHelper.canBreakFar(player)) {
BlockPos startPos = message.isBlockHit() ? message.getBlockPos() : null; BlockPos startPos = message.isBlockHit() ? message.getBlockPos() : null;
onBlockBroken(player, startPos, true); onBlockBroken(player, startPos, true);
} }
}
public static void onBlockBroken(EntityPlayer player, BlockPos startPos, boolean breakStartPos) { public static void onBlockBroken(EntityPlayer player, BlockPos startPos, boolean breakStartPos) {
//Check if not in the middle of placing //Check if not in the middle of placing
Dictionary<EntityPlayer, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer; Dictionary<EntityPlayer, Boolean> currentlyBreaking = player.world.isRemote ? currentlyBreakingClient : currentlyBreakingServer;
if (currentlyBreaking.get(player) != null && !currentlyBreaking.get(player)) { if (currentlyBreaking.get(player) != null && !currentlyBreaking.get(player)) {
//Cancel breaking //Cancel placing
initializeMode(player); initializeMode(player);
return; return;
} }
if (!ReachHelper.canBreakFar(player)) return;
//If first click //If first click
if (currentlyBreaking.get(player) == null) { if (currentlyBreaking.get(player) == null) {
//If startpos is null, dont do anything //If startpos is null, dont do anything

View File

@@ -41,7 +41,7 @@ public class Floor implements IBuildMode {
} }
return planeBound.subtract(start).dotProduct(look) > 0 && return planeBound.subtract(start).dotProduct(look) > 0 &&
distToPlayerSq > 4 && distToPlayerSq < reach * reach && distToPlayerSq > 2 && distToPlayerSq < reach * reach &&
!intersects; !intersects;
} }
} }

View File

@@ -5,6 +5,7 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.util.*; import java.util.*;
@@ -64,7 +65,7 @@ public class Line implements IBuildMode {
} }
return planeBound.subtract(start).dotProduct(look) > 0 && return planeBound.subtract(start).dotProduct(look) > 0 &&
distToPlayerSq > 4 && distToPlayerSq < reach * reach && distToPlayerSq > 2 && distToPlayerSq < reach * reach &&
!intersects; !intersects;
} }
} }
@@ -180,11 +181,16 @@ public class Line implements IBuildMode {
//Select the one that is closest (from wall position to its line counterpart) //Select the one that is closest (from wall position to its line counterpart)
for (int i = 1; i < criteriaList.size(); i++) { for (int i = 1; i < criteriaList.size(); i++) {
Criteria criteria = criteriaList.get(i); Criteria criteria = criteriaList.get(i);
if (criteria.distToLineSq < 2.0 && selected.distToLineSq < 2.0) {
//Both very close to line, choose closest to player
if (criteria.distToPlayerSq < selected.distToPlayerSq)
selected = criteria;
} else {
//Pick closest to line
if (criteria.distToLineSq < selected.distToLineSq) if (criteria.distToLineSq < selected.distToLineSq)
selected = criteria; selected = criteria;
} }
}
//TODO: if multiple are very close, choose closest to player
} }

View File

@@ -73,25 +73,7 @@ public class ModeSettingsManager {
} }
} }
@SubscribeEvent public static void handleNewPlayer(EntityPlayer player){
public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
EntityPlayer player = event.player;
handleNewPlayer(player);
}
@SubscribeEvent
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
EntityPlayer player = event.player;
handleNewPlayer(player);
}
@SubscribeEvent
public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
EntityPlayer player = event.player;
handleNewPlayer(player);
}
private static void handleNewPlayer(EntityPlayer player){
if (getModeSettings(player) == null) { if (getModeSettings(player) == null) {
setModeSettings(player, new ModeSettings()); setModeSettings(player, new ModeSettings());
} }

View File

@@ -1,10 +1,12 @@
package nl.requios.effortlessbuilding.buildmode; package nl.requios.effortlessbuilding.buildmode;
import com.sun.javafx.geom.Vec2d;
import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.helper.ReachHelper; import nl.requios.effortlessbuilding.helper.ReachHelper;
import java.util.*; import java.util.*;
@@ -26,7 +28,10 @@ public class Wall implements IBuildMode {
Criteria(Vec3d planeBound, BlockPos firstPos, Vec3d start, Vec3d look) { Criteria(Vec3d planeBound, BlockPos firstPos, Vec3d start, Vec3d look) {
this.planeBound = planeBound; this.planeBound = planeBound;
this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared(); this.distToPlayerSq = this.planeBound.subtract(start).lengthSquared();
this.angle = this.planeBound.subtract(new Vec3d(firstPos)).normalize().dotProduct(look); Vec3d wall = this.planeBound.subtract(new Vec3d(firstPos));
Vec2d horizontalWall = new Vec2d(wall.x, wall.z);
Vec2d horizontalLook = new Vec2d(look.x, look.z);
this.angle = horizontalWall.x * horizontalLook.x + horizontalWall.y * horizontalLook.y;
} }
//check if its not behind the player and its not too close and not too far //check if its not behind the player and its not too close and not too far
@@ -42,7 +47,7 @@ public class Wall implements IBuildMode {
} }
return planeBound.subtract(start).dotProduct(look) > 0 && return planeBound.subtract(start).dotProduct(look) > 0 &&
distToPlayerSq > 4 && distToPlayerSq < reach * reach && distToPlayerSq > 2 && distToPlayerSq < reach * reach &&
!intersects; !intersects;
} }
} }
@@ -163,14 +168,12 @@ public class Wall implements IBuildMode {
//If multiple are valid, choose based on criteria //If multiple are valid, choose based on criteria
if (criteriaList.size() > 1) { if (criteriaList.size() > 1) {
//Select the one that is closest //Select the one that is closest
//Limit the angle to not be too extreme
for (int i = 1; i < criteriaList.size(); i++) { for (int i = 1; i < criteriaList.size(); i++) {
Criteria criteria = criteriaList.get(i); Criteria criteria = criteriaList.get(i);
if (criteria.distToPlayerSq < selected.distToPlayerSq) if (criteria.distToPlayerSq < selected.distToPlayerSq && Math.abs(criteria.angle) - Math.abs(selected.angle) < 3)
selected = criteria; selected = criteria;
} }
//TODO: limit angle
//Math.abs(zAngle) < Math.abs(xAngle)
} }
return new BlockPos(selected.planeBound); return new BlockPos(selected.planeBound);

View File

@@ -171,33 +171,18 @@ public class ModifierSettingsManager {
case 3: reach = BuildConfig.reach.maxReachLevel3; break; case 3: reach = BuildConfig.reach.maxReachLevel3; break;
} }
EffortlessBuilding.log("before "+this.mirrorSettings.radius);
if (this.mirrorSettings != null) if (this.mirrorSettings != null)
this.mirrorSettings.radius = reach / 2; this.mirrorSettings.radius = reach / 2;
if (this.radialMirrorSettings != null) if (this.radialMirrorSettings != null)
this.radialMirrorSettings.radius = reach / 2; this.radialMirrorSettings.radius = reach / 2;
EffortlessBuilding.log("after "+this.mirrorSettings.radius);
} }
} }
@SubscribeEvent public static void handleNewPlayer(EntityPlayer player){
public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) {
EntityPlayer player = event.player;
handleNewPlayer(player);
}
@SubscribeEvent
public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) {
EntityPlayer player = event.player;
handleNewPlayer(player);
}
@SubscribeEvent
public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
EntityPlayer player = event.player;
handleNewPlayer(player);
}
private static void handleNewPlayer(EntityPlayer player){
if (getModifierSettings(player) == null) { if (getModifierSettings(player) == null) {
setModifierSettings(player, new ModifierSettings()); setModifierSettings(player, new ModifierSettings());
} }

View File

@@ -16,11 +16,15 @@ import java.util.*;
public class UndoRedo { public class UndoRedo {
private static Map<UUID, FixedStack<BlockSet>> undoStacks = new HashMap<>(); //Gets added to twice in singleplayer (server and client) if not careful. So separate stacks.
private static Map<UUID, FixedStack<BlockSet>> redoStacks = new HashMap<>(); private static Map<UUID, FixedStack<BlockSet>> undoStacksClient = new HashMap<>();
private static Map<UUID, FixedStack<BlockSet>> undoStacksServer = new HashMap<>();
private static Map<UUID, FixedStack<BlockSet>> redoStacksClient = new HashMap<>();
private static Map<UUID, FixedStack<BlockSet>> redoStacksServer = new HashMap<>();
//add to undo stack //add to undo stack
public static void addUndo(EntityPlayer player, BlockSet blockSet) { public static void addUndo(EntityPlayer player, BlockSet blockSet) {
Map<UUID, FixedStack<BlockSet>> undoStacks = player.world.isRemote ? undoStacksClient : undoStacksServer;
//If no stack exists, make one //If no stack exists, make one
if (!undoStacks.containsKey(player.getUniqueID())) { if (!undoStacks.containsKey(player.getUniqueID())) {
@@ -31,6 +35,7 @@ public class UndoRedo {
} }
private static void addRedo(EntityPlayer player, BlockSet blockSet) { private static void addRedo(EntityPlayer player, BlockSet blockSet) {
Map<UUID, FixedStack<BlockSet>> redoStacks = player.world.isRemote ? redoStacksClient : redoStacksServer;
//If no stack exists, make one //If no stack exists, make one
if (!redoStacks.containsKey(player.getUniqueID())) { if (!redoStacks.containsKey(player.getUniqueID())) {
@@ -41,6 +46,8 @@ public class UndoRedo {
} }
public static boolean undo(EntityPlayer player) { public static boolean undo(EntityPlayer player) {
Map<UUID, FixedStack<BlockSet>> undoStacks = player.world.isRemote ? undoStacksClient : undoStacksServer;
if (!undoStacks.containsKey(player.getUniqueID())) return false; if (!undoStacks.containsKey(player.getUniqueID())) return false;
FixedStack<BlockSet> undoStack = undoStacks.get(player.getUniqueID()); FixedStack<BlockSet> undoStack = undoStacks.get(player.getUniqueID());
@@ -54,6 +61,9 @@ public class UndoRedo {
//Find up to date itemstacks in player inventory //Find up to date itemstacks in player inventory
List<ItemStack> itemStacks = findItemStacksInInventory(player, blockStates); List<ItemStack> itemStacks = findItemStacksInInventory(player, blockStates);
if (player.world.isRemote) {
BlockPreviewRenderer.onBlocksBroken(coordinates, itemStacks, blockStates, blockSet.getSecondPos(), blockSet.getFirstPos());
} else {
//break all those blocks //break all those blocks
for (int i = 0; i < coordinates.size(); i++) { for (int i = 0; i < coordinates.size(); i++) {
BlockPos coordinate = coordinates.get(i); BlockPos coordinate = coordinates.get(i);
@@ -61,9 +71,7 @@ public class UndoRedo {
SurvivalHelper.breakBlock(player.world, player, coordinate); SurvivalHelper.breakBlock(player.world, player, coordinate);
} }
} }
}
if (player.world.isRemote)
BlockPreviewRenderer.onBlocksBroken(coordinates, itemStacks, blockStates, blockSet.getSecondPos(), blockSet.getFirstPos());
//add to redo //add to redo
addRedo(player, blockSet); addRedo(player, blockSet);
@@ -72,6 +80,8 @@ public class UndoRedo {
} }
public static boolean redo(EntityPlayer player) { public static boolean redo(EntityPlayer player) {
Map<UUID, FixedStack<BlockSet>> redoStacks = player.world.isRemote ? redoStacksClient : redoStacksServer;
if (!redoStacks.containsKey(player.getUniqueID())) return false; if (!redoStacks.containsKey(player.getUniqueID())) return false;
FixedStack<BlockSet> redoStack = redoStacks.get(player.getUniqueID()); FixedStack<BlockSet> redoStack = redoStacks.get(player.getUniqueID());
@@ -86,6 +96,9 @@ public class UndoRedo {
//Find up to date itemstacks in player inventory //Find up to date itemstacks in player inventory
List<ItemStack> itemStacks = findItemStacksInInventory(player, blockStates); List<ItemStack> itemStacks = findItemStacksInInventory(player, blockStates);
if (player.world.isRemote) {
BlockPreviewRenderer.onBlocksPlaced(coordinates, itemStacks, blockStates, blockSet.getFirstPos(), blockSet.getSecondPos());
} else {
//place blocks //place blocks
for (int i = 0; i < coordinates.size(); i++) { for (int i = 0; i < coordinates.size(); i++) {
BlockPos blockPos = coordinates.get(i); BlockPos blockPos = coordinates.get(i);
@@ -98,9 +111,7 @@ public class UndoRedo {
SurvivalHelper.placeBlock(player.world, player, blockPos, blockState, itemStack, EnumFacing.UP, hitVec, false, false); 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 //add to undo
addUndo(player, blockSet); addUndo(player, blockSet);
@@ -108,6 +119,17 @@ public class UndoRedo {
return true; return true;
} }
public static void clear(EntityPlayer player) {
Map<UUID, FixedStack<BlockSet>> undoStacks = player.world.isRemote ? undoStacksClient : undoStacksServer;
Map<UUID, FixedStack<BlockSet>> redoStacks = player.world.isRemote ? redoStacksClient : redoStacksServer;
if (undoStacks.containsKey(player.getUniqueID())) {
undoStacks.get(player.getUniqueID()).clear();
}
if (redoStacks.containsKey(player.getUniqueID())) {
redoStacks.get(player.getUniqueID()).clear();
}
}
private static List<ItemStack> findItemStacksInInventory(EntityPlayer player, List<IBlockState> blockStates) { private static List<ItemStack> findItemStacksInInventory(EntityPlayer player, List<IBlockState> blockStates) {
List<ItemStack> itemStacks = new ArrayList<>(blockStates.size()); List<ItemStack> itemStacks = new ArrayList<>(blockStates.size());
for (IBlockState blockState : blockStates) { for (IBlockState blockState : blockStates) {

View File

@@ -102,7 +102,10 @@ public class ModifierCapabilityManager {
//MIRROR //MIRROR
boolean mirrorEnabled = compound.getBoolean("mirrorEnabled"); boolean mirrorEnabled = compound.getBoolean("mirrorEnabled");
Vec3d mirrorPosition = new Vec3d(compound.getDouble("mirrorPosX"), compound.getDouble("mirrorPosY"), compound.getDouble("mirrorPosZ")); Vec3d mirrorPosition = new Vec3d(
compound.getDouble("mirrorPosX"),
compound.getDouble("mirrorPosY"),
compound.getDouble("mirrorPosZ"));
boolean mirrorX = compound.getBoolean("mirrorX"); boolean mirrorX = compound.getBoolean("mirrorX");
boolean mirrorY = compound.getBoolean("mirrorY"); boolean mirrorY = compound.getBoolean("mirrorY");
boolean mirrorZ = compound.getBoolean("mirrorZ"); boolean mirrorZ = compound.getBoolean("mirrorZ");
@@ -113,7 +116,10 @@ public class ModifierCapabilityManager {
//ARRAY //ARRAY
boolean arrayEnabled = compound.getBoolean("arrayEnabled"); boolean arrayEnabled = compound.getBoolean("arrayEnabled");
BlockPos arrayOffset = new BlockPos(compound.getInteger("arrayOffsetX"), compound.getInteger("arrayOffsetY"), compound.getInteger("arrayOffsetZ")); BlockPos arrayOffset = new BlockPos(
compound.getInteger("arrayOffsetX"),
compound.getInteger("arrayOffsetY"),
compound.getInteger("arrayOffsetZ"));
int arrayCount = compound.getInteger("arrayCount"); int arrayCount = compound.getInteger("arrayCount");
Array.ArraySettings arraySettings = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); Array.ArraySettings arraySettings = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount);
@@ -123,7 +129,10 @@ public class ModifierCapabilityManager {
//RADIAL MIRROR //RADIAL MIRROR
boolean radialMirrorEnabled = compound.getBoolean("radialMirrorEnabled"); boolean radialMirrorEnabled = compound.getBoolean("radialMirrorEnabled");
Vec3d radialMirrorPosition = new Vec3d(compound.getDouble("radialMirrorPosX"), compound.getDouble("radialMirrorPosY"), compound.getDouble("radialMirrorPosZ")); Vec3d radialMirrorPosition = new Vec3d(
compound.getDouble("radialMirrorPosX"),
compound.getDouble("radialMirrorPosY"),
compound.getDouble("radialMirrorPosZ"));
int radialMirrorSlices = compound.getInteger("radialMirrorSlices"); int radialMirrorSlices = compound.getInteger("radialMirrorSlices");
boolean radialMirrorAlternate = compound.getBoolean("radialMirrorAlternate"); boolean radialMirrorAlternate = compound.getBoolean("radialMirrorAlternate");
int radialMirrorRadius = compound.getInteger("radialMirrorRadius"); int radialMirrorRadius = compound.getInteger("radialMirrorRadius");
@@ -132,8 +141,7 @@ public class ModifierCapabilityManager {
RadialMirror.RadialMirrorSettings radialMirrorSettings = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, RadialMirror.RadialMirrorSettings radialMirrorSettings = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition,
radialMirrorSlices, radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes); radialMirrorSlices, radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes);
ModifierSettings ModifierSettings modifierSettings = new ModifierSettings(mirrorSettings, arraySettings, radialMirrorSettings, false, reachUpgrade);
modifierSettings = new ModifierSettings(mirrorSettings, arraySettings, radialMirrorSettings, false, reachUpgrade);
instance.setModifierData(modifierSettings); instance.setModifierData(modifierSettings);
} }
} }

View File

@@ -342,8 +342,7 @@ public class RadialMenu extends GuiScreen {
keybind = ClientProxy.keyBindings[4].getDisplayName(); keybind = ClientProxy.keyBindings[4].getDisplayName();
} }
if (button.action == ModeOptions.ActionEnum.REDO) { if (button.action == ModeOptions.ActionEnum.REDO) {
String sneak = Minecraft.getMinecraft().gameSettings.keyBindSneak.getDisplayName(); keybind = ClientProxy.keyBindings[5].getDisplayName();
keybind = sneak + " + " + ClientProxy.keyBindings[4].getDisplayName();
} }
if (button.action == ModeOptions.ActionEnum.REPLACE) { if (button.action == ModeOptions.ActionEnum.REPLACE) {
keybind = ClientProxy.keyBindings[1].getDisplayName(); keybind = ClientProxy.keyBindings[1].getDisplayName();
@@ -351,7 +350,7 @@ public class RadialMenu extends GuiScreen {
if (button.action == ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) { if (button.action == ModeOptions.ActionEnum.OPEN_MODIFIER_SETTINGS) {
keybind = ClientProxy.keyBindings[0].getDisplayName(); keybind = ClientProxy.keyBindings[0].getDisplayName();
} }
String keybindFormatted = TextFormatting.GRAY + " (" + WordUtils.capitalizeFully(keybind) + ")"; String keybindFormatted = TextFormatting.GRAY + "(" + WordUtils.capitalizeFully(keybind) + ")";
if (button.textSide == EnumFacing.WEST) { if (button.textSide == EnumFacing.WEST) {
@@ -365,10 +364,10 @@ public class RadialMenu extends GuiScreen {
} else if (button.textSide == EnumFacing.UP || button.textSide == EnumFacing.NORTH) { } else if (button.textSide == EnumFacing.UP || button.textSide == EnumFacing.NORTH) {
fontRenderer.drawSplitString( text, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(text) * 0.5), fontRenderer.drawSplitString( keybindFormatted, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(keybindFormatted) * 0.5),
(int) (middleY + button.y1 - 26), wrap,0xffffffff); (int) (middleY + button.y1 - 26), wrap,0xffffffff);
fontRenderer.drawSplitString( keybindFormatted, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(keybindFormatted) * 0.5), fontRenderer.drawSplitString( text, (int) (middleX + (button.x1 + button.x2) * 0.5 - fontRenderer.getStringWidth(text) * 0.5),
(int) (middleY + button.y1 - 14), wrap,0xffffffff); (int) (middleY + button.y1 - 14), wrap,0xffffffff);
} else if (button.textSide == EnumFacing.DOWN || button.textSide == EnumFacing.SOUTH) { } else if (button.textSide == EnumFacing.DOWN || button.textSide == EnumFacing.SOUTH) {

View File

@@ -1,5 +1,7 @@
package nl.requios.effortlessbuilding.helper; package nl.requios.effortlessbuilding.helper;
import nl.requios.effortlessbuilding.EffortlessBuilding;
//Stack with fixed size. Removes (overwrites) oldest element on push. //Stack with fixed size. Removes (overwrites) oldest element on push.
public class FixedStack<T> { public class FixedStack<T> {
private T[] stack; private T[] stack;
@@ -20,7 +22,7 @@ public class FixedStack<T> {
stack[top] = object; stack[top] = object;
top++; top++;
if (filled < size - 1) if (filled < size)
filled++; filled++;
} }

View File

@@ -55,12 +55,6 @@ public class ItemReachUpgrade1 extends Item {
return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand)); return new ActionResult<>(EnumActionResult.PASS, player.getHeldItem(hand));
} }
@Override
public ItemStack onItemUseFinish(ItemStack stack, World worldIn, EntityLivingBase entityLiving) {
EffortlessBuilding.log("used");
return ItemStack.EMPTY;
}
@Override @Override
public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) { public void addInformation(ItemStack stack, @Nullable World world, List<String> tooltip, ITooltipFlag flag) {
tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1); tooltip.add(TextFormatting.GRAY + "Consume to increase reach to " + TextFormatting.BLUE + BuildConfig.reach.maxReachLevel1);

View File

@@ -1,34 +1,61 @@
package nl.requios.effortlessbuilding.network; package nl.requios.effortlessbuilding.network;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.minecraft.util.EnumFacing; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage; import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.Side;
import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmode.BuildModes; import nl.requios.effortlessbuilding.buildmodifier.BlockSet;
import nl.requios.effortlessbuilding.buildmodifier.BuildModifiers; import nl.requios.effortlessbuilding.buildmodifier.UndoRedo;
import nl.requios.effortlessbuilding.proxy.ClientProxy; import nl.requios.effortlessbuilding.proxy.ClientProxy;
import java.util.ArrayList;
/*** /***
* Sends a message to the client asking for its lookat (objectmouseover) data. * Sends a message to the client asking for its lookat (objectmouseover) data.
* This is then sent back with a BlockPlacedMessage. * This is then sent back with a BlockPlacedMessage.
*/ */
public class RequestLookAtMessage implements IMessage { public class RequestLookAtMessage implements IMessage {
private BlockPos coordinate;
private IBlockState blockState;
public RequestLookAtMessage() { public RequestLookAtMessage() {
coordinate = BlockPos.ORIGIN;
blockState = null;
}
public RequestLookAtMessage(BlockPos coordinate, IBlockState blockState) {
this.coordinate = coordinate;
this.blockState = blockState;
}
public BlockPos getCoordinate() {
return coordinate;
}
public IBlockState getBlockState() {
return blockState;
} }
@Override @Override
public void toBytes(ByteBuf buf) { public void toBytes(ByteBuf buf) {
buf.writeInt(this.coordinate.getX());
buf.writeInt(this.coordinate.getY());
buf.writeInt(this.coordinate.getZ());
buf.writeInt(Block.getStateId(this.blockState));
} }
@Override @Override
public void fromBytes(ByteBuf buf) { public void fromBytes(ByteBuf buf) {
coordinate = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt());
blockState = Block.getStateById(buf.readInt());
} }
// The params of the IMessageHandler are <REQ, REPLY> // The params of the IMessageHandler are <REQ, REPLY>
@@ -42,6 +69,18 @@ public class RequestLookAtMessage implements IMessage {
if (ctx.side == Side.CLIENT){ if (ctx.side == Side.CLIENT){
//Received clientside //Received clientside
//Send back your info //Send back your info
EffortlessBuilding.proxy.getThreadListenerFromContext(ctx).addScheduledTask(() -> {
EntityPlayer player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx);
//Add to undo stack clientside
UndoRedo.addUndo(player, new BlockSet(
new ArrayList<BlockPos>() {{add(message.getCoordinate());}},
new ArrayList<IBlockState>() {{add(message.getBlockState());}},
new Vec3d(0,0,0),
message.getCoordinate(), message.getCoordinate()));
});
//Prevent double placing in normal mode with placeStartPos false //Prevent double placing in normal mode with placeStartPos false
return new BlockPlacedMessage(ClientProxy.previousLookAt, false); return new BlockPlacedMessage(ClientProxy.previousLookAt, false);
} }

View File

@@ -26,6 +26,9 @@ import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.client.event.ModelRegistryEvent; import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.event.TextureStitchEvent; import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.settings.IKeyConflictContext;
import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier;
import net.minecraftforge.event.entity.EntityJoinWorldEvent; import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
@@ -77,15 +80,23 @@ public class ClientProxy implements IProxy {
@Override @Override
public void init(FMLInitializationEvent event) { public void init(FMLInitializationEvent event) {
// register key bindings // register key bindings
keyBindings = new KeyBinding[5]; keyBindings = new KeyBinding[7];
// instantiate the key bindings // instantiate the key bindings
keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", Keyboard.KEY_ADD, "key.effortlessbuilding.category"); keyBindings[0] = new KeyBinding("key.effortlessbuilding.hud.desc", KeyConflictContext.UNIVERSAL, Keyboard.KEY_ADD, "key.effortlessbuilding.category");
keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", Keyboard.KEY_SUBTRACT, "key.effortlessbuilding.category"); keyBindings[1] = new KeyBinding("key.effortlessbuilding.replace.desc", KeyConflictContext.IN_GAME, Keyboard.KEY_SUBTRACT, "key.effortlessbuilding.category");
keyBindings[2] = new KeyBinding("key.effortlessbuilding.creative.desc", Keyboard.KEY_NONE, "key.effortlessbuilding.category"); keyBindings[2] = new KeyBinding("key.effortlessbuilding.creative.desc", KeyConflictContext.IN_GAME, Keyboard.KEY_NONE, "key.effortlessbuilding.category");
keyBindings[3] = new KeyBinding("key.effortlessbuilding.mode.desc", Keyboard.KEY_LMENU, "key.effortlessbuilding.category"); keyBindings[3] = new KeyBinding("key.effortlessbuilding.mode.desc", KeyConflictContext.IN_GAME, Keyboard.KEY_LMENU, "key.effortlessbuilding.category") {
keyBindings[4] = new KeyBinding("key.effortlessbuilding.undo.desc", Keyboard.KEY_U, "key.effortlessbuilding.category"); @Override
// keyBindings[5] = new KeyBinding("Reload shaders", Keyboard.KEY_TAB, "key.effortlessbuilding.category"); public boolean conflicts(KeyBinding other) {
//Does not conflict with Chisels and Bits radial menu
if (other.getKeyCode() == getKeyCode() && other.getKeyDescription().equals("mod.chiselsandbits.other.mode")) return false;
return super.conflicts(other);
}
};
keyBindings[4] = new KeyBinding("key.effortlessbuilding.undo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, Keyboard.KEY_Z, "key.effortlessbuilding.category");
keyBindings[5] = new KeyBinding("key.effortlessbuilding.redo.desc", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, Keyboard.KEY_Y, "key.effortlessbuilding.category");
keyBindings[6] = new KeyBinding("Reload shaders", Keyboard.KEY_TAB, "key.effortlessbuilding.category");
// register all the key bindings // register all the key bindings
for (int i = 0; i < keyBindings.length; ++i) { for (int i = 0; i < keyBindings.length; ++i) {
@@ -244,7 +255,6 @@ public class ClientProxy implements IProxy {
if (mc.gameSettings.keyBindAttack.isKeyDown()) { if (mc.gameSettings.keyBindAttack.isKeyDown()) {
//Break block in distance in creative (or survival if enabled in config) //Break block in distance in creative (or survival if enabled in config)
if (ReachHelper.canBreakFar(player)) {
if (breakCooldown <= 0) { if (breakCooldown <= 0) {
breakCooldown = 4; breakCooldown = 4;
RayTraceResult lookingAt = getLookingAt(player); RayTraceResult lookingAt = getLookingAt(player);
@@ -266,7 +276,6 @@ public class ClientProxy implements IProxy {
} else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) { } else if (buildMode == BuildModes.BuildModeEnum.NORMAL_PLUS) {
breakCooldown--; breakCooldown--;
} }
}
//EffortlessBuilding.packetHandler.sendToServer(new CancelModeMessage()); //EffortlessBuilding.packetHandler.sendToServer(new CancelModeMessage());
@@ -319,19 +328,25 @@ public class ClientProxy implements IProxy {
} }
} }
//Undo //Undo (Ctrl+Z)
if (keyBindings[4].isPressed()) { if (keyBindings[4].isPressed()) {
ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO; ModeOptions.ActionEnum action = ModeOptions.ActionEnum.UNDO;
if (player.isSneaking()) action = ModeOptions.ActionEnum.REDO; ModeOptions.performAction(player, action);
EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action));
}
//Redo (Ctrl+Y)
if (keyBindings[5].isPressed()) {
ModeOptions.ActionEnum action = ModeOptions.ActionEnum.REDO;
ModeOptions.performAction(player, action); ModeOptions.performAction(player, action);
EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action)); EffortlessBuilding.packetHandler.sendToServer(new ModeActionMessage(action));
} }
//For shader development //For shader development
// if (keyBindings[5].isPressed()) { if (keyBindings.length >= 7 && keyBindings[6].isPressed()) {
// ShaderHandler.init(); ShaderHandler.init();
// EffortlessBuilding.log(player, "Reloaded shaders"); EffortlessBuilding.log(player, "Reloaded shaders");
// } }
} }

View File

@@ -132,9 +132,13 @@ public class BlockPreviewRenderer {
//Unless alwaysShowBlockPreview is true in config //Unless alwaysShowBlockPreview is true in config
if (doRenderBlockPreviews(modifierSettings, modeSettings, startPos)) { if (doRenderBlockPreviews(modifierSettings, modeSettings, startPos)) {
//Keep blockstate the same for every block in the buildmode
//So dont rotate blocks when in the middle of placing wall etc.
if (BuildModes.isActive(player)) {
IBuildMode buildModeInstance = modeSettings.getBuildMode().instance; IBuildMode buildModeInstance = modeSettings.getBuildMode().instance;
if (buildModeInstance.getSideHit(player) != null) sideHit = buildModeInstance.getSideHit(player); if (buildModeInstance.getSideHit(player) != null) sideHit = buildModeInstance.getSideHit(player);
if (buildModeInstance.getHitVec(player) != null) hitVec = buildModeInstance.getHitVec(player); if (buildModeInstance.getHitVec(player) != null) hitVec = buildModeInstance.getHitVec(player);
}
if (sideHit != null) { if (sideHit != null) {

View File

@@ -2,8 +2,9 @@ key.effortlessbuilding.category=Effortless Building
key.effortlessbuilding.hud.desc=Modifier Menu key.effortlessbuilding.hud.desc=Modifier Menu
key.effortlessbuilding.replace.desc=Toggle QuickReplace key.effortlessbuilding.replace.desc=Toggle QuickReplace
key.effortlessbuilding.creative.desc=Toggle Survival/Creative Mode key.effortlessbuilding.creative.desc=Toggle Survival/Creative Mode
key.effortlessbuilding.mode.desc=Radial Menu key.effortlessbuilding.mode.desc=Radial Menu (C&B compatible)
key.effortlessbuilding.undo.desc=Undo key.effortlessbuilding.undo.desc=Undo
key.effortlessbuilding.redo.desc=Redo
item.effortlessbuilding:randomizer_bag.name=Randomizer Bag item.effortlessbuilding:randomizer_bag.name=Randomizer Bag
item.effortlessbuilding:reach_upgrade1.name=Reach Upgrade 1 item.effortlessbuilding:reach_upgrade1.name=Reach Upgrade 1

View File

@@ -102,5 +102,5 @@ void main() {
if (maskgs * 0.3 + place * 0.7 <= dissolve) if (maskgs * 0.3 + place * 0.7 <= dissolve)
gl_FragColor = vec4(texcolor.rgb, 0.0); gl_FragColor = vec4(texcolor.rgb, 0.0);
else gl_FragColor = color; else gl_FragColor = vec4(color.rgb, 0.85);
} }