Skip to content

Commit

Permalink
improvements for burrow module
Browse files Browse the repository at this point in the history
  • Loading branch information
xGinko committed Aug 12, 2024
1 parent c1f01b9 commit 062cb02
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package me.xginko.aef.modules.combat;

import com.destroystokyo.paper.MaterialTags;
import com.cryptomorin.xseries.XMaterial;
import com.cryptomorin.xseries.XTag;
import me.xginko.aef.modules.AEFModule;
import me.xginko.aef.utils.MaterialUtil;
import org.bukkit.GameMode;
Expand All @@ -16,8 +17,16 @@
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerMoveEvent;

import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Burrow extends AEFModule implements Listener {

private final Set<Material> ignoredMaterial;
private final double damageWhenMovingInBurrow;
private final boolean shouldTeleportUp, preventIfBlockAboveBurrow, breakAnvilInsteadOfTP, allowSlabs;

Expand All @@ -35,6 +44,24 @@ public Burrow() {
this.allowSlabs = config.getBoolean(configPath + ".allow-slabs-in-burrow", true, """
Needs to be enabled to prevent a bug where players are teleported\s
above a slab when the slab is underwater.""");
List<String> defaults = Stream.concat(XTag.SHULKER_BOXES.getValues().stream(),
Stream.of(XMaterial.AIR, XMaterial.DIRT, XMaterial.DIRT_PATH, XMaterial.SAND, XMaterial.GRAVEL))
.filter(XMaterial::isSupported)
.map(XMaterial::parseMaterial)
.map(Enum::name)
.toList();
this.ignoredMaterial = config.getList(configPath + ".ignored-materials", defaults)
.stream()
.map(ignored -> {
try {
return Material.valueOf(ignored);
} catch (IllegalArgumentException e) {
notRecognized(Material.class, ignored);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toCollection(() -> EnumSet.noneOf(Material.class)));
}

@Override
Expand Down Expand Up @@ -69,62 +96,55 @@ private void onSelfPlace(BlockPlaceEvent event) {
private void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
if (player.getGameMode() != GameMode.SURVIVAL) return;
if (player.isInsideVehicle() || player.isGliding()) return;
if (player.isInsideVehicle() || player.isGliding() || player.isSwimming()) return;

final Location playerLocation = player.getLocation();
final Block burrowBlock = playerLocation.getBlock();
final Material burrowMaterial = burrowBlock.getType();

if (
burrowMaterial.equals(Material.AIR)
|| burrowMaterial.equals(Material.DIRT) // Fixes false positives when trampling farmland
|| burrowMaterial.equals(Material.SAND)
|| burrowMaterial.equals(Material.GRAVEL)
|| MaterialTags.SHULKER_BOXES.isTagged(burrowMaterial)
) return;

if (preventIfBlockAboveBurrow || burrowBlock.getRelative(BlockFace.UP).getType().equals(Material.AIR)) {

// Occluding Blocks
if (burrowMaterial.isOccluding() && !MaterialUtil.SINK_IN_BLOCKS.contains(burrowMaterial)) {
if (!allowSlabs || !MaterialUtil.SLAB_LIKE.contains(burrowMaterial)) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
}
if (ignoredMaterial.contains(burrowBlock.getType())) return;

if (!preventIfBlockAboveBurrow && burrowBlock.getRelative(BlockFace.UP).getType() != XMaterial.AIR.parseMaterial()) {
return;
}

// Ender chest & Blocks that are slightly lower in height
if (burrowMaterial.equals(Material.ENDER_CHEST) || MaterialUtil.SINK_IN_BLOCKS.contains(burrowMaterial)) {
if (playerLocation.getY() - playerLocation.getBlockY() < 0.875) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
// Beacon and Indestructibles
if (MaterialUtil.SOLID_INDESTRUCTIBLES.contains(burrowBlock.getType()) || burrowBlock.getType() == XMaterial.BEACON.parseMaterial()) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
return;
}

// Occluding blocks that do not lower the player into themselves
if (burrowBlock.getType().isOccluding() && !MaterialUtil.SINK_IN_BLOCKS.contains(burrowBlock.getType())) {
if (!allowSlabs || !MaterialUtil.SLAB_LIKE.contains(burrowBlock.getType())) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
}

// Enchantment Table
if (burrowMaterial.equals(Material.ENCHANTING_TABLE)) {
if (playerLocation.getY() - playerLocation.getBlockY() < 0.75) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
// Anvil
if (MaterialUtil.ANVILS.contains(burrowBlock.getType())) {
player.damage(damageWhenMovingInBurrow);
if (breakAnvilInsteadOfTP) {
burrowBlock.setType(XMaterial.AIR.parseMaterial());
} else {
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
}

// Anvil
if (MaterialUtil.ANVILS.contains(burrowMaterial)) {
// Ender chest & Blocks that are slightly lower in height
if (burrowBlock.getType() == XMaterial.ENDER_CHEST.parseMaterial() || MaterialUtil.SINK_IN_BLOCKS.contains(burrowBlock.getType())) {
if (playerLocation.getY() - playerLocation.getBlockY() < 0.875) {
player.damage(damageWhenMovingInBurrow);
if (breakAnvilInsteadOfTP) {
burrowBlock.breakNaturally();
} else {
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
}

// Beacon and Indestructibles
if (burrowMaterial.equals(Material.BEACON) || MaterialUtil.SOLID_INDESTRUCTIBLES.contains(burrowMaterial)) {
// Enchantment Table
if (burrowBlock.getType() == XMaterial.ENCHANTING_TABLE.parseMaterial()) {
if (playerLocation.getY() - playerLocation.getBlockY() < 0.75) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package me.xginko.aef.modules.combat;

import com.cryptomorin.xseries.XMaterial;
import com.cryptomorin.xseries.XTag;
import me.xginko.aef.modules.AEFModule;
import me.xginko.aef.utils.EntityUtil;
import me.xginko.aef.utils.MaterialUtil;
import me.xginko.aef.utils.PlatformUtil;
import org.bukkit.GameMode;
Expand All @@ -17,35 +19,51 @@
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerMoveEvent;

import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Burrow extends AEFModule implements Listener {

private final Material SAND, GRAVEL, DIRT, ENCHANTING_TABLE, ENDER_CHEST, BEACON;
private final Set<Material> ignoredMaterial;
private final double damageWhenMovingInBurrow;
private final boolean shouldTeleportUp, preventIfBlockAboveBurrow, breakAnvilInsteadOfTP, allowSlabs;

public Burrow() {
super("combat.prevent-burrow");
// Other cached parsed material
this.SAND = XMaterial.SAND.parseMaterial();
this.GRAVEL = XMaterial.GRAVEL.parseMaterial();
this.ENCHANTING_TABLE = XMaterial.ENCHANTING_TABLE.parseMaterial();
this.ENDER_CHEST = XMaterial.ENDER_CHEST.parseMaterial();
this.BEACON = XMaterial.BEACON.parseMaterial();
this.DIRT = XMaterial.DIRT.parseMaterial();

this.damageWhenMovingInBurrow = config.getDouble(configPath + ".damage-when-moving",1.0,
"1.0 = Half a heart of damage every time you move.");
this.shouldTeleportUp = config.getBoolean(configPath + ".teleport-above-block", true);
this.preventIfBlockAboveBurrow = config.getBoolean(configPath + ".prevent-if-block-above-burrow", false,
"Prevent burrow even if there is a block above the block they\n" +
"are burrowing in.\n" +
"Please note this may allow creating an \"elevator\", players will\n" +
"keep teleporting up until they hit air.");
"are burrowing in.\n" +
"Please note this may allow creating an 'elevator', players will\n" +
"keep teleporting up until they hit air.");
this.breakAnvilInsteadOfTP = config.getBoolean(configPath + ".break-anvil-instead-of-teleport", true);
boolean slabsAreAllowed = config.getBoolean(configPath + ".allow-slabs-in-burrow", true,
this.allowSlabs = config.getBoolean(configPath + ".allow-slabs-in-burrow", PlatformUtil.getMinecraftVersion() > 12,
"Needs to be enabled to prevent a bug where players are teleported\n" +
"above a slab when the slab is underwater.");
this.allowSlabs = PlatformUtil.getMinecraftVersion() > 12 && slabsAreAllowed;
"above a slab when the slab is underwater.");
List<String> defaults = Stream.concat(XTag.SHULKER_BOXES.getValues().stream(),
Stream.of(XMaterial.AIR, XMaterial.DIRT, XMaterial.DIRT_PATH, XMaterial.SAND, XMaterial.GRAVEL))
.filter(XMaterial::isSupported)
.map(XMaterial::parseMaterial)
.map(Enum::name)
.collect(Collectors.toList());
this.ignoredMaterial = config.getList(configPath + ".ignored-materials", defaults)
.stream()
.map(ignored -> {
try {
return Material.valueOf(ignored);
} catch (IllegalArgumentException e) {
notRecognized(Material.class, ignored);
return null;
}
})
.filter(Objects::nonNull)
.collect(Collectors.toCollection(() -> EnumSet.noneOf(Material.class)));
}

@Override
Expand All @@ -64,7 +82,7 @@ public void disable() {
}

private void teleportUpAndCenter(Player player, Location from) {
player.teleport(from.clone().add(0.5, 1, 0.5));
player.teleport(from.clone().add(0.5, 1, 0.5));
}

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
Expand All @@ -79,63 +97,56 @@ private void onSelfPlace(BlockPlaceEvent event) {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
private void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
if (!player.getGameMode().equals(GameMode.SURVIVAL)) return;
if (player.isInsideVehicle() || player.isGliding()) return;
if (player.getGameMode() != GameMode.SURVIVAL) return;
if (player.isInsideVehicle() || player.isGliding() || EntityUtil.isSwimming(player)) return;

final Location playerLocation = player.getLocation();
final Block burrowBlock = playerLocation.getBlock();
final Material burrowMaterial = burrowBlock.getType();

if (
burrowMaterial.equals(Material.AIR)
|| burrowMaterial.equals(DIRT) // Fixes false positives when trampling farmland
|| burrowMaterial.equals(SAND)
|| burrowMaterial.equals(GRAVEL)
|| MaterialUtil.SHULKER_BOXES.contains(burrowMaterial)
) return;

if (preventIfBlockAboveBurrow || burrowBlock.getRelative(BlockFace.UP).getType().equals(Material.AIR)) {

// Occluding Blocks
if (burrowMaterial.isOccluding() && !MaterialUtil.SINK_IN_BLOCKS.contains(burrowMaterial)) {
if (!allowSlabs || !MaterialUtil.SLAB_LIKE.contains(burrowMaterial)) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
}
if (ignoredMaterial.contains(burrowBlock.getType())) return;

if (!preventIfBlockAboveBurrow && burrowBlock.getRelative(BlockFace.UP).getType() != XMaterial.AIR.parseMaterial()) {
return;
}

// Beacon and Indestructibles
if (MaterialUtil.SOLID_INDESTRUCTIBLES.contains(burrowBlock.getType()) || burrowBlock.getType() == XMaterial.BEACON.parseMaterial()) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
return;
}

// Ender chests and blocks that are slightly lower in height
if (burrowMaterial.equals(ENDER_CHEST) || MaterialUtil.SINK_IN_BLOCKS.contains(burrowMaterial)) {
if (playerLocation.getY() - playerLocation.getBlockY() < 0.875) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
// Occluding blocks that do not lower the player into themselves
if (burrowBlock.getType().isOccluding() && !MaterialUtil.SINK_IN_BLOCKS.contains(burrowBlock.getType())) {
if (!allowSlabs || !MaterialUtil.SLAB_LIKE.contains(burrowBlock.getType())) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
}

// Enchantment Tables
if (burrowMaterial.equals(ENCHANTING_TABLE)) {
if (playerLocation.getY() - playerLocation.getBlockY() < 0.75) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
// Anvil
if (MaterialUtil.ANVILS.contains(burrowBlock.getType())) {
player.damage(damageWhenMovingInBurrow);
if (breakAnvilInsteadOfTP) {
burrowBlock.setType(XMaterial.AIR.parseMaterial());
} else {
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
}

// Anvils
if (MaterialUtil.ANVILS.contains(burrowMaterial)) {
// Ender chest & Blocks that are slightly lower in height
if (burrowBlock.getType() == XMaterial.ENDER_CHEST.parseMaterial() || MaterialUtil.SINK_IN_BLOCKS.contains(burrowBlock.getType())) {
if (playerLocation.getY() - playerLocation.getBlockY() < 0.875) {
player.damage(damageWhenMovingInBurrow);
if (breakAnvilInsteadOfTP) {
burrowBlock.breakNaturally();
} else {
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
return;
}

// Beacons and Indestructibles
if (burrowMaterial.equals(BEACON) || MaterialUtil.SOLID_INDESTRUCTIBLES.contains(burrowMaterial)) {
// Enchantment Table
if (burrowBlock.getType() == XMaterial.ENCHANTING_TABLE.parseMaterial()) {
if (playerLocation.getY() - playerLocation.getBlockY() < 0.75) {
player.damage(damageWhenMovingInBurrow);
if (shouldTeleportUp) teleportUpAndCenter(player, burrowBlock.getLocation());
}
Expand Down
12 changes: 12 additions & 0 deletions shared/src/main/java/me/xginko/aef/utils/EntityUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
public class EntityUtil {

private static final boolean MAP_SET_TRACKING_POS_AVAILABLE;
private static final boolean IS_SWIMMING_AVAILABLE;

static {
MAP_SET_TRACKING_POS_AVAILABLE
= Crafty.hasClass("org.bukkit.map.MapView")
&& Crafty.hasMethod(MapView.class, "setTrackingPosition", boolean.class);
IS_SWIMMING_AVAILABLE
= Crafty.hasMethod(LivingEntity.class, "isSwimming", boolean.class);
}

public static boolean canDisableMapPositionCursor() {
Expand Down Expand Up @@ -60,6 +63,15 @@ public static void disableMapPositionCursor(@NotNull ItemFrame itemFrame) {
itemFrame.setItem(itemInsideFrame);
}

/**
* Checks to see if an entity is swimming.
*
* @return True if this entity is swimming.
*/
public static boolean isSwimming(LivingEntity livingEntity) {
return IS_SWIMMING_AVAILABLE && livingEntity.isSwimming();
}

public static final Set<EntityType> MINECARTS = Arrays.stream(XEntityType.values())
.filter(xEntityType -> xEntityType.name().toUpperCase().contains("MINECART"))
.filter(XEntityType::isSupported)
Expand Down

0 comments on commit 062cb02

Please sign in to comment.