diff --git a/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java b/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java index 3a40119..6e29955 100644 --- a/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java +++ b/src/main/java/nl/requios/effortlessbuilding/ClientEvents.java @@ -66,13 +66,13 @@ public class ClientEvents { } } - @SubscribeEvent - public static void registerShaders(RegisterShadersEvent event) throws IOException { - event.registerShader(new ShaderInstance(event.getResourceManager(), - new ResourceLocation(EffortlessBuilding.MODID, "dissolve"), - DefaultVertexFormat.BLOCK), - shaderInstance -> BuildRenderTypes.dissolveShaderInstance = shaderInstance); - } +// @SubscribeEvent +// public static void registerShaders(RegisterShadersEvent event) throws IOException { +// event.registerShader(new ShaderInstance(event.getResourceManager(), +// new ResourceLocation(EffortlessBuilding.MODID, "dissolve"), +// DefaultVertexFormat.BLOCK), +// shaderInstance -> BuildRenderTypes.dissolveShaderInstance = shaderInstance); +// } } @SubscribeEvent @@ -223,19 +223,6 @@ public class ClientEvents { keyBindings[keybindIndex].getKey().getValue()); } - public static BlockHitResult getLookingAtFar(Player player) { - Level world = player.level; - - //base distance off of player ability (config) - float raytraceRange = ReachHelper.getPlacementReach(player); - - Vec3 look = player.getLookAngle(); - Vec3 start = new Vec3(player.getX(), player.getY() + player.getEyeHeight(), player.getZ()); - Vec3 end = new Vec3(player.getX() + look.x * raytraceRange, player.getY() + player.getEyeHeight() + look.y * raytraceRange, player.getZ() + look.z * raytraceRange); - - return world.clip(new ClipContext(start, end, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player)); - } - public static boolean isGameActive() { return !(Minecraft.getInstance().level == null || Minecraft.getInstance().player == null); } diff --git a/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java b/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java index 349ab52..5f2d84e 100644 --- a/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java +++ b/src/main/java/nl/requios/effortlessbuilding/CommonEvents.java @@ -3,10 +3,8 @@ package nl.requios.effortlessbuilding; import net.minecraft.world.InteractionHand; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.Blocks; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; -import net.minecraft.server.level.ServerPlayer; import net.minecraft.resources.ResourceLocation; import net.minecraftforge.common.capabilities.RegisterCapabilitiesEvent; import net.minecraftforge.common.util.FakePlayer; @@ -16,14 +14,10 @@ import net.minecraftforge.event.entity.player.PlayerEvent; import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; -import net.minecraftforge.network.PacketDistributor; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.systems.UndoRedo; -import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.systems.ServerBuildState; import nl.requios.effortlessbuilding.utilities.ReachHelper; -import nl.requios.effortlessbuilding.network.PacketHandler; @EventBusSubscriber public class CommonEvents { @@ -32,18 +26,7 @@ public class CommonEvents { @EventBusSubscriber(bus = EventBusSubscriber.Bus.MOD) public static class ModBusEvents { - @SubscribeEvent - public void registerCapabilities(RegisterCapabilitiesEvent event){ - event.register(ModifierCapabilityManager.IModifierCapability.class); - } - } - @SubscribeEvent - public static void attachCapabilities(AttachCapabilitiesEvent event) { - if (event.getObject() instanceof FakePlayer) return; - if (event.getObject() instanceof Player) { - event.addCapability(new ResourceLocation(EffortlessBuilding.MODID, "build_modifier"), new ModifierCapabilityManager.Provider()); - } } @SubscribeEvent @@ -98,15 +81,22 @@ public class CommonEvents { public static void onPlayerLoggedIn(PlayerEvent.PlayerLoggedInEvent event) { if (event.getEntity() instanceof FakePlayer) return; Player player = event.getEntity(); + if (player.getCommandSenderWorld().isClientSide) { + EffortlessBuilding.log("PlayerLoggedInEvent triggers on client side"); + return; + } + ServerBuildState.handleNewPlayer(player); - ModifierSettingsManager.handleNewPlayer(player); } @SubscribeEvent public static void onPlayerLoggedOut(PlayerEvent.PlayerLoggedOutEvent event) { if (event.getEntity() instanceof FakePlayer) return; Player player = event.getEntity(); - if (player.getCommandSenderWorld().isClientSide) return; + if (player.getCommandSenderWorld().isClientSide) { + EffortlessBuilding.log("PlayerLoggedOutEvent triggers on client side"); + return; + } UndoRedo.clear(player); } @@ -115,37 +105,27 @@ public class CommonEvents { public static void onPlayerRespawn(PlayerEvent.PlayerRespawnEvent event) { if (event.getEntity() instanceof FakePlayer) return; Player player = event.getEntity(); + if (player.getCommandSenderWorld().isClientSide) { + EffortlessBuilding.log("PlayerRespawnEvent triggers on client side"); + return; + } + + //TODO check if this is needed ServerBuildState.handleNewPlayer(player); - ModifierSettingsManager.handleNewPlayer(player); } @SubscribeEvent public static void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event) { if (event.getEntity() instanceof FakePlayer) return; Player player = event.getEntity(); - if (player.getCommandSenderWorld().isClientSide) return; - - //Disable modifiers - ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(player); - modifierSettings.getMirrorSettings().enabled = false; - modifierSettings.getRadialMirrorSettings().enabled = false; - modifierSettings.getArraySettings().enabled = false; - ModifierSettingsManager.setModifierSettings(player, modifierSettings); - - ServerBuildState.handleNewPlayer(player); - ModifierSettingsManager.handleNewPlayer(player); + if (player.getCommandSenderWorld().isClientSide) { + EffortlessBuilding.log("PlayerChangedDimensionEvent triggers on client side"); + return; + } + //Undo redo has no dimension data, so clear it UndoRedo.clear(player); - } - @SubscribeEvent - public static void onPlayerClone(PlayerEvent.Clone event) { - if (event.getEntity() instanceof FakePlayer) return; - //Attach capabilities on death, otherwise crash - Player oldPlayer = event.getOriginal(); - oldPlayer.revive(); - - Player newPlayer = event.getEntity(); - ModifierSettingsManager.setModifierSettings(newPlayer, ModifierSettingsManager.getModifierSettings(oldPlayer)); + //TODO disable build mode and modifiers? } } \ No newline at end of file diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java index f7b87dd..6c1b175 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmode/BuildModes.java @@ -18,7 +18,7 @@ import java.util.*; public class BuildModes { private BuildModeEnum buildMode = BuildModeEnum.DISABLED; - public void findCoordinates(BlockSet blocks, Player player, BuildModeEnum buildMode) { + public void findCoordinates(BlockSet blocks, Player player) { buildMode.instance.findCoordinates(blocks); } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java index a90703f..fe68794 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Array.java @@ -1,5 +1,8 @@ package nl.requios.effortlessbuilding.buildmodifier; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -10,95 +13,56 @@ import net.minecraft.world.phys.Vec3; import net.minecraft.core.Vec3i; import net.minecraftforge.items.IItemHandler; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; +import nl.requios.effortlessbuilding.utilities.BlockEntry; +import nl.requios.effortlessbuilding.utilities.BlockSet; import java.util.ArrayList; import java.util.List; -public class Array { +public class Array extends BaseModifier { - public static List findCoordinates(Player player, BlockPos startPos) { - List coordinates = new ArrayList<>(); + public BlockPos offset = BlockPos.ZERO; + public int count = 5; - //find arraysettings for the player - ArraySettings a = ModifierSettingsManager.getModifierSettings(player).getArraySettings(); - if (!isEnabled(a)) return coordinates; + @Override + public void findCoordinates(BlockSet blocks, Player player) { + if (!enabled || offset.getX() == 0 && offset.getY() == 0 && offset.getZ() == 0) return; - BlockPos pos = startPos; - Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ()); + var originalBlocks = new BlockSet(blocks); + for (BlockEntry blockEntry : originalBlocks) { + var pos = blockEntry.blockPos; + for (int i = 0; i < count; i++) { + pos = pos.offset(offset); + if (blocks.containsKey(pos)) continue; - for (int i = 0; i < a.count; i++) { - pos = pos.offset(offset); - coordinates.add(pos); - } - - return coordinates; - } - - public static List findBlockStates(Player player, BlockPos startPos, BlockState blockState, ItemStack itemStack, List itemStacks) { - List blockStates = new ArrayList<>(); - - //find arraysettings for the player that placed the block - ArraySettings a = ModifierSettingsManager.getModifierSettings(player).getArraySettings(); - if (!isEnabled(a)) return blockStates; - - BlockPos pos = startPos; - Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ()); - - //Randomizer bag synergy - AbstractRandomizerBagItem randomizerBagItem = null; - IItemHandler bagInventory = null; - if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) { - randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem() ; - bagInventory = randomizerBagItem.getBagInventory(itemStack); - } - - for (int i = 0; i < a.count; i++) { - pos = pos.offset(offset); - - //Randomizer bag synergy - if (randomizerBagItem != null) { - itemStack = randomizerBagItem.pickRandomStack(bagInventory); - blockState = BuildModifiers - .getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vec3(0, 0, 0), InteractionHand.MAIN_HAND); + var newBlockEntry = new BlockEntry(pos); + newBlockEntry.copyRotationSettingsFrom(blockEntry); } - - //blockState = blockState.getBlock().getStateForPlacement(player.world, pos, ) - blockStates.add(blockState); - itemStacks.add(itemStack); - } - - return blockStates; - } - - public static boolean isEnabled(ArraySettings a) { - if (a == null || !a.enabled) return false; - - return a.offset.getX() != 0 || a.offset.getY() != 0 || a.offset.getZ() != 0; - } - - public static class ArraySettings { - public boolean enabled = false; - public BlockPos offset = BlockPos.ZERO; - public int count = 5; - - public ArraySettings() { - } - - public ArraySettings(boolean enabled, BlockPos offset, int count) { - this.enabled = enabled; - this.offset = offset; - this.count = count; - } - - public int getReach() { - //find largest offset - int x = Math.abs(offset.getX()); - int y = Math.abs(offset.getY()); - int z = Math.abs(offset.getZ()); - int largestOffset = Math.max(Math.max(x, y), z); - - return largestOffset * count; } } + public int getReach() { + //find largest offset + int x = Math.abs(offset.getX()); + int y = Math.abs(offset.getY()); + int z = Math.abs(offset.getZ()); + int largestOffset = Math.max(Math.max(x, y), z); + + return largestOffset * count; + } + + @Override + public CompoundTag serializeNBT() { + var compound = super.serializeNBT(); + compound.getCompound("offset").merge(NbtUtils.writeBlockPos(offset)); + compound.putInt("count", count); + return compound; + } + + @Override + public void deserializeNBT(CompoundTag compound) { + super.deserializeNBT(compound); + offset = NbtUtils.readBlockPos(compound.getCompound("offset")); + count = compound.getInt("count"); + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BaseModifier.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BaseModifier.java new file mode 100644 index 0000000..c629147 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BaseModifier.java @@ -0,0 +1,23 @@ +package nl.requios.effortlessbuilding.buildmodifier; + +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.Tag; +import net.minecraft.world.entity.player.Player; +import nl.requios.effortlessbuilding.utilities.BlockSet; + +public abstract class BaseModifier { + public boolean enabled = false; + + public abstract void findCoordinates(BlockSet blocks, Player player); + + public CompoundTag serializeNBT() { + CompoundTag compound = new CompoundTag(); + compound.putString("type", this.getClass().getSimpleName()); + compound.putBoolean("enabled", enabled); + return compound; + } + + public void deserializeNBT(CompoundTag compound) { + enabled = compound.getBoolean("enabled"); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java index 1d26754..32dc5d1 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/BuildModifiers.java @@ -1,6 +1,8 @@ package nl.requios.effortlessbuilding.buildmodifier; -import net.minecraft.client.player.LocalPlayer; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.Blocks; @@ -18,9 +20,11 @@ import net.minecraft.world.level.Level; import nl.requios.effortlessbuilding.CommonConfig; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.compatibility.CompatHelper; +import nl.requios.effortlessbuilding.create.foundation.utility.NBTHelper; import nl.requios.effortlessbuilding.systems.DelayedBlockPlacer; import nl.requios.effortlessbuilding.systems.UndoRedo; import nl.requios.effortlessbuilding.utilities.BlockSet; +import nl.requios.effortlessbuilding.utilities.ReachHelper; import nl.requios.effortlessbuilding.utilities.SurvivalHelper; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import nl.requios.effortlessbuilding.utilities.UndoRedoBlockSet; @@ -30,201 +34,133 @@ import java.util.Collections; import java.util.List; public class BuildModifiers { + private List modifierSettingsList = new ArrayList<>(); - public void findCoordinates(BlockSet blocks, LocalPlayer player, ModifierSettingsManager.ModifierSettings modifierSettings) { - + public List getModifierSettingsList() { + return Collections.unmodifiableList(modifierSettingsList); } - //Called from BuildModes - public static void onBlockPlaced(Player player, List startCoordinates, Direction sideHit, Vec3 hitVec, boolean placeStartPos) { - Level world = player.level; - AbstractRandomizerBagItem.renewRandomness(); + public void addModifierSettings(BaseModifier modifierSettings) { + modifierSettingsList.add(modifierSettings); + } - //Format hitvec to 0.x - hitVec = new Vec3(Math.abs(hitVec.x - ((int) hitVec.x)), Math.abs(hitVec.y - ((int) hitVec.y)), Math.abs(hitVec.z - ((int) hitVec.z))); + public void removeModifierSettings(BaseModifier modifierSettings) { + modifierSettingsList.remove(modifierSettings); + } - //find coordinates and blockstates - List coordinates = findCoordinates(player, startCoordinates); - List itemStacks = new ArrayList<>(); - List blockStates = findBlockStates(player, startCoordinates, hitVec, sideHit, itemStacks); + public void removeModifierSettings(int index) { + modifierSettingsList.remove(index); + } - //check if valid blockstates - if (blockStates.size() == 0 || coordinates.size() != blockStates.size()) return; + public void moveUp(BaseModifier modifierSettings) { + int index = modifierSettingsList.indexOf(modifierSettings); + if (index == 0) return; - if (world.isClientSide) { + Collections.swap(modifierSettingsList, index, index - 1); + } -// BlockPreviews.onBlocksPlaced(blocks); + public void moveDown(BaseModifier modifierSettings) { + int index = modifierSettingsList.indexOf(modifierSettings); + if (index == modifierSettingsList.size() - 1) return; - } else { + Collections.swap(modifierSettingsList, index, index + 1); + } - int delay = CommonConfig.visuals.appearAnimationLength.get() * 3 - 3; //DelayedBlockPlacer is 3 times faster than client tick? + public void setFirst(BaseModifier modifierSettings) { + int index = modifierSettingsList.indexOf(modifierSettings); + if (index == 0) return; - //place blocks after delay - EffortlessBuilding.DELAYED_BLOCK_PLACER.placeBlocksDelayed(new DelayedBlockPlacer.Entry(world, player, coordinates, - blockStates, itemStacks, placeStartPos, delay)); + modifierSettingsList.remove(index); + modifierSettingsList.add(0, modifierSettings); + } + + public void setLast(BaseModifier modifierSettings) { + int index = modifierSettingsList.indexOf(modifierSettings); + if (index == modifierSettingsList.size() - 1) return; + + modifierSettingsList.remove(index); + modifierSettingsList.add(modifierSettings); + } + + public void clearAllModifierSettings() { + modifierSettingsList.clear(); + } + + public void findCoordinates(BlockSet blocks, Player player) { + for (BaseModifier modifierSettings : modifierSettingsList) { + modifierSettings.findCoordinates(blocks, player); } } - public static void onBlockBroken(Player player, List startCoordinates, boolean breakStartPos) { - Level world = player.level; - - List coordinates = findCoordinates(player, startCoordinates); - - if (coordinates.isEmpty()) return; - - //remember previous blockstates for undo - List previousBlockStates = new ArrayList<>(coordinates.size()); - List newBlockStates = new ArrayList<>(coordinates.size()); - for (BlockPos coordinate : coordinates) { - previousBlockStates.add(world.getBlockState(coordinate)); - } - - if (world.isClientSide) { -// BlockPreviews.onBlocksBroken(blocks); - - //list of air blockstates - for (int i = 0; i < coordinates.size(); i++) { - newBlockStates.add(Blocks.AIR.defaultBlockState()); - } - - } else { - - //If the player is going to instabreak grass or a plant, only break other instabreaking things - boolean onlyInstaBreaking = !player.isCreative() && - world.getBlockState(startCoordinates.get(0)).getDestroySpeed(world, startCoordinates.get(0)) == 0f; - - //break all those blocks - for (int i = breakStartPos ? 0 : 1; i < coordinates.size(); i++) { - BlockPos coordinate = coordinates.get(i); - if (world.isLoaded(coordinate) && !world.isEmptyBlock(coordinate)) { - if (!onlyInstaBreaking || world.getBlockState(coordinate).getDestroySpeed(world, coordinate) == 0f) { - SurvivalHelper.breakBlock(world, player, coordinate, false); - } - } - } - - //find actual new blockstates for undo - for (BlockPos coordinate : coordinates) { - newBlockStates.add(world.getBlockState(coordinate)); - } - } - - //Set first newBlockState to empty if in NORMAL mode, to make undo/redo work - //(Block isn't broken yet by the time it gets here, and broken after this) - if (!breakStartPos) newBlockStates.set(0, Blocks.AIR.defaultBlockState()); - - //add to undo stack - BlockPos firstPos = startCoordinates.get(0); - BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1); - UndoRedo.addUndo(player, new UndoRedoBlockSet(coordinates, previousBlockStates, newBlockStates, firstPos, secondPos)); + private static final String DATA_KEY = EffortlessBuilding.MODID + ":buildModifiers"; + public void save(Player player) { + var listTag = NBTHelper.writeCompoundList(modifierSettingsList, BaseModifier::serializeNBT); + player.getPersistentData().put(DATA_KEY, listTag); } - public static List findCoordinates(Player player, List posList) { - List coordinates = new ArrayList<>(); - //Add current blocks being placed too - coordinates.addAll(posList); - - //Find mirror/array/radial mirror coordinates for each blockpos - for (BlockPos blockPos : posList) { - List arrayCoordinates = Array.findCoordinates(player, blockPos); - coordinates.addAll(arrayCoordinates); - coordinates.addAll(Mirror.findCoordinates(player, blockPos)); - coordinates.addAll(RadialMirror.findCoordinates(player, blockPos)); - //get mirror for each array coordinate - for (BlockPos coordinate : arrayCoordinates) { - coordinates.addAll(Mirror.findCoordinates(player, coordinate)); - coordinates.addAll(RadialMirror.findCoordinates(player, coordinate)); - } - } - - return coordinates; + //TODO call load + public void load(Player player) { + var listTag = player.getPersistentData().getList(DATA_KEY, Tag.TAG_COMPOUND); + modifierSettingsList = NBTHelper.readCompoundList(listTag, compoundTag -> { + var modifier = createModifier(compoundTag.getString("type")); + modifier.deserializeNBT(compoundTag); + return modifier; + }); } - public static List findCoordinates(Player player, BlockPos blockPos) { - return findCoordinates(player, new ArrayList<>(Collections.singletonList(blockPos))); + private BaseModifier createModifier(String type) { + switch (type) { + case "Mirror": return new Mirror(); + case "Array": return new Array(); + case "RadialMirror": return new RadialMirror(); + default: throw new IllegalArgumentException("Unknown modifier type: " + type); + } } - public static List findBlockStates(Player player, List posList, Vec3 hitVec, Direction facing, List itemStacks) { - List blockStates = new ArrayList<>(); - itemStacks.clear(); - - //Get itemstack - ItemStack itemStack = player.getItemInHand(InteractionHand.MAIN_HAND); - if (itemStack.isEmpty() || !CompatHelper.isItemBlockProxy(itemStack)) { - itemStack = player.getItemInHand(InteractionHand.OFF_HAND); - } - if (itemStack.isEmpty() || !CompatHelper.isItemBlockProxy(itemStack)) { - return blockStates; - } - - //Get ItemBlock stack - ItemStack itemBlock = ItemStack.EMPTY; - if (itemStack.getItem() instanceof BlockItem) itemBlock = itemStack; - else itemBlock = CompatHelper.getItemBlockFromStack(itemStack); - AbstractRandomizerBagItem.resetRandomness(); - - //Add blocks in posList first - for (BlockPos blockPos : posList) { - if (!(itemStack.getItem() instanceof BlockItem)) itemBlock = CompatHelper.getItemBlockFromStack(itemStack); - BlockState blockState = getBlockStateFromItem(itemBlock, player, blockPos, facing, hitVec, InteractionHand.MAIN_HAND); - if (blockState == null) continue; - - blockStates.add(blockState); - itemStacks.add(itemBlock); - } - - for (BlockPos blockPos : posList) { - BlockState blockState = getBlockStateFromItem(itemBlock, player, blockPos, facing, hitVec, InteractionHand.MAIN_HAND); - if (blockState == null) continue; - - List arrayBlockStates = Array.findBlockStates(player, blockPos, blockState, itemStack, itemStacks); - blockStates.addAll(arrayBlockStates); - blockStates.addAll(Mirror.findBlockStates(player, blockPos, blockState, itemStack, itemStacks)); - blockStates.addAll(RadialMirror.findBlockStates(player, blockPos, blockState, itemStack, itemStacks)); - //add mirror for each array coordinate - List arrayCoordinates = Array.findCoordinates(player, blockPos); - for (int i = 0; i < arrayCoordinates.size(); i++) { - BlockPos coordinate = arrayCoordinates.get(i); - BlockState blockState1 = arrayBlockStates.get(i); - if (blockState1 == null) continue; - - blockStates.addAll(Mirror.findBlockStates(player, coordinate, blockState1, itemStack, itemStacks)); - blockStates.addAll(RadialMirror.findBlockStates(player, coordinate, blockState1, itemStack, itemStacks)); - } - - //Adjust blockstates for torches and ladders etc to place on a valid side - //TODO optimize findCoordinates (done twice now) - //TODO fix mirror -// List coordinates = findCoordinates(player, startPos); -// for (int i = 0; i < blockStates.size(); i++) { -// blockStates.set(i, blockStates.get(i).getBlock().getStateForPlacement(player.world, coordinates.get(i), facing, -// (float) hitVec.x, (float) hitVec.y, (float) hitVec.z, itemStacks.get(i).getMetadata(), player, EnumHand.MAIN_HAND)); -// } - } - - return blockStates; - } - - public static BlockState getBlockStateFromItem(ItemStack itemStack, Player player, BlockPos blockPos, Direction facing, Vec3 hitVec, InteractionHand hand) { - return Block.byItem(itemStack.getItem()).getStateForPlacement(new BlockPlaceContext(new UseOnContext(player, hand, new BlockHitResult(hitVec, facing, blockPos, false)))); - } - - //Returns true if equal (or both null) - public static boolean compareCoordinates(List coordinates1, List coordinates2) { - if (coordinates1 == null && coordinates2 == null) return true; - if (coordinates1 == null || coordinates2 == null) return false; - - //Check count, not actual values - if (coordinates1.size() == coordinates2.size()) { - if (coordinates1.size() == 1) { - return coordinates1.get(0).equals(coordinates2.get(0)); - } - return true; - } else { - return false; - } - -// return coordinates1.equals(coordinates2); - } +// public static String sanitize(ModifierSettingsManager.ModifierSettings modifierSettings, Player player) { +// int maxReach = ReachHelper.getMaxReach(player); +// String error = ""; +// +// //Mirror settings +// Mirror.MirrorSettings m = modifierSettings.getMirrorSettings(); +// if (m.radius < 1) { +// m.radius = 1; +// error += "Mirror size has to be at least 1. This has been corrected. "; +// } +// if (m.getReach() > maxReach) { +// m.radius = maxReach / 2; +// error += "Mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to " + (maxReach / 2) + ". "; +// } +// +// //Array settings +// Array.ArraySettings a = modifierSettings.getArraySettings(); +// if (a.count < 0) { +// a.count = 0; +// error += "Array count may not be negative. It has been reset to 0."; +// } +// +// if (a.getReach() > maxReach) { +// a.count = 0; +// error += "Array exceeds your maximum reach of " + maxReach + ". Array count has been reset to 0. "; +// } +// +// //Radial mirror settings +// RadialMirror.RadialMirrorSettings r = modifierSettings.getRadialMirrorSettings(); +// if (r.slices < 2) { +// r.slices = 2; +// error += "Radial mirror needs to have at least 2 slices. Slices has been set to 2."; +// } +// +// if (r.radius < 1) { +// r.radius = 1; +// error += "Radial mirror radius has to be at least 1. This has been corrected. "; +// } +// if (r.getReach() > maxReach) { +// r.radius = maxReach / 2; +// error += "Radial mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to " + (maxReach / 2) + ". "; +// } +// +// return error; +// } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java index 1e358b1..f5db9ef 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/Mirror.java @@ -1,234 +1,113 @@ package nl.requios.effortlessbuilding.buildmodifier; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.nbt.Tag; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.block.state.properties.Half; -import net.minecraft.world.level.block.state.properties.SlabType; -import net.minecraft.core.Direction; -import net.minecraft.world.InteractionHand; import net.minecraft.core.BlockPos; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.items.IItemHandler; -import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; -import java.util.ArrayList; -import java.util.List; +import nl.requios.effortlessbuilding.utilities.BlockEntry; +import nl.requios.effortlessbuilding.utilities.BlockSet; -import net.minecraft.world.level.block.DirectionalBlock; -import net.minecraft.world.level.block.DispenserBlock; -import net.minecraft.world.level.block.SlabBlock; -import net.minecraft.world.level.block.StairBlock; -import net.minecraft.world.level.block.state.BlockState; +public class Mirror extends BaseModifier { + public Vec3 position = new Vec3(0.5, 64.5, 0.5); + public boolean mirrorX = true; + public boolean mirrorY = false; + public boolean mirrorZ = false; + public int radius = 10; + public boolean drawLines = true; + public boolean drawPlanes = true; + + @Override + public void findCoordinates(BlockSet blocks, Player player) { + if (!(enabled && (mirrorX || mirrorY || mirrorZ))) return; -public class Mirror { + var originalBlocks = new BlockSet(blocks); + for (BlockEntry blockEntry : originalBlocks) { + if (!isWithinRange(blockEntry.blockPos)) continue; - public static List findCoordinates(Player player, BlockPos startPos) { - List coordinates = new ArrayList<>(); - - //find mirrorsettings for the player - MirrorSettings m = ModifierSettingsManager.getModifierSettings(player).getMirrorSettings(); - if (!isEnabled(m, startPos)) return coordinates; - - if (m.mirrorX) coordinateMirrorX(m, startPos, coordinates); - if (m.mirrorY) coordinateMirrorY(m, startPos, coordinates); - if (m.mirrorZ) coordinateMirrorZ(m, startPos, coordinates); - - return coordinates; + if (mirrorX) performMirrorX(blocks, blockEntry); + if (mirrorY) performMirrorY(blocks, blockEntry); + if (mirrorZ) performMirrorZ(blocks, blockEntry); + } } - private static void coordinateMirrorX(MirrorSettings m, BlockPos oldBlockPos, List coordinates) { + private void performMirrorX(BlockSet blocks, BlockEntry blockEntry) { //find mirror position - double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5); - BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ()); - coordinates.add(newBlockPos); + double x = position.x + (position.x - blockEntry.blockPos.getX() - 0.5); + BlockPos newBlockPos = new BlockPos(x, blockEntry.blockPos.getY(), blockEntry.blockPos.getZ()); - if (m.mirrorY) coordinateMirrorY(m, newBlockPos, coordinates); - if (m.mirrorZ) coordinateMirrorZ(m, newBlockPos, coordinates); + if (blocks.containsKey(newBlockPos)) return; + + var newBlockEntry = new BlockEntry(newBlockPos); + newBlockEntry.copyRotationSettingsFrom(blockEntry); + newBlockEntry.mirrorX = !newBlockEntry.mirrorX; + + if (mirrorY) performMirrorY(blocks, newBlockEntry); + if (mirrorZ) performMirrorZ(blocks, newBlockEntry); } - private static void coordinateMirrorY(MirrorSettings m, BlockPos oldBlockPos, List coordinates) { + private void performMirrorY(BlockSet blocks, BlockEntry blockEntry) { //find mirror position - double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5); - BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ()); - coordinates.add(newBlockPos); + double y = position.y + (position.y - blockEntry.blockPos.getY() - 0.5); + BlockPos newBlockPos = new BlockPos(blockEntry.blockPos.getX(), y, blockEntry.blockPos.getZ()); - if (m.mirrorZ) coordinateMirrorZ(m, newBlockPos, coordinates); + if (blocks.containsKey(newBlockPos)) return; + + var newBlockEntry = new BlockEntry(newBlockPos); + newBlockEntry.copyRotationSettingsFrom(blockEntry); + newBlockEntry.mirrorY = !newBlockEntry.mirrorY; + + if (mirrorZ) performMirrorZ(blocks, newBlockEntry); } - private static void coordinateMirrorZ(MirrorSettings m, BlockPos oldBlockPos, List coordinates) { + private void performMirrorZ(BlockSet blocks, BlockEntry blockEntry) { //find mirror position - double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5); - BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z); - coordinates.add(newBlockPos); + double z = position.z + (position.z - blockEntry.blockPos.getZ() - 0.5); + BlockPos newBlockPos = new BlockPos(blockEntry.blockPos.getX(), blockEntry.blockPos.getY(), z); + + if (blocks.containsKey(newBlockPos)) return; + + var newBlockEntry = new BlockEntry(newBlockPos); + newBlockEntry.copyRotationSettingsFrom(blockEntry); + newBlockEntry.mirrorZ = !newBlockEntry.mirrorZ; } - public static List findBlockStates(Player player, BlockPos startPos, BlockState blockState, ItemStack itemStack, List itemStacks) { - List blockStates = new ArrayList<>(); - - //find mirrorsettings for the player - MirrorSettings m = ModifierSettingsManager.getModifierSettings(player).getMirrorSettings(); - if (!isEnabled(m, startPos)) return blockStates; - - //Randomizer bag synergy - AbstractRandomizerBagItem randomizerBagItem = null; - IItemHandler bagInventory = null; - if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) { - randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem() ; - bagInventory = randomizerBagItem.getBagInventory(itemStack); - } - - if (m.mirrorX) - blockStateMirrorX(player, m, startPos, blockState, bagInventory, itemStack, InteractionHand.MAIN_HAND, blockStates, itemStacks); - if (m.mirrorY) - blockStateMirrorY(player, m, startPos, blockState, bagInventory, itemStack, InteractionHand.MAIN_HAND, blockStates, itemStacks); - if (m.mirrorZ) - blockStateMirrorZ(player, m, startPos, blockState, bagInventory, itemStack, InteractionHand.MAIN_HAND, blockStates, itemStacks); - - return blockStates; + public boolean isWithinRange(BlockPos blockPos) { + return !(blockPos.getX() + 0.5 < position.x - radius) && !(blockPos.getX() + 0.5 > position.x + radius) && + !(blockPos.getY() + 0.5 < position.y - radius) && !(blockPos.getY() + 0.5 > position.y + radius) && + !(blockPos.getZ() + 0.5 < position.z - radius) && !(blockPos.getZ() + 0.5 > position.z + radius); + } + + public int getReach() { + return radius * 2; //Change ModifierSettings#setReachUpgrade too } - private static void blockStateMirrorX(Player player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState, - IItemHandler bagInventory, ItemStack itemStack, InteractionHand hand, List blockStates, List itemStacks) { - //find mirror position - double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5); - BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ()); - - //Randomizer bag synergy - if (bagInventory != null) { - itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); - oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3(0, 0, 0), hand); - } - - //Find blockstate - BlockState newBlockState = oldBlockState == null ? null : oldBlockState.mirror(net.minecraft.world.level.block.Mirror.FRONT_BACK); - - //Store blockstate and itemstack - blockStates.add(newBlockState); - itemStacks.add(itemStack); - - if (m.mirrorY) - blockStateMirrorY(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks); - if (m.mirrorZ) - blockStateMirrorZ(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks); + @Override + public CompoundTag serializeNBT() { + var compound = super.serializeNBT(); + compound.putDouble("positionX", position.x); + compound.putDouble("positionY", position.y); + compound.putDouble("positionZ", position.z); + compound.putBoolean("mirrorX", mirrorX); + compound.putBoolean("mirrorY", mirrorY); + compound.putBoolean("mirrorZ", mirrorZ); + compound.putInt("radius", radius); + compound.putBoolean("drawLines", drawLines); + compound.putBoolean("drawPlanes", drawPlanes); + return compound; } - private static void blockStateMirrorY(Player player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState, - IItemHandler bagInventory, ItemStack itemStack, InteractionHand hand, List blockStates, List itemStacks) { - //find mirror position - double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5); - BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ()); - - //Randomizer bag synergy - if (bagInventory != null) { - itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); - oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3(0, 0, 0), hand); - } - - //Find blockstate - BlockState newBlockState = oldBlockState == null ? null : getVerticalMirror(oldBlockState); - - //Store blockstate and itemstack - blockStates.add(newBlockState); - itemStacks.add(itemStack); - - if (m.mirrorZ) - blockStateMirrorZ(player, m, newBlockPos, newBlockState, bagInventory, itemStack, hand, blockStates, itemStacks); - } - - private static void blockStateMirrorZ(Player player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState, - IItemHandler bagInventory, ItemStack itemStack, InteractionHand hand, List blockStates, List itemStacks) { - //find mirror position - double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5); - BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z); - - //Randomizer bag synergy - if (bagInventory != null) { - itemStack = ((AbstractRandomizerBagItem)itemStack.getItem()).pickRandomStack(bagInventory); - oldBlockState = BuildModifiers.getBlockStateFromItem(itemStack, player, oldBlockPos, Direction.UP, new Vec3(0, 0, 0), hand); - } - - //Find blockstate - BlockState newBlockState = oldBlockState == null ? null : oldBlockState.mirror(net.minecraft.world.level.block.Mirror.LEFT_RIGHT); - - //Store blockstate and itemstack - blockStates.add(newBlockState); - itemStacks.add(itemStack); - } - - public static boolean isEnabled(MirrorSettings m, BlockPos startPos) { - if (m == null || !m.enabled || (!m.mirrorX && !m.mirrorY && !m.mirrorZ)) return false; - - //within mirror distance - return !(startPos.getX() + 0.5 < m.position.x - m.radius) && !(startPos.getX() + 0.5 > m.position.x + m.radius) && - !(startPos.getY() + 0.5 < m.position.y - m.radius) && !(startPos.getY() + 0.5 > m.position.y + m.radius) && - !(startPos.getZ() + 0.5 < m.position.z - m.radius) && !(startPos.getZ() + 0.5 > m.position.z + m.radius); - } - - private static BlockState getVerticalMirror(BlockState blockState) { - //Stairs - if (blockState.getBlock() instanceof StairBlock) { - if (blockState.getValue(StairBlock.HALF) == Half.BOTTOM) { - return blockState.setValue(StairBlock.HALF, Half.TOP); - } else { - return blockState.setValue(StairBlock.HALF, Half.BOTTOM); - } - } - - //Slabs - if (blockState.getBlock() instanceof SlabBlock) { - if (blockState.getValue(SlabBlock.TYPE) == SlabType.DOUBLE) { - return blockState; - } else if (blockState.getValue(SlabBlock.TYPE) == SlabType.BOTTOM) { - return blockState.setValue(SlabBlock.TYPE, SlabType.TOP); - } else { - return blockState.setValue(SlabBlock.TYPE, SlabType.BOTTOM); - } - } - - //Buttons, endrod, observer, piston - if (blockState.getBlock() instanceof DirectionalBlock) { - if (blockState.getValue(DirectionalBlock.FACING) == Direction.DOWN) { - return blockState.setValue(DirectionalBlock.FACING, Direction.UP); - } else if (blockState.getValue(DirectionalBlock.FACING) == Direction.UP) { - return blockState.setValue(DirectionalBlock.FACING, Direction.DOWN); - } - } - - //Dispenser, dropper - if (blockState.getBlock() instanceof DispenserBlock) { - if (blockState.getValue(DispenserBlock.FACING) == Direction.DOWN) { - return blockState.setValue(DispenserBlock.FACING, Direction.UP); - } else if (blockState.getValue(DispenserBlock.FACING) == Direction.UP) { - return blockState.setValue(DispenserBlock.FACING, Direction.DOWN); - } - } - - return blockState; - } - - public static class MirrorSettings { - public boolean enabled = false; - public Vec3 position = new Vec3(0.5, 64.5, 0.5); - public boolean mirrorX = true, mirrorY = false, mirrorZ = false; - public int radius = 10; - public boolean drawLines = true, drawPlanes = true; - - public MirrorSettings() { - } - - public MirrorSettings(boolean mirrorEnabled, Vec3 position, boolean mirrorX, boolean mirrorY, boolean mirrorZ, int radius, boolean drawLines, boolean drawPlanes) { - this.enabled = mirrorEnabled; - this.position = position; - this.mirrorX = mirrorX; - this.mirrorY = mirrorY; - this.mirrorZ = mirrorZ; - this.radius = radius; - this.drawLines = drawLines; - this.drawPlanes = drawPlanes; - } - - public int getReach() { - return radius * 2; //Change ModifierSettings#setReachUpgrade too - } + @Override + public void deserializeNBT(CompoundTag compound) { + super.deserializeNBT(compound); + position = new Vec3(compound.getDouble("positionX"), compound.getDouble("positionY"), compound.getDouble("positionZ")); + mirrorX = compound.getBoolean("mirrorX"); + mirrorY = compound.getBoolean("mirrorY"); + mirrorZ = compound.getBoolean("mirrorZ"); + radius = compound.getInt("radius"); + drawLines = compound.getBoolean("drawLines"); + drawPlanes = compound.getBoolean("drawPlanes"); } } diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java deleted file mode 100644 index 7acf115..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/ModifierSettingsManager.java +++ /dev/null @@ -1,166 +0,0 @@ -package nl.requios.effortlessbuilding.buildmodifier; - -import net.minecraft.world.entity.player.Player; -import net.minecraft.server.level.ServerPlayer; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.network.PacketDistributor; -import nl.requios.effortlessbuilding.CommonConfig; -import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.capability.ModifierCapabilityManager; -import nl.requios.effortlessbuilding.utilities.ReachHelper; -import nl.requios.effortlessbuilding.network.ModifierSettingsMessage; -import nl.requios.effortlessbuilding.network.PacketHandler; - -import javax.annotation.Nonnull; - -@Mod.EventBusSubscriber -public class ModifierSettingsManager { - - //Retrieves the buildsettings of a player through the modifierCapability capability - //Never returns null - @Nonnull - public static ModifierSettings getModifierSettings(Player player) { - - LazyOptional modifierCapability = - player.getCapability(ModifierCapabilityManager.MODIFIER_CAPABILITY, null); - - if (modifierCapability.isPresent()) { - ModifierCapabilityManager.IModifierCapability capability = modifierCapability.orElse(null); - if (capability.getModifierData() == null){ - capability.setModifierData(new ModifierSettings()); - } - return capability.getModifierData(); - } - - EffortlessBuilding.logger.warn("Player does not have modifierCapability: " + player); - //Return dummy settings - return new ModifierSettings(); - } - - public static void setModifierSettings(Player player, ModifierSettings modifierSettings) { - if (player == null) { - EffortlessBuilding.log("Cannot set buildsettings, player is null"); - return; - } - - LazyOptional modifierCapability = - player.getCapability(ModifierCapabilityManager.MODIFIER_CAPABILITY, null); - - modifierCapability.ifPresent((capability) -> { - capability.setModifierData(modifierSettings); - }); - - if (!modifierCapability.isPresent()) { - EffortlessBuilding.log(player, "Saving buildsettings failed."); - } - } - - public static String sanitize(ModifierSettings modifierSettings, Player player) { - int maxReach = ReachHelper.getMaxReach(player); - String error = ""; - - //Mirror settings - Mirror.MirrorSettings m = modifierSettings.getMirrorSettings(); - if (m.radius < 1) { - m.radius = 1; - error += "Mirror size has to be at least 1. This has been corrected. "; - } - if (m.getReach() > maxReach) { - m.radius = maxReach / 2; - error += "Mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to " + (maxReach / 2) + ". "; - } - - //Array settings - Array.ArraySettings a = modifierSettings.getArraySettings(); - if (a.count < 0) { - a.count = 0; - error += "Array count may not be negative. It has been reset to 0."; - } - - if (a.getReach() > maxReach) { - a.count = 0; - error += "Array exceeds your maximum reach of " + maxReach + ". Array count has been reset to 0. "; - } - - //Radial mirror settings - RadialMirror.RadialMirrorSettings r = modifierSettings.getRadialMirrorSettings(); - if (r.slices < 2) { - r.slices = 2; - error += "Radial mirror needs to have at least 2 slices. Slices has been set to 2."; - } - - if (r.radius < 1) { - r.radius = 1; - error += "Radial mirror radius has to be at least 1. This has been corrected. "; - } - if (r.getReach() > maxReach) { - r.radius = maxReach / 2; - error += "Radial mirror exceeds your maximum reach of " + (maxReach / 2) + ". Radius has been set to " + (maxReach / 2) + ". "; - } - - return error; - } - - public static void handleNewPlayer(Player player) { - //Makes sure player has modifier settings (if it doesnt it will create it) - getModifierSettings(player); - - //Only on server - if (!player.level.isClientSide) { - //Send to client - ModifierSettingsMessage msg = new ModifierSettingsMessage(getModifierSettings(player)); - PacketHandler.INSTANCE.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) player), msg); - } - } - - public static class ModifierSettings { - private Mirror.MirrorSettings mirrorSettings; - private Array.ArraySettings arraySettings; - private RadialMirror.RadialMirrorSettings radialMirrorSettings; - - public ModifierSettings() { - mirrorSettings = new Mirror.MirrorSettings(); - arraySettings = new Array.ArraySettings(); - radialMirrorSettings = new RadialMirror.RadialMirrorSettings(); - } - - public ModifierSettings(Mirror.MirrorSettings mirrorSettings, Array.ArraySettings arraySettings, - RadialMirror.RadialMirrorSettings radialMirrorSettings) { - this.mirrorSettings = mirrorSettings; - this.arraySettings = arraySettings; - this.radialMirrorSettings = radialMirrorSettings; - } - - public Mirror.MirrorSettings getMirrorSettings() { - if (this.mirrorSettings == null) this.mirrorSettings = new Mirror.MirrorSettings(); - return this.mirrorSettings; - } - - public void setMirrorSettings(Mirror.MirrorSettings mirrorSettings) { - if (mirrorSettings == null) return; - this.mirrorSettings = mirrorSettings; - } - - public Array.ArraySettings getArraySettings() { - if (this.arraySettings == null) this.arraySettings = new Array.ArraySettings(); - return this.arraySettings; - } - - public void setArraySettings(Array.ArraySettings arraySettings) { - if (arraySettings == null) return; - this.arraySettings = arraySettings; - } - - public RadialMirror.RadialMirrorSettings getRadialMirrorSettings() { - if (this.radialMirrorSettings == null) this.radialMirrorSettings = new RadialMirror.RadialMirrorSettings(); - return this.radialMirrorSettings; - } - - public void setRadialMirrorSettings(RadialMirror.RadialMirrorSettings radialMirrorSettings) { - if (radialMirrorSettings == null) return; - this.radialMirrorSettings = radialMirrorSettings; - } - } -} - diff --git a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java index 347dc2b..944a175 100644 --- a/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java +++ b/src/main/java/nl/requios/effortlessbuilding/buildmodifier/RadialMirror.java @@ -1,5 +1,6 @@ package nl.requios.effortlessbuilding.buildmodifier; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -12,107 +13,91 @@ import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec3; import net.minecraftforge.items.IItemHandler; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; +import nl.requios.effortlessbuilding.utilities.BlockEntry; +import nl.requios.effortlessbuilding.utilities.BlockSet; import java.util.ArrayList; import java.util.List; -public class RadialMirror { +public class RadialMirror extends BaseModifier { - public static List findCoordinates(Player player, BlockPos startPos) { - List coordinates = new ArrayList<>(); + public Vec3 position = new Vec3(0.5, 64.5, 0.5); + public int slices = 4; + public boolean alternate = false; + public int radius = 20; + public boolean drawLines = true; + public boolean drawPlanes = false; - //find radial mirror settings for the player - RadialMirrorSettings r = ModifierSettingsManager.getModifierSettings(player).getRadialMirrorSettings(); - if (!isEnabled(r, startPos)) return coordinates; + @Override + public void findCoordinates(BlockSet blocks, Player player) { + if (!enabled) return; + + var originalBlocks = new BlockSet(blocks); + for (BlockEntry blockEntry : originalBlocks) { + if (!isWithinRange(blockEntry.blockPos)) continue; + + performRadialMirror(blocks, blockEntry); + } + } + + public void performRadialMirror(BlockSet blocks, BlockEntry blockEntry) { //get angle between slices - double sliceAngle = 2 * Math.PI / r.slices; + double sliceAngle = 2 * Math.PI / slices; - Vec3 startVec = new Vec3(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f); - Vec3 relStartVec = startVec.subtract(r.position); + //Get start vector relative to mirror center + Vec3 relStartVec = Vec3.atCenterOf(blockEntry.blockPos).subtract(position); - double startAngleToCenter = Mth.atan2(relStartVec.x, relStartVec.z); + double startAngleToCenter = Mth.atan2(relStartVec.x, relStartVec.z); //between -PI and PI + //TODO change to Abs if alternative? if (startAngleToCenter < 0) startAngleToCenter += Math.PI; double startAngleInSlice = startAngleToCenter % sliceAngle; - for (int i = 1; i < r.slices; i++) { + for (int i = 1; i < slices; i++) { double curAngle = sliceAngle * i; //alternate mirroring of slices - if (r.alternate && i % 2 == 1) { + boolean doAlternate = alternate && i % 2 == 1; + if (doAlternate) { curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice); } Vec3 relNewVec = relStartVec.yRot((float) curAngle); - BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec)); - if (!coordinates.contains(newBlockPos) && !newBlockPos.equals(startPos)) coordinates.add(newBlockPos); - } + BlockPos newBlockPos = new BlockPos(position.add(relNewVec)); - return coordinates; + if (blocks.containsKey(newBlockPos)) continue; + + BlockEntry newBlockEntry = new BlockEntry(newBlockPos); + newBlockEntry.copyRotationSettingsFrom(blockEntry); + + //rotate block + double angleToCenter = Mth.atan2(relNewVec.x, relNewVec.z); //between -PI and PI + rotateBlockEntry(newBlockEntry, angleToCenter, doAlternate); + } } - public static List findBlockStates(Player player, BlockPos startPos, BlockState blockState, ItemStack itemStack, List itemStacks) { - List blockStates = new ArrayList<>(); - List coordinates = new ArrayList<>(); //to keep track of duplicates + private void rotateBlockEntry(BlockEntry blockEntry, double angleToCenter, boolean alternate) { - //find radial mirror settings for the player that placed the block - RadialMirrorSettings r = ModifierSettingsManager.getModifierSettings(player).getRadialMirrorSettings(); - if (!isEnabled(r, startPos)) return blockStates; - - - //get angle between slices - double sliceAngle = 2 * Math.PI / r.slices; - - Vec3 startVec = new Vec3(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f); - Vec3 relStartVec = startVec.subtract(r.position); - - double startAngleToCenter = Mth.atan2(relStartVec.x, relStartVec.z); - double startAngleToCenterMod = startAngleToCenter < 0 ? startAngleToCenter + Math.PI : startAngleToCenter; - double startAngleInSlice = startAngleToCenterMod % sliceAngle; - - //Rotate the original blockstate - blockState = rotateOriginalBlockState(player, startPos, startAngleToCenter, blockState); - - //Randomizer bag synergy - AbstractRandomizerBagItem randomizerBagItem = null; - IItemHandler bagInventory = null; - if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) { - randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem() ; - bagInventory = randomizerBagItem.getBagInventory(itemStack); - } - - BlockState newBlockState; - for (int i = 1; i < r.slices; i++) { - newBlockState = blockState; - double curAngle = sliceAngle * i; - - //alternate mirroring of slices - if (r.alternate && i % 2 == 1) { - curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice); + if (angleToCenter < -0.751 * Math.PI || angleToCenter > 0.749 * Math.PI) { + blockEntry.rotation = blockEntry.rotation.getRotated(Rotation.CLOCKWISE_180); + if (alternate) { + blockEntry.mirrorZ = !blockEntry.mirrorZ; } - - Vec3 relNewVec = relStartVec.yRot((float) curAngle); - BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec)); - if (coordinates.contains(newBlockPos) || newBlockPos.equals(startPos)) continue; //filter out duplicates - coordinates.add(newBlockPos); - - //Randomizer bag synergy - if (randomizerBagItem != null) { - itemStack = randomizerBagItem.pickRandomStack(bagInventory); - newBlockState = BuildModifiers - .getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vec3(0, 0, 0), InteractionHand.MAIN_HAND); - - newBlockState = rotateOriginalBlockState(player, startPos, startAngleToCenter, newBlockState); + } else if (angleToCenter < -0.251 * Math.PI) { + blockEntry.rotation = blockEntry.rotation.getRotated(Rotation.CLOCKWISE_90); + if (alternate) { + blockEntry.mirrorX = !blockEntry.mirrorX; + } + } else if (angleToCenter > 0.249 * Math.PI) { + blockEntry.rotation = blockEntry.rotation.getRotated(Rotation.COUNTERCLOCKWISE_90); + if (alternate) { + blockEntry.mirrorX = !blockEntry.mirrorX; + } + } else { + if (alternate) { + blockEntry.mirrorZ = !blockEntry.mirrorZ; } - - //rotate - newBlockState = rotateBlockState(player, startPos, relNewVec, newBlockState, r.alternate && i % 2 == 1); - - blockStates.add(newBlockState); - itemStacks.add(itemStack); } - - return blockStates; } private static BlockState rotateOriginalBlockState(Player player, BlockPos startPos, double startAngleToCenter, BlockState blockState) { @@ -158,37 +143,36 @@ public class RadialMirror { return newBlockState; } - public static boolean isEnabled(RadialMirrorSettings r, BlockPos startPos) { - if (r == null || !r.enabled) return false; - - return !(new Vec3(startPos.getX() + 0.5, startPos.getY() + 0.5, startPos.getZ() + 0.5).subtract(r.position).lengthSqr() > - r.radius * r.radius); + public boolean isWithinRange(BlockPos startPos) { + return (new Vec3(startPos.getX() + 0.5, startPos.getY() + 0.5, startPos.getZ() + 0.5).subtract(position).lengthSqr() < radius * radius); } - public static class RadialMirrorSettings { - public boolean enabled = false; - public Vec3 position = new Vec3(0.5, 64.5, 0.5); - public int slices = 4; - public boolean alternate = false; - public int radius = 20; - public boolean drawLines = true, drawPlanes = false; - - public RadialMirrorSettings() { - } - - public RadialMirrorSettings(boolean enabled, Vec3 position, int slices, boolean alternate, int radius, boolean drawLines, boolean drawPlanes) { - this.enabled = enabled; - this.position = position; - this.slices = slices; - this.alternate = alternate; - this.radius = radius; - this.drawLines = drawLines; - this.drawPlanes = drawPlanes; - } - - public int getReach() { - return radius * 2; - } + public int getReach() { + return radius * 2; } + @Override + public CompoundTag serializeNBT() { + var compound = super.serializeNBT(); + compound.putDouble("positionX", position.x); + compound.putDouble("positionY", position.y); + compound.putDouble("positionZ", position.z); + compound.putInt("slices", slices); + compound.putBoolean("alternate", alternate); + compound.putInt("radius", radius); + compound.putBoolean("drawLines", drawLines); + compound.putBoolean("drawPlanes", drawPlanes); + return compound; + } + + @Override + public void deserializeNBT(CompoundTag nbt) { + super.deserializeNBT(nbt); + position = new Vec3(nbt.getDouble("positionX"), nbt.getDouble("positionY"), nbt.getDouble("positionZ")); + slices = nbt.getInt("slices"); + alternate = nbt.getBoolean("alternate"); + radius = nbt.getInt("radius"); + drawLines = nbt.getBoolean("drawLines"); + drawPlanes = nbt.getBoolean("drawPlanes"); + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/capability/ModifierCapabilityManager.java b/src/main/java/nl/requios/effortlessbuilding/capability/ModifierCapabilityManager.java deleted file mode 100644 index f2d6b75..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/capability/ModifierCapabilityManager.java +++ /dev/null @@ -1,180 +0,0 @@ -package nl.requios.effortlessbuilding.capability; - -import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; -import net.minecraft.core.Direction; -import net.minecraft.core.BlockPos; -import net.minecraft.world.phys.Vec3; -import net.minecraftforge.common.capabilities.*; -import net.minecraftforge.common.util.INBTSerializable; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.event.entity.player.PlayerEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod; -import nl.requios.effortlessbuilding.buildmodifier.Array; -import nl.requios.effortlessbuilding.buildmodifier.Mirror; -import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings; - -@Mod.EventBusSubscriber -public class ModifierCapabilityManager { - - public final static Capability MODIFIER_CAPABILITY = CapabilityManager.get(new CapabilityToken<>(){}); - - // Allows for the capability to persist after death. - @SubscribeEvent - public static void clonePlayer(PlayerEvent.Clone event) { - LazyOptional original = event.getOriginal().getCapability(MODIFIER_CAPABILITY, null); - LazyOptional clone = event.getEntity().getCapability(MODIFIER_CAPABILITY, null); - clone.ifPresent(cloneModifierCapability -> - original.ifPresent(originalModifierCapability -> - cloneModifierCapability.setModifierData(originalModifierCapability.getModifierData()))); - } - - public interface IModifierCapability { - ModifierSettings getModifierData(); - - void setModifierData(ModifierSettings modifierSettings); - } - - public static class ModifierCapability implements IModifierCapability { - private ModifierSettings modifierSettings; - - @Override - public ModifierSettings getModifierData() { - return modifierSettings; - } - - @Override - public void setModifierData(ModifierSettings modifierSettings) { - this.modifierSettings = modifierSettings; - } - } - - public static class Provider extends CapabilityProvider implements INBTSerializable { - - private final IModifierCapability instance = new ModifierCapability(); - private LazyOptional modifierCapabilityOptional = LazyOptional.of(() -> instance); - - public Provider() { - super(Provider.class); - gatherCapabilities(); - } - - @Nonnull - @Override - public LazyOptional getCapability(@Nonnull Capability cap, @Nullable Direction side) { - if (cap == MODIFIER_CAPABILITY) return modifierCapabilityOptional.cast(); - return LazyOptional.empty(); - } - - @Override - public void invalidateCaps() { - super.invalidateCaps(); - modifierCapabilityOptional.invalidate(); - } - - @Override - public void reviveCaps() { - super.reviveCaps(); - modifierCapabilityOptional = LazyOptional.of(() -> instance); - } - - @Override - public Tag serializeNBT() { - CompoundTag compound = new CompoundTag(); - ModifierSettings modifierSettings = instance.getModifierData(); - if (modifierSettings == null) modifierSettings = new ModifierSettings(); - - //MIRROR - Mirror.MirrorSettings m = modifierSettings.getMirrorSettings(); - if (m == null) m = new Mirror.MirrorSettings(); - compound.putBoolean("mirrorEnabled", m.enabled); - compound.putDouble("mirrorPosX", m.position.x); - compound.putDouble("mirrorPosY", m.position.y); - compound.putDouble("mirrorPosZ", m.position.z); - compound.putBoolean("mirrorX", m.mirrorX); - compound.putBoolean("mirrorY", m.mirrorY); - compound.putBoolean("mirrorZ", m.mirrorZ); - compound.putInt("mirrorRadius", m.radius); - compound.putBoolean("mirrorDrawLines", m.drawLines); - compound.putBoolean("mirrorDrawPlanes", m.drawPlanes); - - //ARRAY - Array.ArraySettings a = modifierSettings.getArraySettings(); - if (a == null) a = new Array.ArraySettings(); - compound.putBoolean("arrayEnabled", a.enabled); - compound.putInt("arrayOffsetX", a.offset.getX()); - compound.putInt("arrayOffsetY", a.offset.getY()); - compound.putInt("arrayOffsetZ", a.offset.getZ()); - compound.putInt("arrayCount", a.count); - - //compound.putBoolean("quickReplace", buildSettings.doQuickReplace()); dont save quickreplace - - //RADIAL MIRROR - RadialMirror.RadialMirrorSettings r = modifierSettings.getRadialMirrorSettings(); - if (r == null) r = new RadialMirror.RadialMirrorSettings(); - compound.putBoolean("radialMirrorEnabled", r.enabled); - compound.putDouble("radialMirrorPosX", r.position.x); - compound.putDouble("radialMirrorPosY", r.position.y); - compound.putDouble("radialMirrorPosZ", r.position.z); - compound.putInt("radialMirrorSlices", r.slices); - compound.putBoolean("radialMirrorAlternate", r.alternate); - compound.putInt("radialMirrorRadius", r.radius); - compound.putBoolean("radialMirrorDrawLines", r.drawLines); - compound.putBoolean("radialMirrorDrawPlanes", r.drawPlanes); - - return compound; - } - - @Override - public void deserializeNBT(Tag nbt) { - CompoundTag compound = (CompoundTag) nbt; - - //MIRROR - boolean mirrorEnabled = compound.getBoolean("mirrorEnabled"); - Vec3 mirrorPosition = new Vec3( - compound.getDouble("mirrorPosX"), - compound.getDouble("mirrorPosY"), - compound.getDouble("mirrorPosZ")); - boolean mirrorX = compound.getBoolean("mirrorX"); - boolean mirrorY = compound.getBoolean("mirrorY"); - boolean mirrorZ = compound.getBoolean("mirrorZ"); - int mirrorRadius = compound.getInt("mirrorRadius"); - boolean mirrorDrawLines = compound.getBoolean("mirrorDrawLines"); - boolean mirrorDrawPlanes = compound.getBoolean("mirrorDrawPlanes"); - Mirror.MirrorSettings mirrorSettings = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, mirrorDrawLines, mirrorDrawPlanes); - - //ARRAY - boolean arrayEnabled = compound.getBoolean("arrayEnabled"); - BlockPos arrayOffset = new BlockPos( - compound.getInt("arrayOffsetX"), - compound.getInt("arrayOffsetY"), - compound.getInt("arrayOffsetZ")); - int arrayCount = compound.getInt("arrayCount"); - Array.ArraySettings arraySettings = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); - - //RADIAL MIRROR - boolean radialMirrorEnabled = compound.getBoolean("radialMirrorEnabled"); - Vec3 radialMirrorPosition = new Vec3( - compound.getDouble("radialMirrorPosX"), - compound.getDouble("radialMirrorPosY"), - compound.getDouble("radialMirrorPosZ")); - int radialMirrorSlices = compound.getInt("radialMirrorSlices"); - boolean radialMirrorAlternate = compound.getBoolean("radialMirrorAlternate"); - int radialMirrorRadius = compound.getInt("radialMirrorRadius"); - boolean radialMirrorDrawLines = compound.getBoolean("radialMirrorDrawLines"); - boolean radialMirrorDrawPlanes = compound.getBoolean("radialMirrorDrawPlanes"); - RadialMirror.RadialMirrorSettings radialMirrorSettings = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, - radialMirrorSlices, radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes); - - ModifierSettings modifierSettings = new ModifierSettings(mirrorSettings, arraySettings, radialMirrorSettings); - instance.setModifierData(modifierSettings); - } - - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/AbstractSimiContainerScreen.java b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/AbstractSimiContainerScreen.java index 8a2c440..da48a96 100644 --- a/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/AbstractSimiContainerScreen.java +++ b/src/main/java/nl/requios/effortlessbuilding/create/foundation/gui/container/AbstractSimiContainerScreen.java @@ -127,10 +127,10 @@ public abstract class AbstractSimiContainerScreen arrayNumberFieldList = new ArrayList<>(); private GuiCheckBoxFixed buttonArrayEnabled; private GuiNumberField textArrayOffsetX, textArrayOffsetY, textArrayOffsetZ, textArrayCount; - public ArraySettingsGui(GuiScrollPane scrollPane) { + public ArrayPanel(GuiScrollPane scrollPane) { super(scrollPane); } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/BaseModifierPanel.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/BaseModifierPanel.java new file mode 100644 index 0000000..c4469f0 --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/BaseModifierPanel.java @@ -0,0 +1,14 @@ +package nl.requios.effortlessbuilding.gui.buildmodifier; + +import nl.requios.effortlessbuilding.buildmodifier.BaseModifier; +import nl.requios.effortlessbuilding.gui.elements.GuiCollapsibleScrollEntry; +import nl.requios.effortlessbuilding.gui.elements.GuiScrollPane; + +public abstract class BaseModifierPanel extends GuiCollapsibleScrollEntry { + + public BaseModifierPanel(GuiScrollPane scrollPane) { + super(scrollPane); + } + + public abstract void setModifier(BaseModifier modifier); +} diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorSettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorPanel.java similarity index 98% rename from src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorSettingsGui.java rename to src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorPanel.java index 16e8298..e8498fb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorSettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/MirrorPanel.java @@ -12,7 +12,6 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.EffortlessBuilding; import nl.requios.effortlessbuilding.buildmodifier.Mirror; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.gui.elements.*; import nl.requios.effortlessbuilding.utilities.ReachHelper; @@ -22,7 +21,7 @@ import java.util.List; @SuppressWarnings("Duplicates") @OnlyIn(Dist.CLIENT) -public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { +public class MirrorPanel extends BaseModifierPanel { protected static final ResourceLocation BUILDING_ICONS = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/building_icons.png"); @@ -35,7 +34,7 @@ public class MirrorSettingsGui extends GuiCollapsibleScrollEntry { private GuiIconButton buttonCurrentPosition, buttonToggleOdd, buttonDrawPlanes, buttonDrawLines; private boolean drawPlanes, drawLines, toggleOdd; - public MirrorSettingsGui(GuiScrollPane scrollPane) { + public MirrorPanel(GuiScrollPane scrollPane) { super(scrollPane); } diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifierSettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifierSettingsGui.java index 2495e59..ed26adb 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifierSettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/ModifierSettingsGui.java @@ -9,25 +9,32 @@ import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.ClientEvents; import nl.requios.effortlessbuilding.EffortlessBuilding; +import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.buildmodifier.Array; +import nl.requios.effortlessbuilding.buildmodifier.BaseModifier; import nl.requios.effortlessbuilding.buildmodifier.Mirror; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; +import nl.requios.effortlessbuilding.gui.elements.GuiCollapsibleScrollEntry; import nl.requios.effortlessbuilding.gui.elements.GuiScrollPane; -import nl.requios.effortlessbuilding.network.ModifierSettingsMessage; import nl.requios.effortlessbuilding.network.PacketHandler; -import nl.requios.effortlessbuilding.proxy.ClientProxy; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.List; +import java.util.Map; @OnlyIn(Dist.CLIENT) public class ModifierSettingsGui extends Screen { + private final Map modifierPanelMap = new HashMap() {{ + put(Mirror.class, MirrorPanel.class); + put(Array.class, ArrayPanel.class); + put(RadialMirror.class, RadialMirrorPanel.class); + }}; private GuiScrollPane scrollPane; + private List modifierPanels; private Button buttonClose; - private MirrorSettingsGui mirrorSettingsGui; - private ArraySettingsGui arraySettingsGui; - private RadialMirrorSettingsGui radialMirrorSettingsGui; - public ModifierSettingsGui() { super(Component.translatable("effortlessbuilding.screen.modifier_settings")); } @@ -38,14 +45,7 @@ public class ModifierSettingsGui extends Screen { scrollPane = new GuiScrollPane(this, font, 8, height - 30); - mirrorSettingsGui = new MirrorSettingsGui(scrollPane); - scrollPane.AddListEntry(mirrorSettingsGui); - - arraySettingsGui = new ArraySettingsGui(scrollPane); - scrollPane.AddListEntry(arraySettingsGui); - - radialMirrorSettingsGui = new RadialMirrorSettingsGui(scrollPane); - scrollPane.AddListEntry(radialMirrorSettingsGui); + initScrollEntries(); scrollPane.init(renderables); @@ -57,6 +57,27 @@ public class ModifierSettingsGui extends Screen { addRenderableOnly(buttonClose); } + private void initScrollEntries() { + + var modifierSettingsList = EffortlessBuildingClient.BUILD_MODIFIERS.getModifierSettingsList(); + for (BaseModifier modifier : modifierSettingsList) { + BaseModifierPanel modifierPanel = createModifierPanel(modifier.getClass().getSimpleName()); + if (modifierPanel != null) { + modifierPanel.setModifier(modifier); + scrollPane.AddListEntry(modifierPanel); + } + } + } + + private BaseModifierPanel createModifierPanel(String type) { + switch (type) { + case "Mirror": return new MirrorPanel(scrollPane); + case "Array": return new ArrayPanel(scrollPane); + case "RadialMirror": return new RadialMirrorPanel(scrollPane); + default: return null; + } + } + @Override //Process general logic, i.e. hide buttons public void tick() { @@ -131,9 +152,9 @@ public class ModifierSettingsGui extends Screen { scrollPane.onGuiClosed(); //save everything - Mirror.MirrorSettings m = mirrorSettingsGui.getMirrorSettings(); - Array.ArraySettings a = arraySettingsGui.getArraySettings(); - RadialMirror.RadialMirrorSettings r = radialMirrorSettingsGui.getRadialMirrorSettings(); + Mirror.MirrorSettings m = mirrorPanel.getMirrorSettings(); + Array.ArraySettings a = arrayPanel.getArraySettings(); + RadialMirror.RadialMirrorSettings r = radialMirrorPanel.getRadialMirrorSettings(); ModifierSettingsManager.ModifierSettings modifierSettings = ModifierSettingsManager.getModifierSettings(minecraft.player); if (modifierSettings == null) modifierSettings = new ModifierSettingsManager.ModifierSettings(); diff --git a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorSettingsGui.java b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorPanel.java similarity index 98% rename from src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorSettingsGui.java rename to src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorPanel.java index 9ed3ca5..5c91411 100644 --- a/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorSettingsGui.java +++ b/src/main/java/nl/requios/effortlessbuilding/gui/buildmodifier/RadialMirrorPanel.java @@ -11,7 +11,6 @@ import net.minecraft.ChatFormatting; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import nl.requios.effortlessbuilding.gui.elements.*; import nl.requios.effortlessbuilding.utilities.ReachHelper; @@ -22,7 +21,7 @@ import java.util.List; @SuppressWarnings("Duplicates") @OnlyIn(Dist.CLIENT) -public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { +public class RadialMirrorPanel extends BaseModifierPanel { protected static final ResourceLocation BUILDING_ICONS = new ResourceLocation(EffortlessBuilding.MODID, "textures/gui/building_icons.png"); @@ -35,7 +34,7 @@ public class RadialMirrorSettingsGui extends GuiCollapsibleScrollEntry { private GuiIconButton buttonCurrentPosition, buttonToggleOdd, buttonDrawPlanes, buttonDrawLines; private boolean drawPlanes, drawLines, toggleOdd; - public RadialMirrorSettingsGui(GuiScrollPane scrollPane) { + public RadialMirrorPanel(GuiScrollPane scrollPane) { super(scrollPane); } diff --git a/src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java b/src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java index 434c5f2..5f2c6a9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/AbstractRandomizerBagItem.java @@ -24,7 +24,6 @@ import net.minecraftforge.network.NetworkHooks; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; import nl.requios.effortlessbuilding.systems.ServerBuildState; -import nl.requios.effortlessbuilding.capability.ItemHandlerCapabilityProvider; import nl.requios.effortlessbuilding.utilities.SurvivalHelper; import javax.annotation.Nullable; diff --git a/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java b/src/main/java/nl/requios/effortlessbuilding/item/ItemHandlerCapabilityProvider.java similarity index 95% rename from src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java rename to src/main/java/nl/requios/effortlessbuilding/item/ItemHandlerCapabilityProvider.java index 9c44516..6d99aa9 100644 --- a/src/main/java/nl/requios/effortlessbuilding/capability/ItemHandlerCapabilityProvider.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ItemHandlerCapabilityProvider.java @@ -1,4 +1,4 @@ -package nl.requios.effortlessbuilding.capability; +package nl.requios.effortlessbuilding.item; import net.minecraft.nbt.CompoundTag; import net.minecraft.core.Direction; diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java index 4b1868e..515cde0 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade1Item.java @@ -11,7 +11,6 @@ import net.minecraft.ChatFormatting; import net.minecraft.world.level.Level; import nl.requios.effortlessbuilding.CommonConfig; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.utilities.ReachHelper; import javax.annotation.Nullable; diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java index 8963487..4a6f03a 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade2Item.java @@ -11,7 +11,6 @@ import net.minecraft.ChatFormatting; import net.minecraft.world.level.Level; import nl.requios.effortlessbuilding.CommonConfig; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.utilities.ReachHelper; import javax.annotation.Nullable; diff --git a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java index dd03493..be10cb2 100644 --- a/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java +++ b/src/main/java/nl/requios/effortlessbuilding/item/ReachUpgrade3Item.java @@ -11,7 +11,6 @@ import net.minecraft.ChatFormatting; import net.minecraft.world.level.Level; import nl.requios.effortlessbuilding.CommonConfig; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.utilities.ReachHelper; import javax.annotation.Nullable; diff --git a/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsMessage.java b/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsMessage.java deleted file mode 100644 index 56ca0c1..0000000 --- a/src/main/java/nl/requios/effortlessbuilding/network/ModifierSettingsMessage.java +++ /dev/null @@ -1,132 +0,0 @@ -package nl.requios.effortlessbuilding.network; - -import net.minecraft.world.entity.player.Player; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.core.BlockPos; -import net.minecraft.world.phys.Vec3; -import net.minecraftforge.network.NetworkEvent; -import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmodifier.Array; -import nl.requios.effortlessbuilding.buildmodifier.Mirror; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; -import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; - -import java.util.function.Supplier; - -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager.ModifierSettings; - -/** - * Shares modifier settings (see ModifierSettingsManager) between server and client - */ -public class ModifierSettingsMessage { - - private ModifierSettings modifierSettings; - - public ModifierSettingsMessage() { - } - - public ModifierSettingsMessage(ModifierSettings modifierSettings) { - this.modifierSettings = modifierSettings; - } - - public static void encode(ModifierSettingsMessage message, FriendlyByteBuf buf) { - //MIRROR - Mirror.MirrorSettings m = message.modifierSettings.getMirrorSettings(); - buf.writeBoolean(m != null); - if (m != null) { - buf.writeBoolean(m.enabled); - buf.writeDouble(m.position.x); - buf.writeDouble(m.position.y); - buf.writeDouble(m.position.z); - buf.writeBoolean(m.mirrorX); - buf.writeBoolean(m.mirrorY); - buf.writeBoolean(m.mirrorZ); - buf.writeInt(m.radius); - buf.writeBoolean(m.drawLines); - buf.writeBoolean(m.drawPlanes); - } - - //ARRAY - Array.ArraySettings a = message.modifierSettings.getArraySettings(); - buf.writeBoolean(a != null); - if (a != null) { - buf.writeBoolean(a.enabled); - buf.writeInt(a.offset.getX()); - buf.writeInt(a.offset.getY()); - buf.writeInt(a.offset.getZ()); - buf.writeInt(a.count); - } - - //RADIAL MIRROR - RadialMirror.RadialMirrorSettings r = message.modifierSettings.getRadialMirrorSettings(); - buf.writeBoolean(r != null); - if (r != null) { - buf.writeBoolean(r.enabled); - buf.writeDouble(r.position.x); - buf.writeDouble(r.position.y); - buf.writeDouble(r.position.z); - buf.writeInt(r.slices); - buf.writeBoolean(r.alternate); - buf.writeInt(r.radius); - buf.writeBoolean(r.drawLines); - buf.writeBoolean(r.drawPlanes); - } - } - - public static ModifierSettingsMessage decode(FriendlyByteBuf buf) { - //MIRROR - Mirror.MirrorSettings m = new Mirror.MirrorSettings(); - if (buf.readBoolean()) { - boolean mirrorEnabled = buf.readBoolean(); - Vec3 mirrorPosition = new Vec3(buf.readDouble(), buf.readDouble(), buf.readDouble()); - boolean mirrorX = buf.readBoolean(); - boolean mirrorY = buf.readBoolean(); - boolean mirrorZ = buf.readBoolean(); - int mirrorRadius = buf.readInt(); - boolean mirrorDrawLines = buf.readBoolean(); - boolean mirrorDrawPlanes = buf.readBoolean(); - m = new Mirror.MirrorSettings(mirrorEnabled, mirrorPosition, mirrorX, mirrorY, mirrorZ, mirrorRadius, - mirrorDrawLines, mirrorDrawPlanes); - } - - //ARRAY - Array.ArraySettings a = new Array.ArraySettings(); - if (buf.readBoolean()) { - boolean arrayEnabled = buf.readBoolean(); - BlockPos arrayOffset = new BlockPos(buf.readInt(), buf.readInt(), buf.readInt()); - int arrayCount = buf.readInt(); - a = new Array.ArraySettings(arrayEnabled, arrayOffset, arrayCount); - } - - //RADIAL MIRROR - RadialMirror.RadialMirrorSettings r = new RadialMirror.RadialMirrorSettings(); - if (buf.readBoolean()) { - boolean radialMirrorEnabled = buf.readBoolean(); - Vec3 radialMirrorPosition = new Vec3(buf.readDouble(), buf.readDouble(), buf.readDouble()); - int radialMirrorSlices = buf.readInt(); - boolean radialMirrorAlternate = buf.readBoolean(); - int radialMirrorRadius = buf.readInt(); - boolean radialMirrorDrawLines = buf.readBoolean(); - boolean radialMirrorDrawPlanes = buf.readBoolean(); - r = new RadialMirror.RadialMirrorSettings(radialMirrorEnabled, radialMirrorPosition, radialMirrorSlices, - radialMirrorAlternate, radialMirrorRadius, radialMirrorDrawLines, radialMirrorDrawPlanes); - } - - ModifierSettings modifierSettings = new ModifierSettings(m, a, r); - return new ModifierSettingsMessage(modifierSettings); - } - - public static class Handler { - public static void handle(ModifierSettingsMessage message, Supplier ctx) { - ctx.get().enqueueWork(() -> { - Player player = EffortlessBuilding.proxy.getPlayerEntityFromContext(ctx); - - // Sanitize - ModifierSettingsManager.sanitize(message.modifierSettings, player); - - ModifierSettingsManager.setModifierSettings(player, message.modifierSettings); - }); - ctx.get().setPacketHandled(true); - } - } -} diff --git a/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java b/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java index d4813ee..0e0fcee 100644 --- a/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/network/PacketHandler.java @@ -24,8 +24,6 @@ public class PacketHandler { IsUsingBuildModePacket.Handler::handle, Optional.of(NetworkDirection.PLAY_TO_SERVER)); INSTANCE.registerMessage(id++, IsQuickReplacingPacket.class, IsQuickReplacingPacket::encode, IsQuickReplacingPacket::decode, IsQuickReplacingPacket.Handler::handle, Optional.of(NetworkDirection.PLAY_TO_SERVER)); - INSTANCE.registerMessage(id++, ModifierSettingsMessage.class, ModifierSettingsMessage::encode, ModifierSettingsMessage::decode, - ModifierSettingsMessage.Handler::handle); INSTANCE.registerMessage(id++, ServerPlaceBlocksPacket.class, ServerPlaceBlocksPacket::encode, ServerPlaceBlocksPacket::decode, ServerPlaceBlocksPacket.Handler::handle, Optional.of(NetworkDirection.PLAY_TO_SERVER)); INSTANCE.registerMessage(id++, ServerBreakBlocksPacket.class, ServerBreakBlocksPacket::encode, ServerBreakBlocksPacket::decode, diff --git a/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java b/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java index 18fbddd..e1ac55a 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/ModifierRenderer.java @@ -8,7 +8,6 @@ import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.buildmodifier.Mirror; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.buildmodifier.RadialMirror; import java.awt.*; diff --git a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java index a5d9ac2..ee103aa 100644 --- a/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java +++ b/src/main/java/nl/requios/effortlessbuilding/render/RenderHandler.java @@ -17,7 +17,6 @@ import net.minecraftforge.client.event.RenderLevelStageEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; import nl.requios.effortlessbuilding.EffortlessBuildingClient; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.systems.BuilderChain; /*** diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java index a2c216e..74fe242 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderChain.java @@ -18,9 +18,9 @@ import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import nl.requios.effortlessbuilding.ClientEvents; +import nl.requios.effortlessbuilding.CommonConfig; import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.buildmode.BuildModeEnum; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem; import nl.requios.effortlessbuilding.network.PacketHandler; @@ -42,6 +42,8 @@ public class BuilderChain { private BlockEntry startPosForPlacing; private BlockPos startPosForBreaking; private BlockHitResult lookingAtNear; + //Can be near or far depending on abilities + private BlockHitResult lookingAt; public enum BuildingState { IDLE, @@ -82,6 +84,10 @@ public class BuilderChain { EffortlessBuildingClient.BLOCK_PREVIEWS.onBlocksPlaced(blocks); BlockUtilities.playSoundIfFurtherThanNormal(player, blocks.getLastBlockEntry(), false); player.swing(InteractionHand.MAIN_HAND); + + //TODO place blocks delayed on server, calculate what tick they should be placed on + int delay = CommonConfig.visuals.appearAnimationLength.get() * 3 - 3; //DelayedBlockPlacer is 3 times faster than client tick? + PacketHandler.INSTANCE.sendToServer(new ServerPlaceBlocksPacket(blocks)); } } @@ -127,6 +133,7 @@ public class BuilderChain { startPosForPlacing = null; startPosForBreaking = null; lookingAtNear = null; + lookingAt = null; var mc = Minecraft.getInstance(); var player = mc.player; @@ -136,7 +143,6 @@ public class BuilderChain { if (abilitiesState == AbilitiesState.NONE) return; var buildMode = EffortlessBuildingClient.BUILD_MODES.getBuildMode(); - var modifierSettings = ModifierSettingsManager.getModifierSettings(player); if (buildingState == BuildingState.IDLE) { //Find start position @@ -150,8 +156,8 @@ public class BuilderChain { } } - EffortlessBuildingClient.BUILD_MODES.findCoordinates(blocks, player, buildMode); - EffortlessBuildingClient.BUILD_MODIFIERS.findCoordinates(blocks, player, modifierSettings); + EffortlessBuildingClient.BUILD_MODES.findCoordinates(blocks, player); + EffortlessBuildingClient.BUILD_MODIFIERS.findCoordinates(blocks, player); BuilderFilter.filterOnCoordinates(blocks, player); if (buildMode == BuildModeEnum.DISABLED && blocks.size() <= 1) { @@ -196,40 +202,14 @@ public class BuilderChain { return AbilitiesState.CAN_PLACE_AND_BREAK; } - private void onBlocksChanged(Player player) { - - //Renew randomness of randomizer bag - AbstractRandomizerBagItem.renewRandomness(); - - //Play sound (max once every tick) - if (blocks.size() > 1 && soundTime < ClientEvents.ticksInGame) { - soundTime = ClientEvents.ticksInGame; - - if (blocks.getLastBlockEntry() != null && blocks.getLastBlockEntry().newBlockState != null) { - var lastBlockState = blocks.getLastBlockEntry().newBlockState; - SoundType soundType = lastBlockState.getBlock().getSoundType(lastBlockState, player.level, blocks.lastPos, player); - SoundEvent soundEvent = buildingState == BuildingState.BREAKING ? soundType.getBreakSound() : soundType.getPlaceSound(); - player.level.playSound(player, player.blockPosition(), soundEvent, SoundSource.BLOCKS, 0.3f, 0.8f); - } - } - } - - public void cancel() { - if (buildingState == BuildingState.IDLE) return; - buildingState = BuildingState.IDLE; - EffortlessBuildingClient.BUILD_MODES.onCancel(); - Minecraft.getInstance().player.playSound(SoundEvents.UI_TOAST_OUT, 4, 1); - } - private BlockEntry findStartPosition(Player player, BuildModeEnum buildMode) { //Determine if we should look far or nearby boolean shouldLookAtNear = buildMode == BuildModeEnum.DISABLED; - BlockHitResult lookingAt; if (shouldLookAtNear) { lookingAt = lookingAtNear; } else { - lookingAt = ClientEvents.getLookingAtFar(player); + lookingAt = BlockUtilities.getLookingAtFar(player); } if (lookingAt == null || lookingAt.getType() == HitResult.Type.MISS) return null; @@ -291,10 +271,14 @@ public class BuilderChain { private void findNewBlockStates(Player player, ItemStack itemStack) { if (buildingState == BuildingState.BREAKING) return; + var originalDirection = player.getDirection(); + var clickedFace = lookingAt.getDirection(); + Vec3 relativeHitVec = lookingAt.getLocation().subtract(Vec3.atLowerCornerOf(lookingAt.getBlockPos())); + if (itemStack.getItem() instanceof BlockItem) { for (BlockEntry blockEntry : blocks) { - blockEntry.newBlockState = BlockUtilities.getBlockState(player, InteractionHand.MAIN_HAND, itemStack, blockEntry); + blockEntry.setItemStackAndFindNewBlockState(itemStack, player.level, originalDirection, clickedFace, relativeHitVec); } } else if (CompatHelper.isItemBlockProxy(itemStack, false)) { @@ -303,11 +287,36 @@ public class BuilderChain { for (BlockEntry blockEntry : blocks) { ItemStack itemBlockStack = CompatHelper.getItemBlockFromStack(itemStack); if (itemBlockStack == null || itemBlockStack.isEmpty()) continue; - blockEntry.newBlockState = BlockUtilities.getBlockState(player, InteractionHand.MAIN_HAND, itemBlockStack, blockEntry); + blockEntry.setItemStackAndFindNewBlockState(itemBlockStack, player.level, originalDirection, clickedFace, relativeHitVec); } } } + private void onBlocksChanged(Player player) { + + //Renew randomness of randomizer bag + AbstractRandomizerBagItem.renewRandomness(); + + //Play sound (max once every tick) + if (blocks.size() > 1 && soundTime < ClientEvents.ticksInGame) { + soundTime = ClientEvents.ticksInGame; + + if (blocks.getLastBlockEntry() != null && blocks.getLastBlockEntry().newBlockState != null) { + var lastBlockState = blocks.getLastBlockEntry().newBlockState; + SoundType soundType = lastBlockState.getBlock().getSoundType(lastBlockState, player.level, blocks.lastPos, player); + SoundEvent soundEvent = buildingState == BuildingState.BREAKING ? soundType.getBreakSound() : soundType.getPlaceSound(); + player.level.playSound(player, player.blockPosition(), soundEvent, SoundSource.BLOCKS, 0.3f, 0.8f); + } + } + } + + public void cancel() { + if (buildingState == BuildingState.IDLE) return; + buildingState = BuildingState.IDLE; + EffortlessBuildingClient.BUILD_MODES.onCancel(); + Minecraft.getInstance().player.playSound(SoundEvents.UI_TOAST_OUT, 4, 1); + } + public BlockSet getBlocks() { return blocks; } diff --git a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderFilter.java b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderFilter.java index bcb65ac..3b3ad27 100644 --- a/src/main/java/nl/requios/effortlessbuilding/systems/BuilderFilter.java +++ b/src/main/java/nl/requios/effortlessbuilding/systems/BuilderFilter.java @@ -1,5 +1,6 @@ package nl.requios.effortlessbuilding.systems; +import net.minecraft.core.BlockPos; import net.minecraft.world.entity.player.Player; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -7,6 +8,7 @@ import nl.requios.effortlessbuilding.EffortlessBuildingClient; import nl.requios.effortlessbuilding.compatibility.CompatHelper; import nl.requios.effortlessbuilding.utilities.BlockSet; import nl.requios.effortlessbuilding.utilities.PlaceChecker; +import nl.requios.effortlessbuilding.utilities.SurvivalHelper; @OnlyIn(Dist.CLIENT) public class BuilderFilter { @@ -41,6 +43,21 @@ public class BuilderFilter { if (remove) iter.remove(); } + + + //If the player is going to instabreak grass or a plant, only break other instabreaking things +// boolean onlyInstaBreaking = !player.isCreative() && +// world.getBlockState(startCoordinates.get(0)).getDestroySpeed(world, startCoordinates.get(0)) == 0f; +// +// //break all those blocks +// for (int i = breakStartPos ? 0 : 1; i < coordinates.size(); i++) { +// BlockPos coordinate = coordinates.get(i); +// if (world.isLoaded(coordinate) && !world.isEmptyBlock(coordinate)) { +// if (!onlyInstaBreaking || world.getBlockState(coordinate).getDestroySpeed(world, coordinate) == 0f) { +// SurvivalHelper.breakBlock(world, player, coordinate, false); +// } +// } +// } } public static void filterOnNewBlockStates(BlockSet blocks, Player player) { diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockEntry.java b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockEntry.java index 28b7649..62094ff 100644 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockEntry.java +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockEntry.java @@ -1,19 +1,23 @@ package nl.requios.effortlessbuilding.utilities; import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; import net.minecraft.nbt.NbtUtils; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; -import java.util.BitSet; - +//Common public class BlockEntry { public final BlockPos blockPos; public boolean mirrorX; public boolean mirrorY; public boolean mirrorZ; + //Horizontal rotation public Rotation rotation; //BlockState that is currently in the world public BlockState existingBlockState; @@ -24,22 +28,29 @@ public class BlockEntry { this.blockPos = blockPos; } - public boolean meansBreakBlock() { - return newBlockState == null || newBlockState.isAir(); + public void copyRotationSettingsFrom(BlockEntry blockEntry) { + mirrorX = blockEntry.mirrorX; + mirrorY = blockEntry.mirrorY; + mirrorZ = blockEntry.mirrorZ; + rotation = blockEntry.rotation; } - public BitSet getMirrorBitSet() { - BitSet bitSet = new BitSet(3); - bitSet.set(0, mirrorX); - bitSet.set(1, mirrorY); - bitSet.set(2, mirrorZ); - return bitSet; + public void setItemStackAndFindNewBlockState(ItemStack itemStack, Level world, Direction originalDirection, Direction clickedFace, Vec3 relativeHitVec) { + this.itemStack = itemStack; + + Block block = Block.byItem(itemStack.getItem()); + var direction = rotation.rotate(originalDirection); + direction = applyMirror(direction); + //TODO mirror and rotate relativeHitVec? + var blockPlaceContext = new MyPlaceContext(world, blockPos, direction, itemStack, clickedFace, relativeHitVec); + newBlockState = block.getStateForPlacement(blockPlaceContext); } - public void setMirrorBitSet(BitSet bitSet) { - mirrorX = bitSet.get(0); - mirrorY = bitSet.get(1); - mirrorZ = bitSet.get(2); + private Direction applyMirror(Direction direction) { + if (mirrorX && direction.getAxis() == Direction.Axis.Z) direction = direction.getOpposite(); + if (mirrorY && direction.getAxis() == Direction.Axis.Y) direction = direction.getOpposite(); + if (mirrorZ && direction.getAxis() == Direction.Axis.X) direction = direction.getOpposite(); + return direction; } public static void encode(FriendlyByteBuf buf, BlockEntry block) { diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockUtilities.java b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockUtilities.java index 7197f45..598a4fd 100644 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/BlockUtilities.java +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/BlockUtilities.java @@ -8,10 +8,12 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.*; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.Half; +import net.minecraft.world.level.block.state.properties.SlabType; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; @@ -19,10 +21,11 @@ import net.minecraft.world.phys.Vec3; //Common public class BlockUtilities { - public static BlockState getBlockState(Player player, InteractionHand hand, ItemStack blockItemStack, BlockEntry blockEntry) { + @Deprecated //Use BlockEntry.setItemStackAndFindNewBlockState instead + public static BlockState getBlockState(Player player, InteractionHand hand, ItemStack blockItemStack, BlockEntry blockEntry, Vec3 relativeHitVec, Direction sideHit) { Block block = Block.byItem(blockItemStack.getItem()); - //TODO convert lookingAt hitvec to relative hitvec - var blockHitResult = new BlockHitResult(Vec3.ZERO, Direction.UP, blockEntry.blockPos, false); + Vec3 hitVec = relativeHitVec.add(Vec3.atLowerCornerOf(blockEntry.blockPos)); + var blockHitResult = new BlockHitResult(hitVec, sideHit, blockEntry.blockPos, false); return block.getStateForPlacement(new BlockPlaceContext(player, hand, blockItemStack, blockHitResult)); } @@ -56,4 +59,59 @@ public class BlockUtilities { SoundEvent soundEvent = breaking ? soundType.getBreakSound() : soundType.getPlaceSound(); player.level.playSound(player, player.blockPosition(), soundEvent, SoundSource.BLOCKS, 0.6f, soundType.getPitch()); } + + public static BlockState getVerticalMirror(BlockState blockState) { + //Stairs + if (blockState.getBlock() instanceof StairBlock) { + if (blockState.getValue(StairBlock.HALF) == Half.BOTTOM) { + return blockState.setValue(StairBlock.HALF, Half.TOP); + } else { + return blockState.setValue(StairBlock.HALF, Half.BOTTOM); + } + } + + //Slabs + if (blockState.getBlock() instanceof SlabBlock) { + if (blockState.getValue(SlabBlock.TYPE) == SlabType.DOUBLE) { + return blockState; + } else if (blockState.getValue(SlabBlock.TYPE) == SlabType.BOTTOM) { + return blockState.setValue(SlabBlock.TYPE, SlabType.TOP); + } else { + return blockState.setValue(SlabBlock.TYPE, SlabType.BOTTOM); + } + } + + //Buttons, endrod, observer, piston + if (blockState.getBlock() instanceof DirectionalBlock) { + if (blockState.getValue(DirectionalBlock.FACING) == Direction.DOWN) { + return blockState.setValue(DirectionalBlock.FACING, Direction.UP); + } else if (blockState.getValue(DirectionalBlock.FACING) == Direction.UP) { + return blockState.setValue(DirectionalBlock.FACING, Direction.DOWN); + } + } + + //Dispenser, dropper + if (blockState.getBlock() instanceof DispenserBlock) { + if (blockState.getValue(DispenserBlock.FACING) == Direction.DOWN) { + return blockState.setValue(DispenserBlock.FACING, Direction.UP); + } else if (blockState.getValue(DispenserBlock.FACING) == Direction.UP) { + return blockState.setValue(DispenserBlock.FACING, Direction.DOWN); + } + } + + return blockState; + } + + public static BlockHitResult getLookingAtFar(Player player) { + Level world = player.level; + + //base distance off of player ability (config) + float raytraceRange = ReachHelper.getPlacementReach(player); + + Vec3 look = player.getLookAngle(); + Vec3 start = new Vec3(player.getX(), player.getY() + player.getEyeHeight(), player.getZ()); + Vec3 end = new Vec3(player.getX() + look.x * raytraceRange, player.getY() + player.getEyeHeight() + look.y * raytraceRange, player.getZ() + look.z * raytraceRange); + + return world.clip(new ClipContext(start, end, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, player)); + } } diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/MyPlaceContext.java b/src/main/java/nl/requios/effortlessbuilding/utilities/MyPlaceContext.java new file mode 100644 index 0000000..dd3156a --- /dev/null +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/MyPlaceContext.java @@ -0,0 +1,68 @@ +package nl.requios.effortlessbuilding.utilities; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; + +// Version of DirectionalPlaceContext with hitVec +public class MyPlaceContext extends BlockPlaceContext { + private final Direction direction; + + public MyPlaceContext(Level level, BlockPos blockPos, Direction direction, ItemStack itemStack, Direction clickedFace, Vec3 relativeHitVec) { + + super(level, null, InteractionHand.MAIN_HAND, itemStack, new BlockHitResult( + Vec3.atLowerCornerOf(blockPos).add(relativeHitVec), clickedFace, blockPos, false)); + this.direction = direction; + } + + public BlockPos getClickedPos() { + return this.getHitResult().getBlockPos(); + } + + public boolean canPlace() { + return this.getLevel().getBlockState(this.getHitResult().getBlockPos()).canBeReplaced(this); + } + + public boolean replacingClickedOnBlock() { + return this.canPlace(); + } + + public Direction getNearestLookingDirection() { + return Direction.DOWN; + } + + public Direction[] getNearestLookingDirections() { + switch (this.direction) { + case DOWN: + default: + return new Direction[]{Direction.DOWN, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP}; + case UP: + return new Direction[]{Direction.DOWN, Direction.UP, Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST}; + case NORTH: + return new Direction[]{Direction.DOWN, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.UP, Direction.SOUTH}; + case SOUTH: + return new Direction[]{Direction.DOWN, Direction.SOUTH, Direction.EAST, Direction.WEST, Direction.UP, Direction.NORTH}; + case WEST: + return new Direction[]{Direction.DOWN, Direction.WEST, Direction.SOUTH, Direction.UP, Direction.NORTH, Direction.EAST}; + case EAST: + return new Direction[]{Direction.DOWN, Direction.EAST, Direction.SOUTH, Direction.UP, Direction.NORTH, Direction.WEST}; + } + } + + public Direction getHorizontalDirection() { + return this.direction.getAxis() == Direction.Axis.Y ? Direction.NORTH : this.direction; + } + + public boolean isSecondaryUseActive() { + return false; + } + + public float getRotation() { + return (float)(this.direction.get2DDataValue() * 90); + } +} diff --git a/src/main/java/nl/requios/effortlessbuilding/utilities/ReachHelper.java b/src/main/java/nl/requios/effortlessbuilding/utilities/ReachHelper.java index fbf2e6e..693df42 100644 --- a/src/main/java/nl/requios/effortlessbuilding/utilities/ReachHelper.java +++ b/src/main/java/nl/requios/effortlessbuilding/utilities/ReachHelper.java @@ -4,7 +4,6 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.util.Mth; import nl.requios.effortlessbuilding.CommonConfig; import nl.requios.effortlessbuilding.EffortlessBuilding; -import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager; //Common public class ReachHelper {