Overhauled modifiers to run clientside only. BuilderChain applies rotation and mirror to blockstates.

Removed ModifierSettingsManager, ModifierSettingsMessage and capabilities.
This commit is contained in:
Christian Knaapen
2023-01-26 02:09:50 +01:00
parent a760565b66
commit ed2609f97e
31 changed files with 659 additions and 1199 deletions

View File

@@ -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);
}

View File

@@ -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<Entity> 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?
}
}

View File

@@ -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);
}

View File

@@ -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,84 +13,32 @@ 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<BlockPos> findCoordinates(Player player, BlockPos startPos) {
List<BlockPos> coordinates = new ArrayList<>();
//find arraysettings for the player
ArraySettings a = ModifierSettingsManager.getModifierSettings(player).getArraySettings();
if (!isEnabled(a)) return coordinates;
BlockPos pos = startPos;
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
for (int i = 0; i < a.count; i++) {
pos = pos.offset(offset);
coordinates.add(pos);
}
return coordinates;
}
public static List<BlockState> findBlockStates(Player player, BlockPos startPos, BlockState blockState, ItemStack itemStack, List<ItemStack> itemStacks) {
List<BlockState> 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);
}
//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() {
}
@Override
public void findCoordinates(BlockSet blocks, Player player) {
if (!enabled || offset.getX() == 0 && offset.getY() == 0 && offset.getZ() == 0) return;
public ArraySettings(boolean enabled, BlockPos offset, int count) {
this.enabled = enabled;
this.offset = offset;
this.count = count;
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;
var newBlockEntry = new BlockEntry(pos);
newBlockEntry.copyRotationSettingsFrom(blockEntry);
}
}
}
public int getReach() {
@@ -99,6 +50,19 @@ public class Array {
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");
}
}

View File

@@ -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");
}
}

View File

@@ -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<BaseModifier> modifierSettingsList = new ArrayList<>();
public void findCoordinates(BlockSet blocks, LocalPlayer player, ModifierSettingsManager.ModifierSettings modifierSettings) {
public List<BaseModifier> getModifierSettingsList() {
return Collections.unmodifiableList(modifierSettingsList);
}
//Called from BuildModes
public static void onBlockPlaced(Player player, List<BlockPos> 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<BlockPos> coordinates = findCoordinates(player, startCoordinates);
List<ItemStack> itemStacks = new ArrayList<>();
List<BlockState> 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<BlockPos> startCoordinates, boolean breakStartPos) {
Level world = player.level;
private static final String DATA_KEY = EffortlessBuilding.MODID + ":buildModifiers";
List<BlockPos> coordinates = findCoordinates(player, startCoordinates);
if (coordinates.isEmpty()) return;
//remember previous blockstates for undo
List<BlockState> previousBlockStates = new ArrayList<>(coordinates.size());
List<BlockState> newBlockStates = new ArrayList<>(coordinates.size());
for (BlockPos coordinate : coordinates) {
previousBlockStates.add(world.getBlockState(coordinate));
public void save(Player player) {
var listTag = NBTHelper.writeCompoundList(modifierSettingsList, BaseModifier::serializeNBT);
player.getPersistentData().put(DATA_KEY, listTag);
}
if (world.isClientSide) {
// BlockPreviews.onBlocksBroken(blocks);
//list of air blockstates
for (int i = 0; i < coordinates.size(); i++) {
newBlockStates.add(Blocks.AIR.defaultBlockState());
//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;
});
}
} 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));
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);
}
}
//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));
}
public static List<BlockPos> findCoordinates(Player player, List<BlockPos> posList) {
List<BlockPos> 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<BlockPos> 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;
}
public static List<BlockPos> findCoordinates(Player player, BlockPos blockPos) {
return findCoordinates(player, new ArrayList<>(Collections.singletonList(blockPos)));
}
public static List<BlockState> findBlockStates(Player player, List<BlockPos> posList, Vec3 hitVec, Direction facing, List<ItemStack> itemStacks) {
List<BlockState> 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<BlockState> 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<BlockPos> 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<BlockPos> 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));
// 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;
// }
}
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<BlockPos> coordinates1, List<BlockPos> 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);
}
}

View File

