2.2.2-1.20.4
可以通过配置文件修改方块生成的范围
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有生命方块的统计信息
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user