diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..f57aeb4 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index 9b70568..89d6deb 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'com.playerblocklife' -version = '2.2.0-1.20.4' +version = '2.2.2-1.20.4' sourceCompatibility = 17 targetCompatibility = 17 diff --git a/build/classes/java/main/com/playerblocklife/ConfigManager.class b/build/classes/java/main/com/playerblocklife/ConfigManager.class index f73650d..c6c466b 100644 Binary files a/build/classes/java/main/com/playerblocklife/ConfigManager.class and b/build/classes/java/main/com/playerblocklife/ConfigManager.class differ diff --git a/build/classes/java/main/com/playerblocklife/GameStateManager.class b/build/classes/java/main/com/playerblocklife/GameStateManager.class index d87fb4e..f356b83 100644 Binary files a/build/classes/java/main/com/playerblocklife/GameStateManager.class and b/build/classes/java/main/com/playerblocklife/GameStateManager.class differ diff --git a/build/classes/java/main/com/playerblocklife/PlayerBlockManager$1.class b/build/classes/java/main/com/playerblocklife/PlayerBlockManager$1.class index ead2c85..57511f5 100644 Binary files a/build/classes/java/main/com/playerblocklife/PlayerBlockManager$1.class and b/build/classes/java/main/com/playerblocklife/PlayerBlockManager$1.class differ diff --git a/build/classes/java/main/com/playerblocklife/PlayerBlockManager.class b/build/classes/java/main/com/playerblocklife/PlayerBlockManager.class index 98f1f54..2205826 100644 Binary files a/build/classes/java/main/com/playerblocklife/PlayerBlockManager.class and b/build/classes/java/main/com/playerblocklife/PlayerBlockManager.class differ diff --git a/build/classes/java/main/com/playerblocklife/PlayerJoinListener.class b/build/classes/java/main/com/playerblocklife/PlayerJoinListener.class index 2e4bfa8..35598fe 100644 Binary files a/build/classes/java/main/com/playerblocklife/PlayerJoinListener.class and b/build/classes/java/main/com/playerblocklife/PlayerJoinListener.class differ diff --git a/build/libs/PlayerBlockLife-2.2.0-1.20.4.jar b/build/libs/PlayerBlockLife-2.2.0-1.20.4.jar index 64bae72..8c0c917 100644 Binary files a/build/libs/PlayerBlockLife-2.2.0-1.20.4.jar and b/build/libs/PlayerBlockLife-2.2.0-1.20.4.jar differ diff --git a/build/libs/PlayerBlockLife-2.2.1-1.20.4.jar b/build/libs/PlayerBlockLife-2.2.1-1.20.4.jar new file mode 100644 index 0000000..c753c0b Binary files /dev/null and b/build/libs/PlayerBlockLife-2.2.1-1.20.4.jar differ diff --git a/build/libs/PlayerBlockLife-2.2.2-1.20.4.jar b/build/libs/PlayerBlockLife-2.2.2-1.20.4.jar new file mode 100644 index 0000000..00b4e26 Binary files /dev/null and b/build/libs/PlayerBlockLife-2.2.2-1.20.4.jar differ diff --git a/build/resources/main/config.yml b/build/resources/main/config.yml index 2d6a867..855f515 100644 --- a/build/resources/main/config.yml +++ b/build/resources/main/config.yml @@ -9,6 +9,12 @@ game: become_spectator: true # 是否启用生命值系统 health_system: true + + # 方块生成设置 + # 生成方块范围(以玩家为中心的半径) + spread_range: 5 + # 生成方块距离玩家的最小距离 + min_distance: 2 # 广播设置 broadcast: diff --git a/build/resources/main/plugin.yml b/build/resources/main/plugin.yml index 42218a3..fad1baf 100644 --- a/build/resources/main/plugin.yml +++ b/build/resources/main/plugin.yml @@ -1,5 +1,5 @@ name: PlayerBlockLife -version: 2.2.0-1.20.4 +version: 2.2.2-1.20.4 main: com.playerblocklife.PlayerBlockLife api-version: 1.20 author: xiaobai diff --git a/build/tmp/compileJava/compileTransaction/stash-dir/GameStateManager.class.uniqueId1 b/build/tmp/compileJava/compileTransaction/stash-dir/GameStateManager.class.uniqueId1 index d87fb4e..d6693bc 100644 Binary files a/build/tmp/compileJava/compileTransaction/stash-dir/GameStateManager.class.uniqueId1 and b/build/tmp/compileJava/compileTransaction/stash-dir/GameStateManager.class.uniqueId1 differ diff --git a/build/tmp/compileJava/compileTransaction/stash-dir/PlayerBlockManager.class.uniqueId10 b/build/tmp/compileJava/compileTransaction/stash-dir/PlayerBlockManager.class.uniqueId10 index 98f1f54..cd0c1e4 100644 Binary files a/build/tmp/compileJava/compileTransaction/stash-dir/PlayerBlockManager.class.uniqueId10 and b/build/tmp/compileJava/compileTransaction/stash-dir/PlayerBlockManager.class.uniqueId10 differ diff --git a/build/tmp/compileJava/previous-compilation-data.bin b/build/tmp/compileJava/previous-compilation-data.bin index a681249..94f412c 100644 Binary files a/build/tmp/compileJava/previous-compilation-data.bin and b/build/tmp/compileJava/previous-compilation-data.bin differ diff --git a/build/tmp/jar/MANIFEST.MF b/build/tmp/jar/MANIFEST.MF index 4561731..201f6b4 100644 --- a/build/tmp/jar/MANIFEST.MF +++ b/build/tmp/jar/MANIFEST.MF @@ -1,4 +1,4 @@ Manifest-Version: 1.0 -Implementation-Version: 2.2.0-alpha-1.20.4 +Implementation-Version: 2.2.1-1.20.4 Main-Class: com.playerblocklife.PlayerBlockLife diff --git a/build/tmp/shadowJar/MANIFEST.MF b/build/tmp/shadowJar/MANIFEST.MF index 5425c53..7cc954f 100644 --- a/build/tmp/shadowJar/MANIFEST.MF +++ b/build/tmp/shadowJar/MANIFEST.MF @@ -1,4 +1,4 @@ Manifest-Version: 1.0 -Implementation-Version: 2.2.0-1.20.4 +Implementation-Version: 2.2.2-1.20.4 Main-Class: com.playerblocklife.PlayerBlockLife diff --git a/gradle.properties b/gradle.properties index 04c8154..a2125a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,5 +5,5 @@ org.gradle.caching=true org.gradle.daemon=true # ???? -pluginVersion=2.2.0-1.20.4 +pluginVersion=2.2.2-1.20.4 mcVersion=1.20.4 \ No newline at end of file diff --git a/src/main/java/com/playerblocklife/AdminCommands.java b/src/main/java/com/playerblocklife/AdminCommands.java index ddea23e..e574a4e 100644 --- a/src/main/java/com/playerblocklife/AdminCommands.java +++ b/src/main/java/com/playerblocklife/AdminCommands.java @@ -23,7 +23,7 @@ import java.util.UUID; *

