Added rotate block command

This commit is contained in:
Teriuihi 2023-07-08 06:26:01 +02:00
parent 54db863783
commit 1b9278ca25
5 changed files with 332 additions and 7 deletions

View File

@ -1,8 +1,10 @@
package com.alttd.playerutils;
import com.alttd.playerutils.commands.PlayerUtilsCommand;
import com.alttd.playerutils.commands.playerutils_subcommands.RotateBlock;
import com.alttd.playerutils.config.Config;
import com.alttd.playerutils.config.Messages;
import com.alttd.playerutils.event_listeners.RotateBlockEvent;
import com.alttd.playerutils.event_listeners.XpBottleEvent;
import com.alttd.playerutils.util.Logger;
import org.bukkit.plugin.java.JavaPlugin;
@ -10,6 +12,7 @@ import org.bukkit.plugin.java.JavaPlugin;
public final class PlayerUtils extends JavaPlugin {
private Logger logger;
private PlayerUtilsCommand playerUtilsCommand;
@Override
public void onEnable() {
@ -23,11 +26,15 @@ public final class PlayerUtils extends JavaPlugin {
}
private void registerCommands() {
new PlayerUtilsCommand(this, logger);
playerUtilsCommand = new PlayerUtilsCommand(this, logger);
}
private void registerEvents() {
getServer().getPluginManager().registerEvents(new XpBottleEvent(this, logger), this);
RotateBlockEvent rotateBlockEvent = new RotateBlockEvent();
getServer().getPluginManager().registerEvents(rotateBlockEvent, this);
playerUtilsCommand.addSubCommand(new RotateBlock(rotateBlockEvent));
}
public void reloadConfigs() {

View File

@ -1,11 +1,9 @@
package com.alttd.playerutils.commands;
import com.alttd.playerutils.PlayerUtils;
import com.alttd.playerutils.commands.playerutils_subcommands.Glow;
import com.alttd.playerutils.commands.playerutils_subcommands.Reload;
import com.alttd.playerutils.commands.playerutils_subcommands.XPCalc;
import com.alttd.playerutils.commands.playerutils_subcommands.XPCheque;
import com.alttd.playerutils.commands.playerutils_subcommands.*;
import com.alttd.playerutils.config.Messages;
import com.alttd.playerutils.event_listeners.RotateBlockEvent;
import com.alttd.playerutils.util.Logger;
import org.bukkit.command.*;
import org.jetbrains.annotations.NotNull;
@ -30,11 +28,11 @@ public class PlayerUtilsCommand implements CommandExecutor, TabExecutor {
command.setTabCompleter(this);
command.setAliases(List.of("pu"));
subCommands = Arrays.asList(
subCommands = new ArrayList<>(List.of(
new Glow(logger),
new XPCheque(playerUtils),
new XPCalc(),
new Reload(playerUtils)
new Reload(playerUtils))
);
}
@ -95,4 +93,11 @@ public class PlayerUtilsCommand implements CommandExecutor, TabExecutor {
.findFirst()
.orElse(null);
}
public void addSubCommand(SubCommand subCommand) {
if (subCommands.stream().anyMatch(entry -> entry.getName().equalsIgnoreCase(subCommand.getName()))) {
return;
}
subCommands.add(subCommand);
}
}

View File

@ -0,0 +1,48 @@
package com.alttd.playerutils.commands.playerutils_subcommands;
import com.alttd.playerutils.commands.SubCommand;
import com.alttd.playerutils.config.Messages;
import com.alttd.playerutils.event_listeners.RotateBlockEvent;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.util.List;
public class RotateBlock extends SubCommand {
private final RotateBlockEvent rotateBlockEvent;
public RotateBlock(RotateBlockEvent rotateBlockEvent) {
this.rotateBlockEvent = rotateBlockEvent;
}
@Override
public boolean onCommand(CommandSender commandSender, String[] args) {
if (!(commandSender instanceof Player player)) {
commandSender.sendMiniMessage(Messages.GENERIC.PLAYER_ONLY, null);
return true;
}
boolean enabled = rotateBlockEvent.toggleRotate(player.getUniqueId());
if (enabled)
commandSender.sendMiniMessage(Messages.ROTATE_BLOCK.ENABLED, null);
else
commandSender.sendMiniMessage(Messages.ROTATE_BLOCK.DISABLED, null);
return true;
}
@Override
public String getName() {
return "rotateblock";
}
@Override
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
return List.of();
}
@Override
public String getHelpMessage() {
return Messages.HELP.ROTATE_BLOCK;
}
}

View File

@ -33,6 +33,7 @@ public class Messages extends AbstractConfig {
public static String XP_CHEQUE = "<green>Create an xp cheque: <gold>/pu xpcheque <amount></gold></green>";
public static String XP_CALC = "<green>Calculate the amount of xp between levels: <gold>/pu xpcalc <from> <to></gold></green>";
public static String RELOAD = "<green>Reload the configs for PlayerUtils: <gold>/pu reload</gold></green>";
public static String ROTATE_BLOCK = "<green>Enable rotating blocks with a blaze rod: <gold>/pu rotateblock</gold></green>";
@SuppressWarnings("unused")
private static void load() {
@ -42,6 +43,7 @@ public class Messages extends AbstractConfig {
XP_CHEQUE = config.getString(prefix, "xp-cheque", XP_CHEQUE);
XP_CALC = config.getString(prefix, "xp-calc", XP_CALC);
RELOAD = config.getString(prefix, "reload", RELOAD);
ROTATE_BLOCK = config.getString(prefix, "rotate-block", ROTATE_BLOCK);
}
}
@ -115,4 +117,17 @@ public class Messages extends AbstractConfig {
RELOADED = config.getString(prefix, "reloaded", RELOADED);
}
}
public static class ROTATE_BLOCK {
private static final String prefix = "pu-command.rotate-block.";
public static String ENABLED = "<green>You enabled rotating blocks by left clicking them with a <gold>wooden hoe</gold></green>";
public static String DISABLED = "<green>You <red>disabled</red> rotating blocks</green>";
@SuppressWarnings("unused")
private static void load() {
ENABLED = config.getString(prefix, "enabled", ENABLED);
DISABLED = config.getString(prefix, "disabled", DISABLED);
}
}
}

View File

@ -0,0 +1,250 @@
package com.alttd.playerutils.event_listeners;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.Bisected;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.block.data.type.Fence;
import org.bukkit.block.data.type.Stairs;
import org.bukkit.block.data.type.Wall;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import java.util.*;
import java.util.stream.Collectors;
public class RotateBlockEvent implements Listener {
private final HashSet<UUID> rotateEnabled = new HashSet<>();
private static final List<BlockFace> VALID_FOUR_STATES = List.of(BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST);
public synchronized boolean toggleRotate(UUID uuid) {
if (rotateEnabled.contains(uuid)) {
rotateEnabled.remove(uuid);
return false;
} else {
rotateEnabled.add(uuid);
return true;
}
}
private synchronized boolean hasRotateEnabled(UUID uuid) {
return rotateEnabled.contains(uuid);
}
@EventHandler(priority = EventPriority.HIGH)
public void onRightClick(PlayerInteractEvent event) {
Player player = event.getPlayer();
if (!hasRotateEnabled(player.getUniqueId()))
return;
ItemStack item = event.getItem();
if (item == null || !item.getType().equals(Material.WOODEN_HOE))
return;
Block block = event.getClickedBlock();
if (block == null)
return;
Material type = block.getType();
if (Tag.STAIRS.isTagged(type)) {
event.setCancelled(true);
rotateStairs(block, player);
} else if (Tag.WALLS.isTagged(type)) {
event.setCancelled(true);
toggleWall(block, event.getBlockFace(), player, event.getAction().isLeftClick());
} else if (Tag.FENCES.isTagged(type)) {
event.setCancelled(true);
toggleFence(block, event.getBlockFace(), player);
} else if (block.getBlockData() instanceof Directional directional) {
event.setCancelled(true);
rotateNormalBlock(block, directional, player);
}
}
private void rotateNormalBlock(Block block, Directional directional, Player player) {
if (cannotBuild(block, player)) {
return;
}
BlockFace facing = directional.getFacing();
LinkedList<BlockFace> collect = directional.getFaces().stream()
.sorted()
.collect(Collectors.toCollection(LinkedList::new));
int index = collect.indexOf(facing);
if (player.isSneaking()) {
index--;
if (index < 0)
index = collect.size() - 1;
} else {
index++;
if (index >= collect.size())
index = 0;
}
directional.setFacing(collect.get(index));
block.setBlockData(directional);
}
private void toggleFence(Block block, BlockFace blockFace, Player player) {
BlockData blockData = block.getBlockData();
if (!(blockData instanceof Fence fence)) {
return;
}
if (cannotBuild(block, player)) {
return;
}
if (player.isSneaking()) {
fence.getFaces().forEach(face -> fence.setFace(face, false));
block.setBlockData(fence);
return;
}
if (!fence.getAllowedFaces().contains(blockFace)) {
return;
}
Set<BlockFace> faces = fence.getFaces();
fence.setFace(blockFace, !faces.contains(blockFace));
block.setBlockData(fence);
}
private void toggleWall(Block block, BlockFace blockFace, Player player, boolean leftClick) {
BlockData blockData = block.getBlockData();
if (!(blockData instanceof Wall wall)) {
return;
}
if (cannotBuild(block, player)) {
return;
}
if (player.isSneaking()) {
VALID_FOUR_STATES.forEach(face -> wall.setHeight(face, Wall.Height.NONE));
wall.setUp(true);
block.setBlockData(wall);
return;
}
if (!leftClick) {
if (wallHasNoFaces(wall))
return;
wall.setUp(!wall.isUp());
block.setBlockData(wall);
return;
}
if (!VALID_FOUR_STATES.contains(blockFace))
return;
int ordinal = wall.getHeight(blockFace).ordinal();
if (ordinal == Wall.Height.values().length - 1)
ordinal = 0;
else
ordinal++;
wall.setHeight(blockFace, Wall.Height.values()[ordinal]);
if (!wall.isUp() && wallHasNoFaces(wall)) {
wall.setUp(true);
}
block.setBlockData(wall);
}
private boolean wallHasNoFaces(Wall wall) {
for (BlockFace validFourState : VALID_FOUR_STATES) {
if (wall.getHeight(validFourState).equals(Wall.Height.NONE))
continue;
return false;
}
return true;
}
private void rotateStairs(Block block, Player player) {
BlockData blockData = block.getBlockData();
if (!(blockData instanceof Stairs stairs))
return;
if (cannotBuild(block, player)) {
return;
}
Stairs nextRotation;
if (player.isSneaking())
nextRotation = getPreviousRotation(stairs);
else
nextRotation = getNextRotation(stairs);
block.setBlockData(nextRotation);
}
private Stairs getNextRotation(Stairs stairs) {
Stairs.Shape shape = stairs.getShape();
if (shape.ordinal() != Stairs.Shape.values().length - 1) {
stairs.setShape(Stairs.Shape.values()[shape.ordinal() + 1]);
return stairs;
}
Bisected.Half half = stairs.getHalf();
if (half.equals(Bisected.Half.BOTTOM)) {
stairs.setShape(Stairs.Shape.values()[0]);
stairs.setHalf(Bisected.Half.TOP);
return stairs;
}
BlockFace facing = stairs.getFacing();
int index = VALID_FOUR_STATES.indexOf(facing);
if (index == 3) {
index = 0;
} else {
index += 1;
}
stairs.setFacing(VALID_FOUR_STATES.get(index));
stairs.setHalf(Bisected.Half.BOTTOM);
stairs.setShape(Stairs.Shape.values()[0]);
return stairs;
}
private Stairs getPreviousRotation(Stairs stairs) {
Stairs.Shape shape = stairs.getShape();
if (shape.ordinal() != 0) {
stairs.setShape(Stairs.Shape.values()[shape.ordinal() - 1]);
return stairs;
}
Bisected.Half half = stairs.getHalf();
if (half.equals(Bisected.Half.TOP)) {
stairs.setShape(Stairs.Shape.values()[Stairs.Shape.values().length - 1]);
stairs.setHalf(Bisected.Half.BOTTOM);
return stairs;
}
BlockFace facing = stairs.getFacing();
int index = VALID_FOUR_STATES.indexOf(facing);
if (index == 0) {
index = 3;
} else {
index -= 1;
}
stairs.setFacing(VALID_FOUR_STATES.get(index));
stairs.setHalf(Bisected.Half.TOP);
stairs.setShape(Stairs.Shape.values()[Stairs.Shape.values().length - 1]);
return stairs;
}
private boolean cannotBuild(Block block, Player player) {
BlockPlaceEvent placeEvent = new BlockPlaceEvent(block, block.getState(), block, new ItemStack(block.getType()), player, true, EquipmentSlot.HAND);
Bukkit.getPluginManager().callEvent(placeEvent);
return placeEvent.isCancelled();
}
}