@@ -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 {
public static List<BlockPos> findCoordinates(Player player, BlockPos startPos) {
List<BlockPos> 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;
}
private static void coordinateMirrorX(MirrorSettings m, BlockPos oldBlockPos, List<BlockPos> coordinates) {
//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);
if (m.mirrorY) coordinateMirrorY(m, newBlockPos, coordinates);
if (m.mirrorZ) coordinateMirrorZ(m, newBlockPos, coordinates);
}
private static void coordinateMirrorY(MirrorSettings m, BlockPos oldBlockPos, List<BlockPos> coordinates) {
//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);
if (m.mirrorZ) coordinateMirrorZ(m, newBlockPos, coordinates);
}
private static void coordinateMirrorZ(MirrorSettings m, BlockPos oldBlockPos, List<BlockPos> coordinates) {
//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);
}
public static List<BlockState> findBlockStates(Player player, BlockPos startPos, BlockState blockState, ItemStack itemStack, List<ItemStack> itemStacks) {
List<BlockState> 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;
}
private static void blockStateMirrorX(Player player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState,
IItemHandler bagInventory, ItemStack itemStack, InteractionHand hand, List<BlockState> blockStates, List<ItemStack> 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);
}
private static void blockStateMirrorY(Player player, MirrorSettings m, BlockPos oldBlockPos, BlockState oldBlockState,
IItemHandler bagInventory, ItemStack itemStack, InteractionHand hand, List<BlockState> blockStates, List<ItemStack> 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<BlockState> blockStates, List<ItemStack> 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 class Mirror extends BaseModifier {
public Vec3 position = new Vec3(0.5, 64.5, 0.5);
public boolean mirrorX = true, mirrorY = false, mirrorZ = false;
public boolean mirrorX = true;
public boolean mirrorY = false;
public boolean mirrorZ = false;
public int radius = 10;
public boolean drawLines = true, drawPlanes = true;
public boolean drawLines = true;
public boolean drawPlanes = true;
public MirrorSettings() {
@Override
public void findCoordinates(BlockSet blocks, Player player) {
if (!(enabled && (mirrorX || mirrorY || mirrorZ))) return;
var originalBlocks = new BlockSet(blocks);
for (BlockEntry blockEntry : originalBlocks) {
if (!isWithinRange(blockEntry.blockPos)) continue;
if (mirrorX) performMirrorX(blocks, blockEntry);
if (mirrorY) performMirrorY(blocks, blockEntry);
if (mirrorZ) performMirrorZ(blocks, blockEntry);
}
}
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;
private void performMirrorX(BlockSet blocks, BlockEntry blockEntry) {
//find mirror position
double x = position.x + (position.x - blockEntry.blockPos.getX() - 0.5);
BlockPos newBlockPos = new BlockPos(x, blockEntry.blockPos.getY(), blockEntry.blockPos.getZ());
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 void performMirrorY(BlockSet blocks, BlockEntry blockEntry) {
//find mirror position
double y = position.y + (position.y - blockEntry.blockPos.getY() - 0.5);
BlockPos newBlockPos = new BlockPos(blockEntry.blockPos.getX(), y, blockEntry.blockPos.getZ());
if (blocks.containsKey(newBlockPos)) return;
var newBlockEntry = new BlockEntry(newBlockPos);
newBlockEntry.copyRotationSettingsFrom(blockEntry);
newBlockEntry.mirrorY = !newBlockEntry.mirrorY;
if (mirrorZ) performMirrorZ(blocks, newBlockEntry);
}
private void performMirrorZ(BlockSet blocks, BlockEntry blockEntry) {
//find mirror position
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 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
}
@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;
}
@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");
}
}

View File

@@ -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<ModifierCapabilityManager.IModifierCapability> 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<ModifierCapabilityManager.IModifierCapability> 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;
}
}
}

View File

