2.2.2-1.20.4

可以通过配置文件修改方块生成的范围
This commit is contained in:
xiaobai
2026-02-16 19:00:49 +08:00
parent f8c8b1141d
commit 032ef02ec8
33 changed files with 141 additions and 26 deletions

View File

@@ -42,7 +42,7 @@ import java.util.concurrent.ConcurrentHashMap;
* <p>使用并发安全的数据结构确保多线程环境下的数据一致性。</p>
*
* @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();
}
/**
* 获取所有生命方块的统计信息
*/