Overhauled modifiers to run clientside only. BuilderChain applies rotation and mirror to blockstates.
Removed ModifierSettingsManager, ModifierSettingsMessage and capabilities.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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?
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package nl.requios.effortlessbuilding.buildmodifier;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
@@ -10,95 +13,56 @@ import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
|
||||
import nl.requios.effortlessbuilding.utilities.BlockEntry;
|
||||
import nl.requios.effortlessbuilding.utilities.BlockSet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Array {
|
||||
public class Array extends BaseModifier {
|
||||
|
||||
public static List<BlockPos> findCoordinates(Player player, BlockPos startPos) {
|
||||
List<BlockPos> coordinates = new ArrayList<>();
|
||||
public BlockPos offset = BlockPos.ZERO;
|
||||
public int count = 5;
|
||||
|
||||
//find arraysettings for the player
|
||||
ArraySettings a = ModifierSettingsManager.getModifierSettings(player).getArraySettings();
|
||||
if (!isEnabled(a)) return coordinates;
|
||||
@Override
|
||||
public void findCoordinates(BlockSet blocks, Player player) {
|
||||
if (!enabled || offset.getX() == 0 && offset.getY() == 0 && offset.getZ() == 0) return;
|
||||
|
||||
BlockPos pos = startPos;
|
||||
Vec3i offset = new Vec3i(a.offset.getX(), a.offset.getY(), a.offset.getZ());
|
||||
var originalBlocks = new BlockSet(blocks);
|
||||
for (BlockEntry blockEntry : originalBlocks) {
|
||||
var pos = blockEntry.blockPos;
|
||||
for (int i = 0; i < count; i++) {
|
||||
pos = pos.offset(offset);
|
||||
if (blocks.containsKey(pos)) continue;
|
||||
|
||||
for (int i = 0; i < a.count; i++) {
|
||||
pos = pos.offset(offset);
|
||||
coordinates.add(pos);
|
||||
}
|
||||
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
public static List<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);
|
||||
var newBlockEntry = new BlockEntry(pos);
|
||||
newBlockEntry.copyRotationSettingsFrom(blockEntry);
|
||||
}
|
||||
|
||||
//blockState = blockState.getBlock().getStateForPlacement(player.world, pos, )
|
||||
blockStates.add(blockState);
|
||||
itemStacks.add(itemStack);
|
||||
}
|
||||
|
||||
return blockStates;
|
||||
}
|
||||
|
||||
public static boolean isEnabled(ArraySettings a) {
|
||||
if (a == null || !a.enabled) return false;
|
||||
|
||||
return a.offset.getX() != 0 || a.offset.getY() != 0 || a.offset.getZ() != 0;
|
||||
}
|
||||
|
||||
public static class ArraySettings {
|
||||
public boolean enabled = false;
|
||||
public BlockPos offset = BlockPos.ZERO;
|
||||
public int count = 5;
|
||||
|
||||
public ArraySettings() {
|
||||
}
|
||||
|
||||
public ArraySettings(boolean enabled, BlockPos offset, int count) {
|
||||
this.enabled = enabled;
|
||||
this.offset = offset;
|
||||
this.count = count;
|
||||
}
|
||||
|
||||
public int getReach() {
|
||||
//find largest offset
|
||||
int x = Math.abs(offset.getX());
|
||||
int y = Math.abs(offset.getY());
|
||||
int z = Math.abs(offset.getZ());
|
||||
int largestOffset = Math.max(Math.max(x, y), z);
|
||||
|
||||
return largestOffset * count;
|
||||
}
|
||||
}
|
||||
|
||||
public int getReach() {
|
||||
//find largest offset
|
||||
int x = Math.abs(offset.getX());
|
||||
int y = Math.abs(offset.getY());
|
||||
int z = Math.abs(offset.getZ());
|
||||
int largestOffset = Math.max(Math.max(x, y), z);
|
||||
|
||||
return largestOffset * count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag serializeNBT() {
|
||||
var compound = super.serializeNBT();
|
||||
compound.getCompound("offset").merge(NbtUtils.writeBlockPos(offset));
|
||||
compound.putInt("count", count);
|
||||
return compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(CompoundTag compound) {
|
||||
super.deserializeNBT(compound);
|
||||
offset = NbtUtils.readBlockPos(compound.getCompound("offset"));
|
||||
count = compound.getInt("count");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
if (world.isClientSide) {
|
||||
// BlockPreviews.onBlocksBroken(blocks);
|
||||
|
||||
//list of air blockstates
|
||||
for (int i = 0; i < coordinates.size(); i++) {
|
||||
newBlockStates.add(Blocks.AIR.defaultBlockState());
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
//If the player is going to instabreak grass or a plant, only break other instabreaking things
|
||||
boolean onlyInstaBreaking = !player.isCreative() &&
|
||||
world.getBlockState(startCoordinates.get(0)).getDestroySpeed(world, startCoordinates.get(0)) == 0f;
|
||||
|
||||
//break all those blocks
|
||||
for (int i = breakStartPos ? 0 : 1; i < coordinates.size(); i++) {
|
||||
BlockPos coordinate = coordinates.get(i);
|
||||
if (world.isLoaded(coordinate) && !world.isEmptyBlock(coordinate)) {
|
||||
if (!onlyInstaBreaking || world.getBlockState(coordinate).getDestroySpeed(world, coordinate) == 0f) {
|
||||
SurvivalHelper.breakBlock(world, player, coordinate, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//find actual new blockstates for undo
|
||||
for (BlockPos coordinate : coordinates) {
|
||||
newBlockStates.add(world.getBlockState(coordinate));
|
||||
}
|
||||
}
|
||||
|
||||
//Set first newBlockState to empty if in NORMAL mode, to make undo/redo work
|
||||
//(Block isn't broken yet by the time it gets here, and broken after this)
|
||||
if (!breakStartPos) newBlockStates.set(0, Blocks.AIR.defaultBlockState());
|
||||
|
||||
//add to undo stack
|
||||
BlockPos firstPos = startCoordinates.get(0);
|
||||
BlockPos secondPos = startCoordinates.get(startCoordinates.size() - 1);
|
||||
UndoRedo.addUndo(player, new UndoRedoBlockSet(coordinates, previousBlockStates, newBlockStates, firstPos, secondPos));
|
||||
private static final String DATA_KEY = EffortlessBuilding.MODID + ":buildModifiers";
|
||||
|
||||
public void save(Player player) {
|
||||
var listTag = NBTHelper.writeCompoundList(modifierSettingsList, BaseModifier::serializeNBT);
|
||||
player.getPersistentData().put(DATA_KEY, listTag);
|
||||
}
|
||||
|
||||
public static List<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;
|
||||
//TODO call load
|
||||
public void load(Player player) {
|
||||
var listTag = player.getPersistentData().getList(DATA_KEY, Tag.TAG_COMPOUND);
|
||||
modifierSettingsList = NBTHelper.readCompoundList(listTag, compoundTag -> {
|
||||
var modifier = createModifier(compoundTag.getString("type"));
|
||||
modifier.deserializeNBT(compoundTag);
|
||||
return modifier;
|
||||
});
|
||||
}
|
||||
|
||||
public static List<BlockPos> findCoordinates(Player player, BlockPos blockPos) {
|
||||
return findCoordinates(player, new ArrayList<>(Collections.singletonList(blockPos)));
|
||||
private BaseModifier createModifier(String type) {
|
||||
switch (type) {
|
||||
case "Mirror": return new Mirror();
|
||||
case "Array": return new Array();
|
||||
case "RadialMirror": return new RadialMirror();
|
||||
default: throw new IllegalArgumentException("Unknown modifier type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<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));
|
||||
// }
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// 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;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,234 +1,113 @@
|
||||
package nl.requios.effortlessbuilding.buildmodifier;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.nbt.Tag;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.state.properties.Half;
|
||||
import net.minecraft.world.level.block.state.properties.SlabType;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
import nl.requios.effortlessbuilding.item.AbstractRandomizerBagItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import nl.requios.effortlessbuilding.utilities.BlockEntry;
|
||||
import nl.requios.effortlessbuilding.utilities.BlockSet;
|
||||
|
||||
import net.minecraft.world.level.block.DirectionalBlock;
|
||||
import net.minecraft.world.level.block.DispenserBlock;
|
||||
import net.minecraft.world.level.block.SlabBlock;
|
||||
import net.minecraft.world.level.block.StairBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
public class Mirror extends BaseModifier {
|
||||
public Vec3 position = new Vec3(0.5, 64.5, 0.5);
|
||||
public boolean mirrorX = true;
|
||||
public boolean mirrorY = false;
|
||||
public boolean mirrorZ = false;
|
||||
public int radius = 10;
|
||||
public boolean drawLines = true;
|
||||
public boolean drawPlanes = true;
|
||||
|
||||
public class Mirror {
|
||||
@Override
|
||||
public void findCoordinates(BlockSet blocks, Player player) {
|
||||
if (!(enabled && (mirrorX || mirrorY || mirrorZ))) return;
|
||||
|
||||
public static List<BlockPos> findCoordinates(Player player, BlockPos startPos) {
|
||||
List<BlockPos> coordinates = new ArrayList<>();
|
||||
var originalBlocks = new BlockSet(blocks);
|
||||
for (BlockEntry blockEntry : originalBlocks) {
|
||||
if (!isWithinRange(blockEntry.blockPos)) continue;
|
||||
|
||||
//find mirrorsettings for the player
|
||||
MirrorSettings m = ModifierSettingsManager.getModifierSettings(player).getMirrorSettings();
|
||||
if (!isEnabled(m, startPos)) return coordinates;
|
||||
|
||||
if (m.mirrorX) coordinateMirrorX(m, startPos, coordinates);
|
||||
if (m.mirrorY) coordinateMirrorY(m, startPos, coordinates);
|
||||
if (m.mirrorZ) coordinateMirrorZ(m, startPos, coordinates);
|
||||
|
||||
return coordinates;
|
||||
if (mirrorX) performMirrorX(blocks, blockEntry);
|
||||
if (mirrorY) performMirrorY(blocks, blockEntry);
|
||||
if (mirrorZ) performMirrorZ(blocks, blockEntry);
|
||||
}
|
||||
}
|
||||
|
||||
private static void coordinateMirrorX(MirrorSettings m, BlockPos oldBlockPos, List<BlockPos> coordinates) {
|
||||
private void performMirrorX(BlockSet blocks, BlockEntry blockEntry) {
|
||||
//find mirror position
|
||||
double x = m.position.x + (m.position.x - oldBlockPos.getX() - 0.5);
|
||||
BlockPos newBlockPos = new BlockPos(x, oldBlockPos.getY(), oldBlockPos.getZ());
|
||||
coordinates.add(newBlockPos);
|
||||
double x = position.x + (position.x - blockEntry.blockPos.getX() - 0.5);
|
||||
BlockPos newBlockPos = new BlockPos(x, blockEntry.blockPos.getY(), blockEntry.blockPos.getZ());
|
||||
|
||||
if (m.mirrorY) coordinateMirrorY(m, newBlockPos, coordinates);
|
||||
if (m.mirrorZ) coordinateMirrorZ(m, newBlockPos, coordinates);
|
||||
if (blocks.containsKey(newBlockPos)) return;
|
||||
|
||||
var newBlockEntry = new BlockEntry(newBlockPos);
|
||||
newBlockEntry.copyRotationSettingsFrom(blockEntry);
|
||||
newBlockEntry.mirrorX = !newBlockEntry.mirrorX;
|
||||
|
||||
if (mirrorY) performMirrorY(blocks, newBlockEntry);
|
||||
if (mirrorZ) performMirrorZ(blocks, newBlockEntry);
|
||||
}
|
||||
|
||||
private static void coordinateMirrorY(MirrorSettings m, BlockPos oldBlockPos, List<BlockPos> coordinates) {
|
||||
private void performMirrorY(BlockSet blocks, BlockEntry blockEntry) {
|
||||
//find mirror position
|
||||
double y = m.position.y + (m.position.y - oldBlockPos.getY() - 0.5);
|
||||
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), y, oldBlockPos.getZ());
|
||||
coordinates.add(newBlockPos);
|
||||
double y = position.y + (position.y - blockEntry.blockPos.getY() - 0.5);
|
||||
BlockPos newBlockPos = new BlockPos(blockEntry.blockPos.getX(), y, blockEntry.blockPos.getZ());
|
||||
|
||||
if (m.mirrorZ) coordinateMirrorZ(m, newBlockPos, coordinates);
|
||||
if (blocks.containsKey(newBlockPos)) return;
|
||||
|
||||
var newBlockEntry = new BlockEntry(newBlockPos);
|
||||
newBlockEntry.copyRotationSettingsFrom(blockEntry);
|
||||
newBlockEntry.mirrorY = !newBlockEntry.mirrorY;
|
||||
|
||||
if (mirrorZ) performMirrorZ(blocks, newBlockEntry);
|
||||
}
|
||||
|
||||
private static void coordinateMirrorZ(MirrorSettings m, BlockPos oldBlockPos, List<BlockPos> coordinates) {
|
||||
private void performMirrorZ(BlockSet blocks, BlockEntry blockEntry) {
|
||||
//find mirror position
|
||||
double z = m.position.z + (m.position.z - oldBlockPos.getZ() - 0.5);
|
||||
BlockPos newBlockPos = new BlockPos(oldBlockPos.getX(), oldBlockPos.getY(), z);
|
||||
coordinates.add(newBlockPos);
|
||||
double z = position.z + (position.z - blockEntry.blockPos.getZ() - 0.5);
|
||||
BlockPos newBlockPos = new BlockPos(blockEntry.blockPos.getX(), blockEntry.blockPos.getY(), z);
|
||||
|
||||
if (blocks.containsKey(newBlockPos)) return;
|
||||
|
||||
var newBlockEntry = new BlockEntry(newBlockPos);
|
||||
newBlockEntry.copyRotationSettingsFrom(blockEntry);
|
||||
newBlockEntry.mirrorZ = !newBlockEntry.mirrorZ;
|
||||
}
|
||||
|
||||
public static List<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;
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
public int getReach() {
|
||||
return radius * 2; //Change ModifierSettings#setReachUpgrade too
|
||||
}
|
||||
|
||||
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);
|
||||
@Override
|
||||
public CompoundTag serializeNBT() {
|
||||
var compound = super.serializeNBT();
|
||||
compound.putDouble("positionX", position.x);
|
||||
compound.putDouble("positionY", position.y);
|
||||
compound.putDouble("positionZ", position.z);
|
||||
compound.putBoolean("mirrorX", mirrorX);
|
||||
compound.putBoolean("mirrorY", mirrorY);
|
||||
compound.putBoolean("mirrorZ", mirrorZ);
|
||||
compound.putInt("radius", radius);
|
||||
compound.putBoolean("drawLines", drawLines);
|
||||
compound.putBoolean("drawPlanes", drawPlanes);
|
||||
return compound;
|
||||
}
|
||||
|
||||
private static void 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 Vec3 position = new Vec3(0.5, 64.5, 0.5);
|
||||
public boolean mirrorX = true, mirrorY = false, mirrorZ = false;
|
||||
public int radius = 10;
|
||||
public boolean drawLines = true, drawPlanes = true;
|
||||
|
||||
public MirrorSettings() {
|
||||
}
|
||||
|
||||
public MirrorSettings(boolean mirrorEnabled, Vec3 position, boolean mirrorX, boolean mirrorY, boolean mirrorZ, int radius, boolean drawLines, boolean drawPlanes) {
|
||||
this.enabled = mirrorEnabled;
|
||||
this.position = position;
|
||||
this.mirrorX = mirrorX;
|
||||
this.mirrorY = mirrorY;
|
||||
this.mirrorZ = mirrorZ;
|
||||
this.radius = radius;
|
||||
this.drawLines = drawLines;
|
||||
this.drawPlanes = drawPlanes;
|
||||
}
|
||||
|
||||
public int getReach() {
|
||||
return radius * 2; //Change ModifierSettings#setReachUpgrade too
|
||||
}
|
||||
@Override
|
||||
public void deserializeNBT(CompoundTag compound) {
|
||||
super.deserializeNBT(compound);
|
||||
position = new Vec3(compound.getDouble("positionX"), compound.getDouble("positionY"), compound.getDouble("positionZ"));
|
||||
mirrorX = compound.getBoolean("mirrorX");
|
||||
mirrorY = compound.getBoolean("mirrorY");
|
||||
mirrorZ = compound.getBoolean("mirrorZ");
|
||||
radius = compound.getInt("radius");
|
||||
drawLines = compound.getBoolean("drawLines");
|
||||
drawPlanes = compound.getBoolean("drawPlanes");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
return coordinates;
|
||||
if (blocks.containsKey(newBlockPos)) continue;
|
||||
|
||||
BlockEntry newBlockEntry = new BlockEntry(newBlockPos);
|
||||
newBlockEntry.copyRotationSettingsFrom(blockEntry);
|
||||
|
||||
//rotate block
|
||||
double angleToCenter = Mth.atan2(relNewVec.x, relNewVec.z); //between -PI and PI
|
||||
rotateBlockEntry(newBlockEntry, angleToCenter, doAlternate);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<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
|
||||
private void rotateBlockEntry(BlockEntry blockEntry, double angleToCenter, boolean alternate) {
|
||||
|
||||
//find radial mirror settings for the player that placed the block
|
||||
RadialMirrorSettings r = ModifierSettingsManager.getModifierSettings(player).getRadialMirrorSettings();
|
||||
if (!isEnabled(r, startPos)) return blockStates;
|
||||
|
||||
|
||||
//get angle between slices
|
||||
double sliceAngle = 2 * Math.PI / r.slices;
|
||||
|
||||
Vec3 startVec = new Vec3(startPos.getX() + 0.5f, startPos.getY() + 0.5f, startPos.getZ() + 0.5f);
|
||||
Vec3 relStartVec = startVec.subtract(r.position);
|
||||
|
||||
double startAngleToCenter = Mth.atan2(relStartVec.x, relStartVec.z);
|
||||
double startAngleToCenterMod = startAngleToCenter < 0 ? startAngleToCenter + Math.PI : startAngleToCenter;
|
||||
double startAngleInSlice = startAngleToCenterMod % sliceAngle;
|
||||
|
||||
//Rotate the original blockstate
|
||||
blockState = rotateOriginalBlockState(player, startPos, startAngleToCenter, blockState);
|
||||
|
||||
//Randomizer bag synergy
|
||||
AbstractRandomizerBagItem randomizerBagItem = null;
|
||||
IItemHandler bagInventory = null;
|
||||
if (!itemStack.isEmpty() && itemStack.getItem() instanceof AbstractRandomizerBagItem) {
|
||||
randomizerBagItem = (AbstractRandomizerBagItem) itemStack.getItem() ;
|
||||
bagInventory = randomizerBagItem.getBagInventory(itemStack);
|
||||
}
|
||||
|
||||
BlockState newBlockState;
|
||||
for (int i = 1; i < r.slices; i++) {
|
||||
newBlockState = blockState;
|
||||
double curAngle = sliceAngle * i;
|
||||
|
||||
//alternate mirroring of slices
|
||||
if (r.alternate && i % 2 == 1) {
|
||||
curAngle = curAngle - startAngleInSlice + (sliceAngle - startAngleInSlice);
|
||||
if (angleToCenter < -0.751 * Math.PI || angleToCenter > 0.749 * Math.PI) {
|
||||
blockEntry.rotation = blockEntry.rotation.getRotated(Rotation.CLOCKWISE_180);
|
||||
if (alternate) {
|
||||
blockEntry.mirrorZ = !blockEntry.mirrorZ;
|
||||
}
|
||||
|
||||
Vec3 relNewVec = relStartVec.yRot((float) curAngle);
|
||||
BlockPos newBlockPos = new BlockPos(r.position.add(relNewVec));
|
||||
if (coordinates.contains(newBlockPos) || newBlockPos.equals(startPos)) continue; //filter out duplicates
|
||||
coordinates.add(newBlockPos);
|
||||
|
||||
//Randomizer bag synergy
|
||||
if (randomizerBagItem != null) {
|
||||
itemStack = randomizerBagItem.pickRandomStack(bagInventory);
|
||||
newBlockState = BuildModifiers
|
||||
.getBlockStateFromItem(itemStack, player, startPos, Direction.UP, new Vec3(0, 0, 0), InteractionHand.MAIN_HAND);
|
||||
|
||||
newBlockState = rotateOriginalBlockState(player, startPos, startAngleToCenter, newBlockState);
|
||||
} else if (angleToCenter < -0.251 * Math.PI) {
|
||||
blockEntry.rotation = blockEntry.rotation.getRotated(Rotation.CLOCKWISE_90);
|
||||
if (alternate) {
|
||||
blockEntry.mirrorX = !blockEntry.mirrorX;
|
||||
}
|
||||
} else if (angleToCenter > 0.249 * Math.PI) {
|
||||
blockEntry.rotation = blockEntry.rotation.getRotated(Rotation.COUNTERCLOCKWISE_90);
|
||||
if (alternate) {
|
||||
blockEntry.mirrorX = !blockEntry.mirrorX;
|
||||
}
|
||||
} else {
|
||||
if (alternate) {
|
||||
blockEntry.mirrorZ = !blockEntry.mirrorZ;
|
||||
}
|
||||
|
||||
//rotate
|
||||
newBlockState = rotateBlockState(player, startPos, relNewVec, newBlockState, r.alternate && i % 2 == 1);
|
||||
|
||||
blockStates.add(newBlockState);
|
||||
itemStacks.add(itemStack);
|
||||
}
|
||||
|
||||
return blockStates;
|
||||
}
|
||||
|
||||
private static BlockState rotateOriginalBlockState(Player player, BlockPos startPos, double startAngleToCenter, BlockState blockState) {
|
||||
@@ -158,37 +143,36 @@ public class RadialMirror {
|
||||
return newBlockState;
|
||||
}
|
||||
|
||||
public static boolean isEnabled(RadialMirrorSettings r, BlockPos startPos) {
|
||||
if (r == null || !r.enabled) return false;
|
||||
|
||||
return !(new Vec3(startPos.getX() + 0.5, startPos.getY() + 0.5, startPos.getZ() + 0.5).subtract(r.position).lengthSqr() >
|
||||
r.radius * r.radius);
|
||||
public boolean isWithinRange(BlockPos startPos) {
|
||||
return (new Vec3(startPos.getX() + 0.5, startPos.getY() + 0.5, startPos.getZ() + 0.5).subtract(position).lengthSqr() < radius * radius);
|
||||
}
|
||||
|
||||
public static class RadialMirrorSettings {
|
||||
public boolean enabled = false;
|
||||
public Vec3 position = new Vec3(0.5, 64.5, 0.5);
|
||||
public int slices = 4;
|
||||
public boolean alternate = false;
|
||||
public int radius = 20;
|
||||
public boolean drawLines = true, drawPlanes = false;
|
||||
|
||||
public RadialMirrorSettings() {
|
||||
}
|
||||
|
||||
public RadialMirrorSettings(boolean enabled, Vec3 position, int slices, boolean alternate, int radius, boolean drawLines, boolean drawPlanes) {
|
||||
this.enabled = enabled;
|
||||
this.position = position;
|
||||
this.slices = slices;
|
||||
this.alternate = alternate;
|
||||
this.radius = radius;
|
||||
this.drawLines = drawLines;
|
||||
this.drawPlanes = drawPlanes;
|
||||
}
|
||||
|
||||
public int getReach() {
|
||||
return radius * 2;
|
||||
}
|
||||
public int getReach() {
|
||||
return radius * 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag serializeNBT() {
|
||||
var compound = super.serializeNBT();
|
||||
compound.putDouble("positionX", position.x);
|
||||
compound.putDouble("positionY", position.y);
|
||||
compound.putDouble("positionZ", position.z);
|
||||
compound.putInt("slices", slices);
|
||||
compound.putBoolean("alternate", alternate);
|
||||
compound.putInt("radius", radius);
|
||||
compound.putBoolean("drawLines", drawLines);
|
||||
compound.putBoolean("drawPlanes", drawPlanes);
|
||||
return compound;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deserializeNBT(CompoundTag nbt) {
|
||||
super.deserializeNBT(nbt);
|
||||
position = new Vec3(nbt.getDouble("positionX"), nbt.getDouble("positionY"), nbt.getDouble("positionZ"));
|
||||
slices = nbt.getInt("slices");
|
||||
alternate = nbt.getBoolean("alternate");
|
||||
radius = nbt.getInt("radius");
|
||||
drawLines = nbt.getBoolean("drawLines");
|
||||
drawPlanes = nbt.getBoolean("drawPlanes");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package nl.requios.effortlessbuilding.capability;
|
||||
package nl.requios.effortlessbuilding.item;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.core.Direction;
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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.*;
|
||||
|
||||
@@ -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;
|
||||
|
||||
/***
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user