@@ -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<BlockPos> findCoordinates(Player player, BlockPos startPos) {
List<BlockPos> 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));
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);
}
}
return coordinates;
private void rotateBlockEntry(BlockEntry blockEntry, double angleToCenter, boolean alternate) {
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;
}
public static List<BlockState> findBlockStates(Player player, BlockPos startPos, BlockState blockState, ItemStack itemStack, List<ItemStack> itemStacks) {
List<BlockState> blockStates = new ArrayList<>();
List<BlockPos> coordinates = new ArrayList<>(); //to keep track of duplicates
//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);
} else if (angleToCenter < -0.251 * Math.PI) {
blockEntry.rotation = blockEntry.rotation.getRotated(Rotation.CLOCKWISE_90);
if (alternate) {
blockEntry.mirrorX = !blockEntry.mirrorX;
}
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);
} else if (angleToCenter > 0.249 * Math.PI) {
blockEntry.rotation = blockEntry.rotation.getRotated(Rotation.COUNTERCLOCKWISE_90);
if (alternate) {
blockEntry.mirrorX = !blockEntry.mirrorX;
}
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 (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 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 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 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");
}
}

View File

@@ -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<IModifierCapability> MODIFIER_CAPABILITY = CapabilityManager.get(new CapabilityToken<>(){});
// Allows for the capability to persist after death.
@SubscribeEvent
public static void clonePlayer(PlayerEvent.Clone event) {
LazyOptional<IModifierCapability> original = event.getOriginal().getCapability(MODIFIER_CAPABILITY, null);
LazyOptional<IModifierCapability> 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<Provider> implements INBTSerializable<Tag> {
private final IModifierCapability instance = new ModifierCapability();
private LazyOptional<IModifierCapability> modifierCapabilityOptional = LazyOptional.of(() -> instance);
public Provider() {
super(Provider.class);
gatherCapabilities();
}
@Nonnull
@Override
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> 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);
}
}
}

View File

@@ -127,10 +127,10 @@ public abstract class AbstractSimiContainerScreen<T extends AbstractContainerMen
return leftPos - windowXOffset + (imageWidth - textureWidth) / 2;
}
public void renderPlayerInventory(PoseStack ms, int x, int y) {
AllGuiTextures.PLAYER_INVENTORY.render(ms, x, y, this);
font.draw(ms, playerInventoryTitle, x + 8, y + 6, 0x404040);
}
// public void renderPlayerInventory(PoseStack ms, int x, int y) {
// AllGuiTextures.PLAYER_INVENTORY.render(ms, x, y, this);
// font.draw(ms, playerInventoryTitle, x + 8, y + 6, 0x404040);
// }
@Override
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {

View File

@@ -10,9 +10,7 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import nl.requios.effortlessbuilding.EffortlessBuilding;
import nl.requios.effortlessbuilding.buildmodifier.Array;
import nl.requios.effortlessbuilding.buildmodifier.ModifierSettingsManager;
import nl.requios.effortlessbuilding.gui.elements.GuiCheckBoxFixed;
import nl.requios.effortlessbuilding.gui.elements.GuiCollapsibleScrollEntry;
import nl.requios.effortlessbuilding.gui.elements.GuiNumberField;
import nl.requios.effortlessbuilding.gui.elements.GuiScrollPane;
import nl.requios.effortlessbuilding.utilities.ReachHelper;
@@ -21,14 +19,14 @@ import java.util.ArrayList;
import java.util.List;
@OnlyIn(Dist.CLIENT)
public class ArraySettingsGui extends GuiCollapsibleScrollEntry {
public class ArrayPanel extends BaseModifierPanel {
protected List<GuiNumberField> arrayNumberFieldList = new ArrayList<>();
private GuiCheckBoxFixed buttonArrayEnabled;
private GuiNumberField textArrayOffsetX, textArrayOffsetY, textArrayOffsetZ, textArrayCount;
public ArraySettingsGui(GuiScrollPane scrollPane) {
public ArrayPanel(GuiScrollPane scrollPane) {
super(scrollPane);
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -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<Class, Class> modifierPanelMap = new HashMap<Class, Class>() {{
put(Mirror.class, MirrorPanel.class);
put(Array.class, ArrayPanel.class);
put(RadialMirror.class, RadialMirrorPanel.class);
}};
private GuiScrollPane scrollPane;
private List<BaseModifierPanel> 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();

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -1,4 +1,4 @@
package nl.requios.effortlessbuilding.capability;
package nl.requios.effortlessbuilding.item;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.core.Direction;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<NetworkEvent.Context> 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);
}
}
}

View File

@@ -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,

View File

@@ -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.*;

View File

@@ -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;
/***

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -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) {

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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 {