diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/bridge/BridgeService.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/bridge/BridgeService.java index ae2ae8be..665362bd 100644 --- a/eternalcombat-api/src/main/java/com/eternalcode/combat/bridge/BridgeService.java +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/bridge/BridgeService.java @@ -30,12 +30,12 @@ public BridgeService(PluginConfig pluginConfig, PluginManager pluginManager, Log public void init(FightManager fightManager, Server server) { this.initialize("WorldGuard", - () -> this.regionProvider = new WorldGuardRegionProvider(this.pluginConfig.settings.blockedRegions), + () -> this.regionProvider = new WorldGuardRegionProvider(this.pluginConfig.settings.blockedRegions, this.pluginConfig), () -> { - this.regionProvider = new DefaultRegionProvider(this.pluginConfig.settings.blockedRegionRadius); + this.regionProvider = new DefaultRegionProvider(this.pluginConfig.settings.blockedRegionRadius); - this.logger.warning("WorldGuard is not installed, set to default region provider."); - }); + this.logger.warning("WorldGuard is not installed, set to default region provider."); + }); this.initialize("PlaceholderAPI", () -> new FightTagPlaceholder(fightManager, server, plugin).register(), diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/config/implementation/PluginConfig.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/config/implementation/PluginConfig.java index badab43e..a192f99f 100644 --- a/eternalcombat-api/src/main/java/com/eternalcode/combat/config/implementation/PluginConfig.java +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/config/implementation/PluginConfig.java @@ -46,8 +46,15 @@ public static class Settings extends OkaeriConfig { @Comment("# List of regions to block") public List blockedRegions = Collections.singletonList("your_region"); - @Comment("# Set the knock multiplier for the blocked region") - public double blockedRegionKnockMultiplier = 1.2; + @Comment({ + "# Set the knock multiplier for the blocked region", + "# Values can be decimal. Do NOT use negative values.", + "# Setting it around 1 knocks the player around 2-4 blocks away." + }) + public double blockedRegionKnockMultiplier = 1; + + @Comment({"# Should the player be prevented from entering regions with WorldGuard flag PVP set to DENY "}) + public boolean shouldPreventPvpRegions = true; @Comment("# Set the radius of the blocked region if you aren't using WorldGuard basen on default spawn region!") public int blockedRegionRadius = 10; @@ -196,7 +203,7 @@ public static class Messages extends OkaeriConfig { public String blockPlacingBlockedDuringCombat = "&cYou cannot place {MODE} {Y} coordinate during combat!"; @Comment("# Message sent when player tries to enter a region") - public String cantEnterOnRegion = "&cYou can't enter on this region during combat!"; + public String cantEnterOnRegion = "&cYou can't enter this region during combat!"; public static class AdminMessages extends OkaeriConfig { @Comment("# Message sent when the configuration is reloaded") diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/notification/NotificationAnnouncer.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/notification/NotificationAnnouncer.java index 6ced8479..47de9228 100644 --- a/eternalcombat-api/src/main/java/com/eternalcode/combat/notification/NotificationAnnouncer.java +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/notification/NotificationAnnouncer.java @@ -45,7 +45,6 @@ public void send(CommandSender sender, Notification notification, Formatter form case BOSS_BAR -> { BossBarNotification bossBarNotification = (BossBarNotification) notification; - BossBar bossBar = bossBarNotification.create(message); audience.showBossBar(bossBar); diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/DefaultRegionProvider.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/DefaultRegionProvider.java index 1f004c1a..8f948ce3 100644 --- a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/DefaultRegionProvider.java +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/DefaultRegionProvider.java @@ -1,6 +1,8 @@ package com.eternalcode.combat.region; +import java.util.Optional; import org.bukkit.Location; +import org.bukkit.util.BlockVector; public class DefaultRegionProvider implements RegionProvider { @@ -11,31 +13,24 @@ public DefaultRegionProvider(int radius) { } @Override - public boolean isInRegion(Location location) { + public Optional getRegion(Location location) { Location spawnLocation = location.getWorld().getSpawnLocation(); double x = spawnLocation.getX(); double z = spawnLocation.getZ(); - Point min = new Point(x - this.radius, z - this.radius); - Point max = new Point(x + this.radius, z + this.radius); + BlockVector min = new BlockVector(x - this.radius, 0, z - this.radius); + BlockVector max = new BlockVector(x + this.radius, 0, z + this.radius); - return this.contains(min, max, location.getX(), location.getZ()); - } + if (this.contains(min, max, location.getX(), location.getZ())) { + return Optional.of(() -> new Location(location.getWorld(), x, location.getY(), z)); + } - @Override - public Location getRegionCenter(Location location) { - Location spawnLocation = location.getWorld().getSpawnLocation(); - double x = spawnLocation.getX(); - double z = spawnLocation.getZ(); - - return new Location(location.getWorld(), x, location.getY(), z); + return Optional.empty(); } - public boolean contains(Point min, Point max, double x, double z) { - return x >= min.x() && x < max.x() - && z >= min.z() && z < max.z(); + private boolean contains(BlockVector min, BlockVector max, double x, double z) { + return x >= min.getX() && x < max.getX() + && z >= min.getZ() && z < max.getZ(); } - public record Point(double x, double z) {} - } diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/Region.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/Region.java new file mode 100644 index 00000000..fecd119a --- /dev/null +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/Region.java @@ -0,0 +1,9 @@ +package com.eternalcode.combat.region; + +import org.bukkit.Location; + +public interface Region { + + Location getCenter(); + +} diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/RegionController.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/RegionController.java index 657a60b9..9039be19 100644 --- a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/RegionController.java +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/RegionController.java @@ -3,6 +3,7 @@ import com.eternalcode.combat.config.implementation.PluginConfig; import com.eternalcode.combat.fight.FightManager; import com.eternalcode.combat.notification.NotificationAnnouncer; +import java.util.Optional; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -44,17 +45,22 @@ void onPlayerMove(PlayerMoveEvent event) { int zFrom = locationFrom.getBlockZ(); if (xTo != xFrom || yTo != yFrom || zTo != zFrom) { - if (!this.regionProvider.isInRegion(locationTo)) { + Optional regionOptional = regionProvider.getRegion(locationTo); + if (regionOptional.isEmpty()) { return; } - Location spawnLocation = this.regionProvider.getRegionCenter(locationTo); - Location playerLocation = player.getLocation().subtract(spawnLocation); - double distance = playerLocation.distance(spawnLocation); - Vector knockback = new Vector(0, 3, 0).multiply(this.pluginConfig.settings.blockedRegionKnockMultiplier / distance); - Vector vector = playerLocation.toVector().add(knockback); + Region region = regionOptional.get(); + Location centerOfRegion = region.getCenter(); + Location subtract = player.getLocation().subtract(centerOfRegion); - player.setVelocity(vector); + Vector knockbackVector = new Vector(subtract.getX(), 0, subtract.getZ()).normalize(); + Vector configuredVector = new Vector( + this.pluginConfig.settings.blockedRegionKnockMultiplier, + 0.5, + this.pluginConfig.settings.blockedRegionKnockMultiplier); + + player.setVelocity(knockbackVector.multiply(configuredVector)); this.announcer.sendMessage(player, this.pluginConfig.messages.cantEnterOnRegion); } diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/RegionProvider.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/RegionProvider.java index ec47f18d..a60c7fe9 100644 --- a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/RegionProvider.java +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/RegionProvider.java @@ -1,11 +1,14 @@ package com.eternalcode.combat.region; +import java.util.Optional; import org.bukkit.Location; public interface RegionProvider { - boolean isInRegion(Location location); + Optional getRegion(Location location); - Location getRegionCenter(Location location); + default boolean isInRegion(Location location) { + return getRegion(location).isPresent(); + } } diff --git a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/WorldGuardRegionProvider.java b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/WorldGuardRegionProvider.java index 9773eeb0..96ecef4b 100644 --- a/eternalcombat-api/src/main/java/com/eternalcode/combat/region/WorldGuardRegionProvider.java +++ b/eternalcombat-api/src/main/java/com/eternalcode/combat/region/WorldGuardRegionProvider.java @@ -1,69 +1,75 @@ package com.eternalcode.combat.region; +import com.eternalcode.combat.config.implementation.PluginConfig; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldguard.WorldGuard; import com.sk89q.worldguard.protection.ApplicableRegionSet; +import com.sk89q.worldguard.protection.flags.Flags; +import com.sk89q.worldguard.protection.flags.StateFlag; import com.sk89q.worldguard.protection.regions.ProtectedRegion; import com.sk89q.worldguard.protection.regions.RegionContainer; import com.sk89q.worldguard.protection.regions.RegionQuery; +import java.util.Optional; +import java.util.TreeSet; import org.bukkit.Location; import java.util.List; public class WorldGuardRegionProvider implements RegionProvider { - private final List regions; + private final RegionContainer regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer(); + private final TreeSet regions = new TreeSet<>(String.CASE_INSENSITIVE_ORDER); + private final PluginConfig pluginConfig; - public WorldGuardRegionProvider(List regions) { - this.regions = regions; + public WorldGuardRegionProvider(List regions, PluginConfig pluginConfig) { + this.regions.addAll(regions); + this.pluginConfig = pluginConfig; } @Override - public boolean isInRegion(Location location) { - return this.regions.stream().anyMatch(region -> this.isInCombatRegion(location, region)); - } - - @Override - public Location getRegionCenter(Location location) { - RegionContainer regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer(); - RegionQuery regionQuery = regionContainer.createQuery(); + public Optional getRegion(Location location) { + RegionQuery regionQuery = this.regionContainer.createQuery(); ApplicableRegionSet applicableRegions = regionQuery.getApplicableRegions(BukkitAdapter.adapt(location)); - double minX = 0; - double maxX = 0; - double minZ = 0; - double maxZ = 0; - for (ProtectedRegion region : applicableRegions.getRegions()) { - BlockVector3 min = region.getMinimumPoint(); - BlockVector3 max = region.getMaximumPoint(); - - if (min.getX() < minX) { - minX = min.getX(); - } - if (max.getX() > maxX) { - maxX = max.getX(); - } - if (min.getZ() < minZ) { - minZ = min.getZ(); - } - if (max.getZ() > maxZ) { - maxZ = max.getZ(); + if (!isCombatRegion(region)) { + continue; } + + return Optional.of(new RegionImpl(location, region)); + } + + return Optional.empty(); + } + + private boolean isCombatRegion(ProtectedRegion region) { + if (this.regions.contains(region.getId())) { + return true; } - double x = (maxX - minX) / 2 + minX; - double z = (maxZ - minZ) / 2 + minZ; + if (this.pluginConfig.settings.shouldPreventPvpRegions) { + StateFlag.State flag = region.getFlag(Flags.PVP); + + if (flag != null) { + return flag.equals(StateFlag.State.DENY); + } + } - return new Location(location.getWorld(), x, location.getY(), z); + return false; } - private boolean isInCombatRegion(Location location, String regionName) { - RegionContainer regionContainer = WorldGuard.getInstance().getPlatform().getRegionContainer(); - RegionQuery regionQuery = regionContainer.createQuery(); - ApplicableRegionSet applicableRegions = regionQuery.getApplicableRegions(BukkitAdapter.adapt(location)); + private record RegionImpl(Location contextLocation, ProtectedRegion region) implements Region { + @Override + public Location getCenter() { + BlockVector3 min = region.getMinimumPoint(); + BlockVector3 max = region.getMaximumPoint(); - return applicableRegions.getRegions().stream().anyMatch(region -> region.getId().equalsIgnoreCase(regionName)); + double x = (double) (min.getX() + max.getX()) / 2; + double z = (double) (min.getZ() + max.getZ()) / 2; + + return new Location(contextLocation.getWorld(), x, contextLocation.getY(), z); + } } + }