From cf5c9df1f3d9c01e960046ec59b7fc6678943601 Mon Sep 17 00:00:00 2001 From: zhangyuheng Date: Wed, 17 Apr 2024 21:53:49 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=A4=85=E5=AD=90=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- .../cn/lunadeer/essentialsd/ChairEvent.java | 198 ++++++++++++++++++ .../cn/lunadeer/essentialsd/EssentialsD.java | 1 + .../essentialsd/utils/ConfigManager.java | 25 ++- src/main/resources/config.yml | 6 + 5 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 src/main/java/cn/lunadeer/essentialsd/ChairEvent.java diff --git a/pom.xml b/pom.xml index baa2510..913291f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ cn.lunadeer EssentialsD - 1.14.4 + 1.15.7 jar EssentialsD diff --git a/src/main/java/cn/lunadeer/essentialsd/ChairEvent.java b/src/main/java/cn/lunadeer/essentialsd/ChairEvent.java new file mode 100644 index 0000000..7c88043 --- /dev/null +++ b/src/main/java/cn/lunadeer/essentialsd/ChairEvent.java @@ -0,0 +1,198 @@ +package cn.lunadeer.essentialsd; + +import cn.lunadeer.essentialsd.utils.XLogger; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.type.Sign; +import org.bukkit.block.data.type.Stairs; +import org.bukkit.block.data.type.WallSign; +import org.bukkit.entity.*; +import org.bukkit.event.Event; +import org.bukkit.util.Vector; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +public class ChairEvent implements Listener { + + @EventHandler + public void onPlayerInteract(PlayerInteractEvent event) { + if (!EssentialsD.config.getChairEnable()) { + return; + } + if (event.getAction() != Action.RIGHT_CLICK_BLOCK) { + return; + } + Block block = event.getClickedBlock(); + if (block == null) { + return; + } + + Player player = event.getPlayer(); + if (!(block.getState().getBlockData() instanceof Stairs)) { + return; + } + Stairs stairs = (Stairs) block.getState().getBlockData(); + int chair_width = 1; + + // Check if block beneath chair is solid. + if (block.getRelative(BlockFace.DOWN).isEmpty()) + return; + + // Check if player is sitting. + if (!player.isSneaking() && player.getVehicle() != null) { + player.getVehicle().remove(); + return; + } + + // Check for distance between player and chair. + if (player.getLocation().distance(block.getLocation().add(0.5, 0, 0.5)) > 2) + return; + + // Check for signs. + if (EssentialsD.config.getChairSignCheck()) { + boolean sign1 = false; + boolean sign2 = false; + + if (stairs.getFacing() == BlockFace.NORTH || stairs.getFacing() == BlockFace.SOUTH) { + sign1 = checkSign(block, BlockFace.EAST); + sign2 = checkSign(block, BlockFace.WEST); + } else if (stairs.getFacing() == BlockFace.EAST || stairs.getFacing() == BlockFace.WEST) { + sign1 = checkSign(block, BlockFace.NORTH); + sign2 = checkSign(block, BlockFace.SOUTH); + } + + if (!(sign1 && sign2)) + return; + } + + // Check for maximal chair width. + if (EssentialsD.config.getChairMaxWidth() > 0) { + if (stairs.getFacing() == BlockFace.NORTH || stairs.getFacing() == BlockFace.SOUTH) { + chair_width += getChairWidth(block, BlockFace.EAST); + chair_width += getChairWidth(block, BlockFace.WEST); + } else if (stairs.getFacing() == BlockFace.EAST || stairs.getFacing() == BlockFace.WEST) { + chair_width += getChairWidth(block, BlockFace.NORTH); + chair_width += getChairWidth(block, BlockFace.SOUTH); + } + + if (chair_width > EssentialsD.config.getChairMaxWidth()) + return; + } + + // Sit-down process. + if (player.getVehicle() != null) + player.getVehicle().remove(); + + ArmorStand drop = dropSeat(block); + + // Changing the drop material is only necessary for the item merge feature of CB++ + // The client won't update the material, though. + if (!drop.addPassenger(player)) { + XLogger.debug("Failed to make player " + player.getName() + " sit on a chair."); + } else { + XLogger.debug("Player " + player.getName() + " is sitting on a chair."); + } + + // Cancel BlockPlaceEvent Result, if player is rightclicking with a block in his hand. + event.setUseInteractedBlock(Event.Result.DENY); + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + if (!EssentialsD.config.getChairEnable()) { + return; + } + if (!(event.getBlock().getState().getBlockData() instanceof Stairs)) { + return; + } + clearSeat(event.getBlock()); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (!EssentialsD.config.getChairEnable()) { + return; + } + Entity vehicle = event.getPlayer().getVehicle(); + // Let players stand up when leaving the server. + if (vehicle instanceof Item) + vehicle.remove(); + } + + private ArmorStand dropSeat(Block chair) { + clearSeat(chair); + Location location = chair.getLocation().add(0.5, (EssentialsD.config.getChairSitHeight() + 0.5), 0.5); + switch (((Stairs) chair.getState().getBlockData()).getFacing()) { + case SOUTH: + location.setDirection(new Vector(0, 0, -1)); + break; + case WEST: + location.setDirection(new Vector(1, 0, 0)); + break; + case NORTH: + location.setDirection(new Vector(0, 0, 1)); + break; + case EAST: + location.setDirection(new Vector(-1, 0, 0)); + break; + } + ArmorStand armorStand = (ArmorStand) chair.getWorld().spawnEntity(location, EntityType.ARMOR_STAND); + if (!EssentialsD.config.isDebug()) { + armorStand.setVisible(false); + } + armorStand.setGravity(false); + armorStand.setInvulnerable(true); + armorStand.setSmall(true); + XLogger.debug("Chair dropped at " + location.toString()); + return armorStand; + } + + private void clearSeat(Block chair) { + Location location = chair.getLocation().add(0.5, (EssentialsD.config.getChairSitHeight() + 0.5), 0.5); + for (Entity e : location.getWorld().getNearbyEntities(location, 0.4, 0.4, 0.4)) { + if (e instanceof ArmorStand) { + e.remove(); + } + } + } + + private int getChairWidth(Block block, BlockFace face) { + int width = 0; + + // Go through the blocks next to the clicked block and check if there are any further stairs. + for (int i = 1; i <= EssentialsD.config.getChairMaxWidth(); i++) { + Block relative = block.getRelative(face, i); + if (!(relative.getState().getBlockData() instanceof Stairs)) { + break; + } + if (((Stairs) relative.getState().getBlockData()).getFacing() == ((Stairs) block.getState().getBlockData()).getFacing()) + width++; + else + break; + } + + return width; + } + + private boolean checkSign(Block block, BlockFace face) { + // Go through the blocks next to the clicked block and check if are signs on the end. + for (int i = 1; i <= EssentialsD.config.getChairMaxWidth(); i++) { + Block relative = block.getRelative(face, i); + if (relative.getState().getBlockData() instanceof Stairs) { + continue; + } + return relative.getState().getBlockData() instanceof WallSign; + } + return false; + } +} diff --git a/src/main/java/cn/lunadeer/essentialsd/EssentialsD.java b/src/main/java/cn/lunadeer/essentialsd/EssentialsD.java index 1262013..e727bbd 100644 --- a/src/main/java/cn/lunadeer/essentialsd/EssentialsD.java +++ b/src/main/java/cn/lunadeer/essentialsd/EssentialsD.java @@ -22,6 +22,7 @@ public final class EssentialsD extends JavaPlugin { tpManager = new TeleportManager(); Bukkit.getPluginManager().registerEvents(new Events(), this); + Bukkit.getPluginManager().registerEvents(new ChairEvent(), this); Objects.requireNonNull(Bukkit.getPluginCommand("suicide")).setExecutor(new Suicide()); Objects.requireNonNull(Bukkit.getPluginCommand("hat")).setExecutor(new Hat()); Objects.requireNonNull(Bukkit.getPluginCommand("showitem")).setExecutor(new ShowItem()); diff --git a/src/main/java/cn/lunadeer/essentialsd/utils/ConfigManager.java b/src/main/java/cn/lunadeer/essentialsd/utils/ConfigManager.java index f08d7b7..77bfb5d 100644 --- a/src/main/java/cn/lunadeer/essentialsd/utils/ConfigManager.java +++ b/src/main/java/cn/lunadeer/essentialsd/utils/ConfigManager.java @@ -29,6 +29,10 @@ public class ConfigManager { _tp_cool_down = _file.getInt("Teleport.CoolDown", 0); _tp_expire = _file.getInt("Teleport.Expire", 30); _loot_table_ratio = _file.getInt("LootTableRatio", 1); + _chair_enable = _file.getBoolean("Chair.Enable", true); + _chair_max_width = _file.getInt("Chair.MaxWidth", 4); + _chair_sign_check = _file.getBoolean("Chair.SignCheck", false); + _chair_sit_height = (float) _file.getDouble("Chair.SitHeight", -0.95); } public Boolean isDebug() { @@ -81,6 +85,22 @@ public class ConfigManager { return _loot_table_ratio; } + public Boolean getChairEnable() { + return _chair_enable; + } + + public Integer getChairMaxWidth() { + return _chair_max_width; + } + + public Boolean getChairSignCheck() { + return _chair_sign_check; + } + + public Float getChairSitHeight() { + return _chair_sit_height; + } + public void ApplyForceLoadChunks() { if (_chunk_operate_delay < 0) { XLogger.info("加载区块操作已禁用"); @@ -131,5 +151,8 @@ public class ConfigManager { private Integer _tp_delay; private Integer _tp_cool_down; private Integer _loot_table_ratio; - + private Boolean _chair_enable; + private Integer _chair_max_width; + private Boolean _chair_sign_check; + private Float _chair_sit_height; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2f0ddae..9f16c09 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -23,4 +23,10 @@ Teleport: # 冷却时间 秒 CoolDown: 0 +Chair: + Enable: true + MaxWidth: 4 + SignCheck: false + SitHeight: -0.95 + Debug: false \ No newline at end of file