这些命令在新模式下会与GameStateManager交互,以正确管理游戏状态。

* * @author xiaobai - * @version 2.2.0-1.20.4 + * @version 2.2.2-1.20.4 * @since 1.0.0 */ public class AdminCommands implements CommandExecutor { diff --git a/src/main/java/com/playerblocklife/BlockBreakListener.java b/src/main/java/com/playerblocklife/BlockBreakListener.java index b020cbf..a83bef2 100644 --- a/src/main/java/com/playerblocklife/BlockBreakListener.java +++ b/src/main/java/com/playerblocklife/BlockBreakListener.java @@ -31,7 +31,7 @@ import java.util.UUID; *

此监听器与GameStateManager协作,确保游戏规则正确执行。

* * @author xiaobai - * @version 2.2.0-1.20.4 + * @version 2.2.2-1.20.4 * @since 1.0.0 */ public class BlockBreakListener implements Listener { diff --git a/src/main/java/com/playerblocklife/CheckLifeBlocksCommand.java b/src/main/java/com/playerblocklife/CheckLifeBlocksCommand.java index 207b151..3707c3a 100644 --- a/src/main/java/com/playerblocklife/CheckLifeBlocksCommand.java +++ b/src/main/java/com/playerblocklife/CheckLifeBlocksCommand.java @@ -13,7 +13,7 @@ import org.bukkit.entity.Player; * 与旧模式不同,此命令不再显示生命方块的具体位置,而是提供当前游戏状态信息。

* * @author xiaobai - * @version 2.2.0-1.20.4 + * @version 2.2.2-1.20.4 * @since 1.0.0 */ public class CheckLifeBlocksCommand implements CommandExecutor { diff --git a/src/main/java/com/playerblocklife/ConfigManager.java b/src/main/java/com/playerblocklife/ConfigManager.java index 5a2ee00..88c20a8 100644 --- a/src/main/java/com/playerblocklife/ConfigManager.java +++ b/src/main/java/com/playerblocklife/ConfigManager.java @@ -31,7 +31,7 @@ import java.nio.charset.StandardCharsets; * * * @author xiaobai - * @version 2.2.0-1.20.4 + * @version -1.20.4 * @since 1.0.0 */ public class ConfigManager { @@ -323,6 +323,24 @@ public class ConfigManager { return getConfig().getBoolean("protection.protect_from_pistons", true); } + /** + * 获取方块生成范围(以玩家为中心的半径) + * + * @return 生成范围(方块),默认为5 + */ + public int getSpreadRange() { + return getConfig().getInt("game.spread_range", 5); + } + + /** + * 获取方块生成距离玩家的最小距离 + * + * @return 最小距离(方块),默认为2 + */ + public int getMinDistance() { + return getConfig().getInt("game.min_distance", 2); + } + // 命令启用配置获取方法 diff --git a/src/main/java/com/playerblocklife/GameStateManager.java b/src/main/java/com/playerblocklife/GameStateManager.java index 1176122..17766a6 100644 --- a/src/main/java/com/playerblocklife/GameStateManager.java +++ b/src/main/java/com/playerblocklife/GameStateManager.java @@ -45,7 +45,7 @@ import java.util.UUID; * * * @author xiaobai - * @version 2.2.0-1.20.4 + * @version -1.20.4 * @since 4.0.0 */ public class GameStateManager { @@ -253,7 +253,8 @@ public class GameStateManager { Material color = playerColors.get(player.getUniqueId()); ConfigManager config = plugin.getConfigManager(); int blockAmount = 5; // 使用固定值,因为配置已移除 - int spreadRange = 5; // 使用固定值,因为配置已移除 + int spreadRange = config.getSpreadRange(); // 从配置获取范围 + int minDistance = config.getMinDistance(); // 从配置获取最小距离 List blocks = new ArrayList<>(); int blocksPlaced = 0; @@ -266,6 +267,13 @@ public class GameStateManager { int x = random.nextInt(spreadRange * 2 + 1) - spreadRange; int z = random.nextInt(spreadRange * 2 + 1) - spreadRange; + // 检查与玩家的距离是否满足最小距离要求 + double distance = Math.sqrt(x * x + z * z); + if (distance < minDistance) { + attempts++; + continue; + } + Location testLoc = center.clone().add(x, 0, z); World world = testLoc.getWorld(); if (world == null) continue; @@ -608,6 +616,14 @@ public class GameStateManager { * 重置游戏 */ public void resetGame() { + // 删除世界中所有未被破坏的生命方块(新模式) + removeGameBlocksFromWorld(); + + // 删除旧模式的生命方块 + if (plugin.getBlockManager() != null) { + plugin.getBlockManager().resetGameBlocks(); + } + // 清空所有数据 playerColors.clear(); playerBlocks.clear(); @@ -631,6 +647,33 @@ public class GameStateManager { setCurrentState(GameState.WAITING); } + /** + * 从世界中删除所有游戏生命方块 + */ + private void removeGameBlocksFromWorld() { + // 遍历所有玩家的生命方块位置并将其设置为空气 + for (List blocks : playerBlocks.values()) { + for (Location location : blocks) { + if (location.getWorld() != null) { + Block block = location.getBlock(); + // 只删除生命方块(彩色羊毛、玻璃或混凝土) + if (isLifeBlockMaterial(block.getType())) { + block.setType(Material.AIR); + } + } + } + } + } + + /** + * 检查材料是否为生命方块材料 + */ + private boolean isLifeBlockMaterial(Material material) { + return material.name().endsWith("_WOOL") || + material.name().endsWith("_STAINED_GLASS") || + material.name().endsWith("_CONCRETE"); + } + /** * 获取玩家剩余方块数量 */ diff --git a/src/main/java/com/playerblocklife/LifeSystem.java b/src/main/java/com/playerblocklife/LifeSystem.java index 9589b60..6775405 100644 --- a/src/main/java/com/playerblocklife/LifeSystem.java +++ b/src/main/java/com/playerblocklife/LifeSystem.java @@ -33,7 +33,7 @@ import java.util.UUID; * * * @author xiaobai - * @version 2.2.0 + * @version * @since 1.0.0 */ public class LifeSystem { diff --git a/src/main/java/com/playerblocklife/PBLCommands.java b/src/main/java/com/playerblocklife/PBLCommands.java index 639dd09..70a883a 100644 --- a/src/main/java/com/playerblocklife/PBLCommands.java +++ b/src/main/java/com/playerblocklife/PBLCommands.java @@ -18,7 +18,7 @@ import org.bukkit.entity.Player; *

这些命令仅允许服务器管理员(OP)执行,用于控制PlayerBlockLife游戏的生命周期。

* * @author xiaobai - * @version 2.2.0-1.20.4 + * @version 2.2.2-1.20.4 * @since 4.0.0 */ public class PBLCommands implements CommandExecutor { diff --git a/src/main/java/com/playerblocklife/PlayerBlockLife.java b/src/main/java/com/playerblocklife/PlayerBlockLife.java index a3d4263..9727c90 100644 --- a/src/main/java/com/playerblocklife/PlayerBlockLife.java +++ b/src/main/java/com/playerblocklife/PlayerBlockLife.java @@ -24,7 +24,7 @@ import java.util.logging.Level; * * * @author xiaobai - * @version 2.2.0-1.20.4 + * @version 2.2.2-1.20.4 * @since 1.0.0 */ public class PlayerBlockLife extends JavaPlugin { diff --git a/src/main/java/com/playerblocklife/PlayerBlockManager.java b/src/main/java/com/playerblocklife/PlayerBlockManager.java index 81874e2..4ce2805 100644 --- a/src/main/java/com/playerblocklife/PlayerBlockManager.java +++ b/src/main/java/com/playerblocklife/PlayerBlockManager.java @@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentHashMap; *

使用并发安全的数据结构确保多线程环境下的数据一致性。

* * @author xiaobai - * @version 2.2.0 + * @version 2.2.2 * @since 1.0.0 */ public class PlayerBlockManager { @@ -67,8 +67,10 @@ public class PlayerBlockManager { ConfigManager config = plugin.getConfigManager(); boolean requireOpenSky = true; // 使用默认值,因为配置已移除 int maxAttempts = 50; // 使用默认值,因为配置已移除 + int spreadRange = config.getSpreadRange(); // 从配置获取范围 + int minDistance = config.getMinDistance(); // 从配置获取最小距离 - return generateLifeBlocksForPlayer(player, 5, 5, requireOpenSky, maxAttempts); + return generateLifeBlocksForPlayer(player, 5, spreadRange, minDistance, requireOpenSky, maxAttempts); } /** @@ -96,14 +98,15 @@ public class PlayerBlockManager { * * @param player 目标玩家 * @param blockAmount 要生成的方块数量 - * @param spreadRange 生成范围(以玩家为中心的正方形边长的一半) + * @param spreadRange 生成范围(以玩家为中心的半径) + * @param minDistance 生成方块距离玩家的最小距离 * @param requireOpenSky 是否需要开阔天空(上方无方块覆盖) * @param maxAttempts 寻找合适位置的最大尝试次数 * @return 生成成功返回true,失败返回false * @see SkinManager#isSkinLoaded(UUID) * @see SkinManager#getSkinFromSkinsRestorer(Player) */ - public boolean generateLifeBlocksForPlayer(Player player, int blockAmount, int spreadRange, boolean requireOpenSky, int maxAttempts) { + public boolean generateLifeBlocksForPlayer(Player player, int blockAmount, int spreadRange, int minDistance, boolean requireOpenSky, int maxAttempts) { UUID playerId = player.getUniqueId(); String playerName = player.getName(); @@ -123,7 +126,7 @@ public class PlayerBlockManager { // 尝试生成指定数量的方块 while (blocksPlaced < blockAmount && attempts < maxAttempts) { - Location blockLoc = findSurfaceLocation(player.getLocation(), spreadRange, requireOpenSky); + Location blockLoc = findSurfaceLocation(player.getLocation(), spreadRange, minDistance, requireOpenSky); attempts++; if (blockLoc != null && placePlayerHead(blockLoc, playerId, playerName)) { @@ -148,11 +151,18 @@ public class PlayerBlockManager { /** * 寻找地表位置(放宽条件,只要是露天地面就可以) */ - private Location findSurfaceLocation(Location center, int spreadRange, boolean requireOpenSky) { + private Location findSurfaceLocation(Location center, int spreadRange, int minDistance, boolean requireOpenSky) { for (int i = 0; i < 20; i++) { // 增加尝试次数 int x = random.nextInt(spreadRange * 2 + 1) - spreadRange; int z = random.nextInt(spreadRange * 2 + 1) - spreadRange; + // 检查与玩家的距离是否满足最小距离要求 + double distance = Math.sqrt(x * x + z * z); + if (distance < minDistance) { + // 如果距离太近,重新生成坐标 + continue; + } + // 以玩家坐标为中心,但高度从世界最高点开始寻找 Location testLoc = center.clone().add(x, 0, z); World world = testLoc.getWorld(); @@ -755,6 +765,30 @@ public class PlayerBlockManager { return nearest; } + /** + * 重置游戏时删除所有未被破坏的生命方块 + */ + public void resetGameBlocks() { + // 遍历所有生命方块位置并将其设置为空气 + for (Location location : blockOwners.keySet()) { + if (location.getWorld() != null) { + Block block = location.getBlock(); + // 只删除玩家头颅方块 + if (block.getType() == Material.PLAYER_HEAD || block.getType() == Material.PLAYER_WALL_HEAD) { + block.setType(Material.AIR); + } + } + } + + // 清空内部数据结构 + playerBlocks.clear(); + blockOwners.clear(); + playerBlockTypes.clear(); + + // 保存数据更新 + saveData(); + } + /** * 获取所有生命方块的统计信息 */ diff --git a/src/main/java/com/playerblocklife/PlayerJoinListener.java b/src/main/java/com/playerblocklife/PlayerJoinListener.java index 58198d4..4a726be 100644 --- a/src/main/java/com/playerblocklife/PlayerJoinListener.java +++ b/src/main/java/com/playerblocklife/PlayerJoinListener.java @@ -28,7 +28,7 @@ import java.util.UUID; *

此监听器与GameStateManager协作,确保玩家正确加入PlayerBlockLife游戏模式。

* * @author xiaobai - * @version 2.2.0-1.20.4 + * @version 2.2.2-1.20.4 * @since 1.0.0 */ public class PlayerJoinListener implements Listener { @@ -90,7 +90,7 @@ public class PlayerJoinListener implements Listener { // 调用方块管理器生成方块 boolean success = plugin.getBlockManager().generateLifeBlocksForPlayer( - player, 5, 5, requireOpenSky, maxAttempts + player, 5, config.getSpreadRange(), config.getMinDistance(), requireOpenSky, maxAttempts ); if (success) { diff --git a/src/main/java/com/playerblocklife/PlayerQuitListener.java b/src/main/java/com/playerblocklife/PlayerQuitListener.java index 3a4ba72..c9b61fc 100644 --- a/src/main/java/com/playerblocklife/PlayerQuitListener.java +++ b/src/main/java/com/playerblocklife/PlayerQuitListener.java @@ -11,7 +11,7 @@ import org.bukkit.event.player.PlayerQuitEvent; * 其生命方块状态,因为方块位置信息仅在服务器运行期间维护。

* * @author xiaobai - * @version 2.2.0-1.20.4 + * @version 2.2.2-1.20.4 * @since 1.0.0 */ public class PlayerQuitListener implements Listener { diff --git a/src/main/java/com/playerblocklife/SetLifeBlocksCommand.java b/src/main/java/com/playerblocklife/SetLifeBlocksCommand.java index 58bbed0..0cbd271 100644 --- a/src/main/java/com/playerblocklife/SetLifeBlocksCommand.java +++ b/src/main/java/com/playerblocklife/SetLifeBlocksCommand.java @@ -14,7 +14,7 @@ import org.bukkit.entity.Player; * 玩家应等待管理员使用 /PlayerBlockLife start 命令开始游戏。

* * @author xiaobai - * @version 2.2.0-1.20.4 + * @version 2.2.2-1.20.4 * @since 1.0.0 */ public class SetLifeBlocksCommand implements CommandExecutor { diff --git a/src/main/java/com/playerblocklife/SkinManager.java b/src/main/java/com/playerblocklife/SkinManager.java index 93db8bc..49b8c1d 100644 --- a/src/main/java/com/playerblocklife/SkinManager.java +++ b/src/main/java/com/playerblocklife/SkinManager.java @@ -52,7 +52,7 @@ import java.util.concurrent.ConcurrentHashMap; *

皮肤缓存默认保留7天,过期后自动重新获取。

* * @author xiaobai - * @version 2.2.0 + * @version 2.2.2 * @since 1.0.0 */ public class SkinManager { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2d6a867..855f515 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -9,6 +9,12 @@ game: become_spectator: true # 是否启用生命值系统 health_system: true + + # 方块生成设置 + # 生成方块范围(以玩家为中心的半径) + spread_range: 5 + # 生成方块距离玩家的最小距离 + min_distance: 2 # 广播设置 broadcast: diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 42218a3..fad1baf 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: PlayerBlockLife -version: 2.2.0-1.20.4 +version: 2.2.2-1.20.4 main: com.playerblocklife.PlayerBlockLife api-version: 1.20 author: xiaobai