From 821b46a253004f854522b9413b61fda977415c26 Mon Sep 17 00:00:00 2001 From: Christian Knaapen Date: Thu, 18 Oct 2018 16:50:39 +0200 Subject: [PATCH] Fixed shrinking itemstack with mirror/array when not using quickreplace. Fixed replacing same blocks dropping extra. --- .../nl/requios/effortlessbuilding/Array.java | 11 ++++--- .../effortlessbuilding/EventHandler.java | 31 ++++++++++++++++--- .../nl/requios/effortlessbuilding/Mirror.java | 12 ++++--- .../effortlessbuilding/QuickReplace.java | 17 +++------- .../effortlessbuilding/SurvivalHelper.java | 25 +++++++++------ 5 files changed, 59 insertions(+), 37 deletions(-) diff --git a/src/main/java/nl/requios/effortlessbuilding/Array.java b/src/main/java/nl/requios/effortlessbuilding/Array.java index c03d8ab..95b4b41 100644 --- a/src/main/java/nl/requios/effortlessbuilding/Array.java +++ b/src/main/java/nl/requios/effortlessbuilding/Array.java @@ -35,14 +35,14 @@ public class Array { } //Called from EventHandler - public static void onBlockPlaced(BlockEvent.PlaceEvent event) { - if (event.getWorld().isRemote) return; + public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) { + if (event.getWorld().isRemote) return false; //find arraysettings for the player that placed the block ArraySettings a = BuildSettingsManager.getBuildSettings(event.getPlayer()).getArraySettings(); - if (a == null || !a.enabled) return; + if (a == null || !a.enabled) return false; - if (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0) return; + if (a.offset.getX() == 0 && a.offset.getY() == 0 && a.offset.getZ() == 0) return false; BlockPos pos = event.getPos(); Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ()); @@ -76,7 +76,8 @@ public class Array { SurvivalHelper.placeBlock(event.getWorld(), event.getPlayer(), pos, blockState, itemStack, EnumFacing.NORTH, true, false); } } - //EffortlessBuilding.log(event.getPlayer(), String.valueOf(event.getPlayer().getHeldItem(event.getHand()).getCount())); + + return true; } private static IBlockState getBlockStateFromRandomizerBag(IItemHandler bagInventory, World world, EntityPlayer player, BlockPos pos, ItemStack itemStack) { diff --git a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java index 239b2e0..47985b5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/EventHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/EventHandler.java @@ -1,23 +1,31 @@ package nl.requios.effortlessbuilding; import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; +import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; +import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.world.BlockEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; import nl.requios.effortlessbuilding.capability.BuildModifierCapability; @Mod.EventBusSubscriber public class EventHandler { + private static boolean placedBlock = false; + private static BlockEvent.PlaceEvent placeEvent = null; + @SubscribeEvent public static void registerBlocks(RegistryEvent.Register event) { @@ -42,15 +50,28 @@ public class EventHandler } } + @SubscribeEvent + public static void onServerTick(TickEvent.ServerTickEvent event) { + if (placedBlock) { + placedBlock = false; + + Mirror.onBlockPlaced(placeEvent); + Array.onBlockPlaced(placeEvent); + } + } @SubscribeEvent public static void onBlockPlaced(BlockEvent.PlaceEvent event) { - QuickReplace.onBlockPlaced(event); - if (event.isCanceled()) return; - Mirror.onBlockPlaced(event); - Array.onBlockPlaced(event); - } + if (QuickReplace.onBlockPlaced(event)) { + event.setCanceled(true); + return; + } + //Delay mirror and array by a tick so we can edit the held itemstack + //Otherwise the itemstack count would be overridden by ItemBlock#onItemUse + placedBlock = true; + placeEvent = event; + } @SubscribeEvent public static void onBlockBroken(BlockEvent.BreakEvent event) { diff --git a/src/main/java/nl/requios/effortlessbuilding/Mirror.java b/src/main/java/nl/requios/effortlessbuilding/Mirror.java index f6651fb..77144f8 100644 --- a/src/main/java/nl/requios/effortlessbuilding/Mirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/Mirror.java @@ -62,14 +62,14 @@ public class Mirror { } //Called from EventHandler - public static void onBlockPlaced(BlockEvent.PlaceEvent event) { - if (event.getWorld().isRemote) return; + public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) { + if (event.getWorld().isRemote) return false; //find mirrorsettings for the player that placed the block MirrorSettings m = BuildSettingsManager.getBuildSettings(event.getPlayer()).getMirrorSettings(); - if (m == null) return; + if (m == null) return false; - if (!m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return; + if (!m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return false; //if within mirror distance, mirror BlockPos oldBlockPos = event.getPos(); @@ -77,7 +77,7 @@ public class Mirror { if (oldBlockPos.getX() + 0.5 < m.position.x - m.radius || oldBlockPos.getX() + 0.5 > m.position.x + m.radius || oldBlockPos.getY() + 0.5 < m.position.y - m.radius || oldBlockPos.getY() + 0.5 > m.position.y + m.radius || oldBlockPos.getZ() + 0.5 < m.position.z - m.radius || oldBlockPos.getZ() + 0.5 > m.position.z + m.radius) - return; + return false; ItemStack itemStack = event.getPlayer().getHeldItem(event.getHand()); @@ -98,6 +98,8 @@ public class Mirror { if (m.mirrorZ) { placeMirrorZ(event.getWorld(), event.getPlayer(), m, oldBlockPos, event.getPlacedBlock(), bagInventory, itemStack); } + + return true; } private static void placeMirrorX(World world, EntityPlayer player, MirrorSettings m, BlockPos oldBlockPos, IBlockState oldBlockState, IItemHandler bagInventory, ItemStack itemStack) { diff --git a/src/main/java/nl/requios/effortlessbuilding/QuickReplace.java b/src/main/java/nl/requios/effortlessbuilding/QuickReplace.java index 956c8fa..ed927f5 100644 --- a/src/main/java/nl/requios/effortlessbuilding/QuickReplace.java +++ b/src/main/java/nl/requios/effortlessbuilding/QuickReplace.java @@ -19,18 +19,18 @@ public class QuickReplace { //Dilemma in getting blockstate from event to when message is received: // 1) send via client. Then hacking makes it possible to place any block. // 2) save serverside. Messages may not be received chronologically so data could get switched. - //Solution for now: save blockstate per player. Messages from 1 player will rarely come unchronologically + //Solution for now: save data serverside and per player. Messages from 1 player will rarely come unchronologically //and players will rarely switch between blocks that quickly. private static Dictionary blockStates = new Hashtable<>(); private static Dictionary itemStacks = new Hashtable<>(); - public static void onBlockPlaced(BlockEvent.PlaceEvent event) { - if (event.getWorld().isRemote) return; + public static boolean onBlockPlaced(BlockEvent.PlaceEvent event) { + if (event.getWorld().isRemote) return true; //Only serverside BuildSettingsManager.BuildSettings buildSettings = BuildSettingsManager.getBuildSettings(event.getPlayer()); - if (!buildSettings.doQuickReplace()) return; + if (!buildSettings.doQuickReplace()) return false; //TODO base on player facing instead, no more messages (or break block clientside) @@ -40,7 +40,7 @@ public class QuickReplace { //RayTraceResult result = event.getWorld().rayTraceBlocks(event.getPlayer().getPositionEyes(1f), event.getPlayer().getLookVec()); EffortlessBuilding.packetHandler.sendTo(new QuickReplaceMessage(), (EntityPlayerMP) event.getPlayer()); - event.setCanceled(true); + return true; } public static void onMessageReceived(EntityPlayer player, QuickReplaceMessage message) { @@ -61,15 +61,8 @@ public class QuickReplace { IBlockState blockState = blockStates.get(player.getUniqueID()); ItemStack itemStack = itemStacks.get(player.getUniqueID()); - //SurvivalHelper.dropBlock(player.world, placedAgainstBlockPos, player); - //player.world.setBlockState(placedAgainstBlockPos, blockState); SurvivalHelper.placeBlock(player.world, player, placedAgainstBlockPos, blockState, itemStack, message.getSideHit(), true, false); -// //Shrink itemstack with 1 -// if (!player.isCreative() && Block.getBlockFromItem(itemStack.getItem()) == blockState.getBlock()) { -// itemStack.shrink(1); -// } - //Mirror and Array synergy BlockSnapshot blockSnapshot = new BlockSnapshot(player.world, placedAgainstBlockPos, blockState); BlockEvent.PlaceEvent placeEvent = new BlockEvent.PlaceEvent(blockSnapshot, blockState, player, EnumHand.MAIN_HAND); diff --git a/src/main/java/nl/requios/effortlessbuilding/SurvivalHelper.java b/src/main/java/nl/requios/effortlessbuilding/SurvivalHelper.java index e56f7d9..4d40ffb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/SurvivalHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/SurvivalHelper.java @@ -46,7 +46,7 @@ public class SurvivalHelper { Block block = ((ItemBlock) itemstack.getItem()).getBlock(); - if (!itemstack.isEmpty() && canPlayerEdit(player, world, pos, itemstack) && mayPlace(world, block, pos, skipCollisionCheck, facing.getOpposite(), player)) + if (!itemstack.isEmpty() && canPlayerEdit(player, world, pos, itemstack) && mayPlace(world, block, blockState, pos, skipCollisionCheck, facing.getOpposite(), player)) { //Drop existing block //TODO check if can replace @@ -117,7 +117,7 @@ public class SurvivalHelper { } //From World#mayPlace - private static boolean mayPlace(World world, Block blockIn, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer) + private static boolean mayPlace(World world, Block blockIn, IBlockState newBlockState, BlockPos pos, boolean skipCollisionCheck, EnumFacing sidePlacedOn, @Nullable Entity placer) { IBlockState iblockstate1 = world.getBlockState(pos); AxisAlignedBB axisalignedbb = skipCollisionCheck ? null : blockIn.getDefaultState().getCollisionBoundingBox(world, pos); @@ -126,16 +126,21 @@ public class SurvivalHelper { { return false; } - else if (iblockstate1.getMaterial() == Material.CIRCUITS && blockIn == Blocks.ANVIL) + + //Check if same block + //Necessary otherwise extra items will be dropped + if (iblockstate1 == newBlockState) { + return false; + } + + if (iblockstate1.getMaterial() == Material.CIRCUITS && blockIn == Blocks.ANVIL) { return true; } - else - { - //TODO check config for allow to replace - return true; - //TODO fix check canPlaceBlockOnSide - //return /*iblockstate1.getBlock().isReplaceable(world, pos) &&*/ blockIn.canPlaceBlockOnSide(world, pos, sidePlacedOn); - } + + //TODO check config for allow to replace + return true; + //TODO fix check canPlaceBlockOnSide + //return /*iblockstate1.getBlock().isReplaceable(world, pos) &&*/ blockIn.canPlaceBlockOnSide(world, pos, sidePlacedOn); } }