diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85e7c1d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.idea/ diff --git a/pom.xml b/pom.xml index 90ef713..f498e56 100644 --- a/pom.xml +++ b/pom.xml @@ -13,4 +13,24 @@ 8 + + + public + https://repo.aurora-pixels.com/repository/public/ + + + + + + org.spigotmc + spigot-api + 1.18.2 + + + com.fastasyncworldedit.bukkit + FastAsyncWorldEdit + 1.18.2 + + + \ No newline at end of file diff --git a/src/main/java/me/Demon/BlockWars/Eventi/MinerChangeEvent.java b/src/main/java/me/Demon/BlockWars/Eventi/MinerChangeEvent.java new file mode 100644 index 0000000..35352c8 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Eventi/MinerChangeEvent.java @@ -0,0 +1,40 @@ +package me.Demon.BlockWars.Eventi; + +import me.Demon.BlockWars.Game.GameData; +import me.Demon.BlockWars.Game.Region; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class MinerChangeEvent extends Event { + + private static HandlerList handlers = new HandlerList(); + private final GameData game; + private final Region region; + private final String eventType; + + @Override + public HandlerList getHandlers() { + return handlers; + } + + public static HandlerList getHandlerList() { + return handlers; + } + public MinerChangeEvent(GameData game, Region region,String eventType) { + this.game = game; + this.region = region; + this.eventType = eventType; + } + + public GameData getGame() { + return game; + } + + public Region getRegion() { + return region; + } + + public String getEventType() { + return eventType; + } +} diff --git a/src/main/java/me/Demon/BlockWars/Game/BlockRegion.java b/src/main/java/me/Demon/BlockWars/Game/BlockRegion.java new file mode 100644 index 0000000..bdee2e8 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Game/BlockRegion.java @@ -0,0 +1,27 @@ +package me.Demon.BlockWars.Game; + +public class BlockRegion { + private int minX; + private int maxX; + + public BlockRegion(int minX, int maxX) { + this.minX = minX; + this.maxX = maxX; + } + + public int getMinX() { + return minX; + } + + public int getMaxX() { + return maxX; + } + + @Override + public String toString() { + return "Region{" + + "minX=" + minX + + ", maxX=" + maxX + + '}'; + } +} diff --git a/src/main/java/me/Demon/BlockWars/Game/GameData.java b/src/main/java/me/Demon/BlockWars/Game/GameData.java new file mode 100644 index 0000000..568aa87 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Game/GameData.java @@ -0,0 +1,251 @@ +package me.Demon.BlockWars.Game; + +import com.yaohun.GameGoal.GameGoal; +import com.yaohun.GameGoal.api.GameGoalAPI; +import me.Demon.BlockWars.Main; +import me.Demon.BlockWars.Manager.MinerOperate; +import me.Demon.BlockWars.Util.BossBarUtil; +import me.Demon.BlockWars.Util.ComputeBlock; +import me.Demon.BlockWars.Util.GameUtil; +import org.bukkit.*; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.Boss; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Firework; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +public class GameData { + + private Region region; + private World world; + private static boolean started; + private BossBar bossBar1; + private BossBar bossBar2; + private BossBar bossBar3; + private List blockRegionList = new ArrayList<>(); + private int totalBlockAmount = 0; // 当前矿坑中的方块数量 + private int completeBlockGoal = 0; + private List tasks = new ArrayList<>(); + private boolean checking; // 挑战成功 + private int countdownTime = 15; // 挑战成功倒计时 + + public GameData(){ + countdownTime = Main.configYml.getCountdownTime(); // 设置倒计时时间 + bossBar1 = Bukkit.createBossBar("今日挑战进度", BarColor.WHITE, BarStyle.SEGMENTED_10); + bossBar2 = Bukkit.createBossBar("填充进度", BarColor.GREEN, BarStyle.SEGMENTED_20); + bossBar3 = Bukkit.createBossBar("掉炸弹", BarColor.RED, BarStyle.SOLID); + } + + public void updateBossBar(){ + refreshCompleteBossBar(); + refreshGiveALikeEffect(); + } + + // 刷新今日挑战进度 + public void refreshCompleteBossBar() { + int a = GameGoalAPI.getNowcompleteAmount(); // 当前已完成挑战次数 + int b = GameGoalAPI.getCompleteAmount(); // 需要完成多少挑战次数 + double percent = (double) a / (double) b; + if (a < 0) { + bossBar1.setTitle("§6今日挑战进度: §4" + a + "§f/" + b); + } else { + bossBar1.setTitle("§6今日挑战进度: §f" + a + "/" + b); + } + BossBarUtil.setBarProgress(bossBar1,percent); + BossBarUtil.setBarColor(bossBar1,percent); + } + + public void refreshGiveALikeEffect(){ + int a = this.totalBlockAmount; + int b = this.completeBlockGoal; + double percent = (double) a / (double) b; + System.out.println("[调试 - 进度] 填充进度: "+a+" b = "+b); + String percentShow = String.format("%.2f", (percent * 100)); + bossBar2.setTitle("§6填充进度: §f"+a+"/"+b+" §9("+percentShow+"%)"); + System.out.println("[调试 - 进度] 填充进度: "+percent); + BossBarUtil.setBarProgress(bossBar2,percent); + BossBarUtil.setBarColor(bossBar2,percent); + } + + public void startGame(){ + if(isStarted()){return;} + setStarted(true); + initializeGameData(); // 初始化游戏参数 + GameUtil.ClearWorldEntity(); // 清理世界所有生物 + for (Player player : Bukkit.getOnlinePlayers()) { + initializePlayerData(player); // 初始化玩家数据 + } + // 初始化主播参数 + tasks.add(new BukkitRunnable() { + @Override + public void run() { + totalBlockAmount = ComputeBlock.getCompleteBlockAmount(blockRegionList); // 每秒刷新一次矿区方块数量 + updateBossBar(); + if (!checking) { + checkComplete(); // 检测玩家当前挑战完成进度 + } + } + }.runTaskTimer(Main.plugin, 0L, 20L)); + } + public void initializeGameData(){ + String worldName = "world"; + this.world = Bukkit.getWorld(worldName); + if(world != null) { + world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false); + world.setGameRule(GameRule.DO_MOB_LOOT, false); + world.setGameRule(GameRule.DO_MOB_SPAWNING, false); + world.setGameRule(GameRule.DISABLE_ELYTRA_MOVEMENT_CHECK, true); + world.setTime(6000); + } + GameGoalAPI.setNowCompleteAmount(0); // 初始化游戏进度 + this.checking = false; + GameUtil.loadSchematics("miner_11x11"); // 初始化矿区模板 + MinerOperate.initializeMinerSize(); // 初始化矿区大小 + updateBossBar(); + } + /* + * 初始化主播游戏参数: 生命值、物品栏、BossBar、当前位置 + * */ + public void initializePlayerData(Player player){ + player.getInventory().clear(); + Inventory inv = player.getInventory(); + for (int i = 0;i < 27;i++){ + inv.setItem(i,new ItemStack(Material.IRON_BLOCK)); + } + player.teleport(region.getHub()); + // 添加boss血条 + BossBarUtil.addBossBar(player,new ArrayList<>(Arrays.asList(bossBar1,bossBar2))); + } + + private int countdown; // 当前倒计时 + + public void checkComplete() { + if (checking) { + return; + } + if (this.totalBlockAmount >= completeBlockGoal) { + checking = true; + countdown = 0; + tasks.add(new BukkitRunnable() { + @Override + public void run() { + if (totalBlockAmount < completeBlockGoal) { + cancel(); + stopBukkitTaskList(); // 清理TaskList 并关闭 + checking = false; + Bukkit.broadcastMessage("§c[系统]§a弹坑出现缺口,需要进行填充."); + for (Player player : Bukkit.getOnlinePlayers()) { + player.sendTitle("§c哎呀!", "§6继续加油!"); + player.playSound(player.getLocation(), "niganma", 1.0F, 1.0F); + } + return; + } + if (countdown >= countdownTime) { + BukkitTask task = new BukkitRunnable() { + private int i = 0; + + @Override + public void run() { + if (i >= 100) { + cancel(); + return; + } + region.getWorld().setTime(region.getWorld().getTime() + 480L); + i++; + } + }.runTaskTimer(Main.plugin, 0L, 1L); + tasks.add(task); + GameGoalAPI.addNowCompleteAmount(1); + stopBukkitTaskList(); // 清理TaskList 并关闭 + checking = false; + Bukkit.broadcastMessage("§c[系统]§a挑战成功! §b游戏进度+1"); + for (Player player : Bukkit.getOnlinePlayers()) { + player.playSound(player.getLocation(), "duolaameng", 1.0F, 1.0F); + player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 1.0f, 1.1f); + } + MinerOperate.clearMinerAll(blockRegionList); // 清理矿区中所有方块 + return; + } + countdown++; + int daojishi = Main.configYml.getCountdownTime(); + for (Player player : Bukkit.getOnlinePlayers()) { + player.sendTitle("§6§l" + (daojishi - countdown), "§6即将挑战成功!"); + } + for (Player player : Bukkit.getOnlinePlayers()) { + player.playSound(player.getLocation(), "daojishi", 1.0f, 1.0f); + } + } + }.runTaskTimer(Main.plugin, 0L, 20L)); + Bukkit.broadcastMessage("§c[系统]§a若§6" + countdownTime + "秒§a内弹坑未出现缺口则挑战成功!"); + } + } + + /* + * 清理 BukkitTask 缓存 + * */ + public void stopBukkitTaskList(){ + for (BukkitTask runnable : tasks){ + runnable.cancel(); + } + tasks.clear(); + } + + + /* + * 当游戏矿区发生变化时需要调用一次这个事件!!! + * */ + public void refreshBlockRgionList(int chunkSize){ + BlockRegion originalRegion = new BlockRegion((int) region.getMin().getX(), (int) region.getMax().getX()); + List blockRegions = new ArrayList<>(); + int min = (int) originalRegion.getMinX(); + int max = (int) originalRegion.getMaxX(); + if(max - min <= chunkSize){ + blockRegions.add(originalRegion); + }else{ + for (int x = min; x < max; x += chunkSize) { + int newMax = Math.min(x + chunkSize, max); + blockRegions.add(new BlockRegion(x, newMax)); + } + } + this.blockRegionList = blockRegions; + } + + public List getBlockRegionList() { + return blockRegionList; + } + public Region getRegion() { + return region; + } + + public void setRegion(Region region) { + this.region = region; + } + + public World getWorld() { + return world; + } + + public boolean isStarted() { + return started; + } + + public void setStarted(boolean started) { + GameData.started = started; + } + + public void setCompleteBlockGoal(int completeBlockGoal) { + this.completeBlockGoal = completeBlockGoal; + } +} diff --git a/src/main/java/me/Demon/BlockWars/Game/Point.java b/src/main/java/me/Demon/BlockWars/Game/Point.java new file mode 100644 index 0000000..8782c9d --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Game/Point.java @@ -0,0 +1,97 @@ +package me.Demon.BlockWars.Game; + +import com.sk89q.worldedit.math.BlockVector3; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.Objects; + +public class Point { + + private double x; + private double y; + private double z; + + public Point(int x, int y, int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Point(double x, double y, double z) { + this.x = x; + this.y = y; + this.z = z; + } + + public double getX() { + return x; + } + + public double getY() { + return y; + } + + public double getZ() { + return z; + } + + public void setX(double x) { + this.x = x; + } + + public void setY(double y) { + this.y = y; + } + + public void setZ(double z) { + this.z = z; + } + + public Point clone() { + return new Point(x, y, z); + } + + public Location toLocation(World world) { + return new Location(world, x, y, z, 0, 0); + } + + public static Point of(Location location) { + return new Point(location.getX(), location.getY(), location.getZ()); + } + + public static Point deserialize(ConfigurationSection section) { + return new Point(section.getDouble("x"), section.getDouble("y"), section.getDouble("z")); + } + public static Point deserialize(double x,double y,double z) { + return new Point(x, y, z); + } + + public BlockVector3 toBlockVector3() { + return BlockVector3.at(x, y, z); + } + + @Override + public String toString() { + return "Point{" + + "x=" + x + + ", y=" + y + + ", z=" + z + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Point point = (Point) o; + return Double.compare(point.x, x) == 0 && Double.compare(point.y, y) == 0 && Double.compare(point.z, z) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(x, y, z); + } + +} diff --git a/src/main/java/me/Demon/BlockWars/Game/Region.java b/src/main/java/me/Demon/BlockWars/Game/Region.java new file mode 100644 index 0000000..12081fb --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Game/Region.java @@ -0,0 +1,110 @@ +package me.Demon.BlockWars.Game; + +import me.Demon.BlockWars.Main; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; + +public class Region { + + private World world; + private Point min; + private Point max; + + public Region(World world, Point min, Point max) { + this.world = world; + this.min = min; + this.max = max; + } + + public Location getHub(){ + double z = (min.getZ() + max.getZ()) / 2; + double y = min.getY(); + if(max.getY() > y){ + y = max.getY(); + } + int backhub = Main.configYml.getGameSettings("backhub"); + if(backhub == 1){ + double x = (max.getX() - 1); + return new Location(world,x,(y+5),z,90,90); + }else if(backhub == 2){ + double x = (min.getX() + 1); + return new Location(world,x,(y+5),z,-90,90); + } + double x = (min.getX() + max.getX()) / 2; + return new Location(world,x,(y+5),z,-90,90); + } + /*public Location getHub(){ + double x = (min.getX() + max.getX()) / 2; + double z = (min.getZ() + max.getZ()) / 2; + double y = min.getY(); + if(max.getY() > y){ + y = max.getY(); + } + return new Location(world,x,(y+10 ),z,90,0); + }*/ + + public World getWorld() { + return world; + } + + public Point getMin() { + return min; + } + + public Point getMax() { + return max; + } + + public void setMax(Point max) { + this.max = max; + } + + public void setMin(Point min) { + this.min = min; + } + + public static Region deserialize(ConfigurationSection section) { + World world1 = Bukkit.getWorld(section.getString("world")); + Point point1 = Point.deserialize(section.getConfigurationSection("min")); + Point point2 = Point.deserialize(section.getConfigurationSection("max")); + return new Region(world1, point1, point2); + } + public static Region deserialize(String worldName,Point point_min,Point point_max) { + World world1 = Bukkit.getWorld(worldName); + return new Region(world1,point_min,point_max); + } + + public boolean isInRegion(Location location) { + if (!location.getWorld().getName().equalsIgnoreCase(world.getName())) { + return false; + } + return (location.getBlockX() >= this.min.getX() + && location.getBlockX() <= this.max.getX() + && location.getBlockY() >= this.min.getY() + && location.getBlockY() <= this.max.getY() + && location.getBlockZ() >= this.min.getZ() + && location.getBlockZ() <= this.max.getZ()); + } + public boolean isInBreakRegion(Location location) { + if (!location.getWorld().getName().equalsIgnoreCase(world.getName())) { + return false; + } + return (location.getBlockX() >= (this.min.getX()-5) + && location.getBlockX() <= (this.max.getX()+5) + && location.getBlockZ() >= (this.min.getZ()-5) + && location.getBlockZ() <= (this.max.getZ()+5)); + } + public boolean isInRegionPlayer(Location location) { + if (!location.getWorld().getName().equalsIgnoreCase(world.getName())) { + return false; + } + return (location.getBlockX() >= this.min.getX() + && location.getBlockX() <= this.max.getX() + && location.getBlockY() >= this.min.getY() + && location.getBlockZ() >= this.min.getZ() + && location.getBlockZ() <= this.max.getZ()); + } + +} diff --git a/src/main/java/me/Demon/BlockWars/Listener/GameListener.java b/src/main/java/me/Demon/BlockWars/Listener/GameListener.java new file mode 100644 index 0000000..3f8ebf6 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Listener/GameListener.java @@ -0,0 +1,228 @@ +package me.Demon.BlockWars.Listener; + +import cn.hamster3.cdapi.CDTimeAPI; +import me.Demon.BlockWars.Game.Region; +import me.Demon.BlockWars.Main; +import me.Demon.BlockWars.Util.GameUtil; +import org.bukkit.*; +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockExplodeEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerPickupItemEvent; +import org.bukkit.event.player.PlayerSwapHandItemsEvent; +import org.bukkit.event.server.ServerListPingEvent; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitRunnable; + +import java.util.Iterator; + +/* +* GameListener +* 用途: 游戏中搭方块、禁止破坏、tnt保护 +* +* */ +public class GameListener implements Listener { + + @EventHandler + public void onPing(ServerListPingEvent e){ + if (Main.gameData.isStarted()) { + e.setMotd("§a整蛊模式: §6TNT填充 §a当前版本: §6常规版 §b运行中"); + }else{ + e.setMotd("§a整蛊模式: §6TNT填充 §a当前版本: §6常规版 §c未运行"); + } + } + + @EventHandler + public void onSwap(PlayerSwapHandItemsEvent e) { + Player p = e.getPlayer(); + e.setCancelled(true); + if (!p.isSneaking()) { + p.addPotionEffect(new PotionEffect(PotionEffectType.FAST_DIGGING, 20 * 60, 0,false,false)); + p.addPotionEffect(new PotionEffect(PotionEffectType.SPEED, 20 * 60, 2,false,false)); + long anti_spawn = CDTimeAPI.getCD(p.getUniqueId(),"anti_spawn"); + if(anti_spawn < 1) { + p.teleport(Main.gameData.getRegion().getHub()); + }else{ + double time = (double) (anti_spawn / 1000); + p.sendMessage("§c[系统]§a整蛊效果生效中...§e"+String.format("%.1f",time)+"秒§a才能传送."); + p.teleport(p.getLocation().add(0,100,0)); + } + } + } + + /* + * 若玩家是创造模式没有SHIFT蹲下的情况下会切换成观察者模式 + * */ + @EventHandler + public void onPick(PlayerDropItemEvent e){ + Player p = e.getPlayer(); + if (Main.gameData.isStarted()) { + if(p.isSneaking()){ + // RepairGiftGui.OpenGui(p); + } else { + if (p.getGameMode() == GameMode.CREATIVE) { + p.setGameMode(GameMode.SPECTATOR); + } + } + e.setCancelled(true); + } + } + + /* + * 若玩家是观察者模式 任意交互均可切换回创造模式 + * */ + @EventHandler + public void onUse(PlayerInteractEvent e){ + Player p = e.getPlayer(); + if (Main.gameData.isStarted()) { + if (p.getGameMode() == GameMode.SPECTATOR) { + p.setGameMode(GameMode.CREATIVE); + } + } + } + + /* + * 禁止破坏游戏区域外的方块 + * */ + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + Block block = event.getBlock(); + if (Main.gameData.isStarted()) { + Region region = Main.gameData.getRegion(); + if (region.isInRegionPlayer(block.getLocation())) { + event.setCancelled(false); + }else if(region.isInBreakRegion(block.getLocation())){ + event.setCancelled(true); + } + } + } + + /* + * 启动快速搭建方块 + * */ + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) { + Player p = event.getPlayer(); + World world = p.getWorld(); + Block block = event.getBlockPlaced(); + if (Main.gameData.isStarted()) { + Region region = Main.gameData.getRegion(); + if (region.isInRegion(block.getLocation())) { + boolean sounds_butt = Main.configYml.isGameSettings("placesounds"); + if(Main.configYml.isGameSettings("speedplace")) { + if (!isPlaceNextBlock(block)) { + GameUtil.refreshPlayerHandStack(p); + if(sounds_butt) { + p.playSound(p.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_PLACE, 1.0F, 1.0F); + } + return; + } + Location location = block.getLocation(); + int indexY = location.getBlockY(); + for (int y = (int) region.getMin().getY(); y < indexY; y++) { + Block block2 = location.getWorld().getBlockAt(location.getBlockX(), y, location.getBlockZ()); + if (block2.getType().equals(Material.AIR)) { + indexY = y; + break; + } + } + event.setCancelled(true); + int a = 1; + for (int place_y = indexY; place_y <= (indexY+2); place_y++) { + int finalPlace_y = place_y; + new BukkitRunnable() { + @Override + public void run() { + Block block1 = world.getBlockAt(location.getBlockX(), finalPlace_y, location.getBlockZ()); + if (block1.getType().equals(Material.AIR)) { + if (sounds_butt) { + p.playSound(p.getLocation(), Sound.BLOCK_METAL_PLACE, 1.0F, 1.0F); + p.playSound(p.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_PLACE, 1.0F, 1.0F); + } + cancel(); + } + } + }.runTaskLater(Main.plugin, a); + a++; + } + GameUtil.refreshPlayerHandStack(p); + }else{ + if(sounds_butt) { + p.playSound(p.getLocation(), Sound.BLOCK_AMETHYST_BLOCK_PLACE, 1.0F, 1.0F); + } + } + } else if(Main.gameData.getRegion().isInBreakRegion(block.getLocation())){ + event.setCancelled(true); + } + } + } + /* + * 检测方块下方是否是空气 + * */ + public boolean isPlaceNextBlock(Block block){ + Location location = block.getLocation(); + int indexY = location.getBlockY(); + Block block_next = location.getWorld().getBlockAt(location.getBlockX(), indexY-1, location.getBlockZ()); + if (block_next.getType().equals(Material.AIR)) { + return true; + } + return false; + } + + /* + * 当发生爆炸时检测被炸方块是否有保护 + * */ + @EventHandler + public void onBlockExplode(BlockExplodeEvent event) { + if (Main.gameData.isStarted()) { + Iterator iterator = event.blockList().iterator(); + while (iterator.hasNext()) { + Block block = iterator.next(); + if (Main.gameData.getRegion().isInRegion(block.getLocation())) { + block.breakNaturally(); + }else if(!Main.gameData.getRegion().isInBreakRegion(block.getLocation())){ + block.breakNaturally(); + } + iterator.remove(); + } + } + } + /* + * 当发生爆炸时检测被炸方块是否有保护 + * */ + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (Main.gameData.isStarted()) { + Iterator iterator = event.blockList().iterator(); + while (iterator.hasNext()) { + Block block = iterator.next(); + if (Main.gameData.getRegion().isInRegion(block.getLocation())) { + block.breakNaturally(); + }else if(!Main.gameData.getRegion().isInBreakRegion(block.getLocation())){ + block.breakNaturally(); + } + iterator.remove(); + } + } + } + + /* + * 拾取任何物品不进入背包直接清理 + * */ + @EventHandler + public void onPick(PlayerPickupItemEvent e){ + Player p = e.getPlayer(); + p.playSound(p.getLocation(), Sound.ENTITY_ITEM_PICKUP,1,1); + e.setCancelled(true); + e.getItem().remove(); + } +} diff --git a/src/main/java/me/Demon/BlockWars/Listener/GamePotect.java b/src/main/java/me/Demon/BlockWars/Listener/GamePotect.java new file mode 100644 index 0000000..2f813f2 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Listener/GamePotect.java @@ -0,0 +1,99 @@ +package me.Demon.BlockWars.Listener; + +import me.Demon.BlockWars.Main; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; +import org.bukkit.event.block.BlockBurnEvent; +import org.bukkit.event.block.BlockIgniteEvent; +import org.bukkit.event.entity.*; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.event.weather.WeatherChangeEvent; + +/* +* GamePotect +* 用途: 保护游戏世界 +* */ +public class GamePotect implements Listener { + + @EventHandler/*禁止史莱姆分裂*/ + public void onSlimeSplit(SlimeSplitEvent event) { + event.setCancelled(true); + } + + @EventHandler /*保护农作物免踩踏*/ + public void onJumpFarm(PlayerInteractEvent e){ + if (e.isCancelled()) {return;} + if(e.getAction() == Action.PHYSICAL){ + Block block = e.getClickedBlock(); + if(block.getType() == Material.FARMLAND){ + e.setCancelled(true); + } + } + } + + @EventHandler /*保护农作物免踩踏*/ + public void onMobsFarm(EntityInteractEvent e){ + if (e.isCancelled()) {return;} + if(e.getEntityType() != EntityType.PLAYER){ + Block block = e.getBlock(); + if(block.getType() == Material.FARMLAND){ + e.setCancelled(true); + } + } + } + + @EventHandler /*生物免摔落伤害*/ + public void onAntiFall(EntityDamageEvent event) { + if(event.getEntity() instanceof Player){ + event.setDamage(0); + } + if (event.getCause().equals(EntityDamageEvent.DamageCause.FALL)) { + event.setCancelled(true); + } + if(event.getEntityType() == EntityType.PIG) { + if(Main.configYml.isGameSettings("pigkills")) { + if (event.getCause() != EntityDamageEvent.DamageCause.ENTITY_ATTACK) { + event.setDamage(0); + } + } + } + } + @EventHandler + public void onEntityCombust(EntityCombustEvent event) { + if (event.getEntity() instanceof LivingEntity) { + event.setCancelled(true); // 取消生物燃烧 + + } + } + + @EventHandler + public void onEntityDamageByBlock(EntityDamageByBlockEvent event) { + if (event.getEntity() instanceof LivingEntity) { + if(event.getDamager() != null) { + if (event.getDamager().getType().name().contains("MAGMA")) { + event.setCancelled(true); + } + } + } + } + + @EventHandler(priority= EventPriority.HIGH) + public void onWeatherChange(WeatherChangeEvent e) { + e.setCancelled(true); + } + @EventHandler/*禁止火焰传播*/ + public void onBlockFire(BlockBurnEvent e) { + e.setCancelled(true); + } + @EventHandler/*禁止火焰点燃物品*/ + public void onBlockIgnite(BlockIgniteEvent e) { + e.setCancelled(true); + } +} diff --git a/src/main/java/me/Demon/BlockWars/Listener/JoinEvent.java b/src/main/java/me/Demon/BlockWars/Listener/JoinEvent.java new file mode 100644 index 0000000..724d007 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Listener/JoinEvent.java @@ -0,0 +1,30 @@ +package me.Demon.BlockWars.Listener; + +import me.Demon.BlockWars.Game.GameData; +import me.Demon.BlockWars.Main; +import org.bukkit.GameMode; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.scheduler.BukkitRunnable; + +public class JoinEvent implements Listener { + + @EventHandler(priority= EventPriority.HIGHEST) + public void onJoinItems(PlayerJoinEvent e) { + Player p = e.getPlayer(); + p.setGameMode(GameMode.CREATIVE); + new BukkitRunnable() { + public void run() { + GameData game = Main.gameData; + if(!game.isStarted()) { + game.startGame(); + } + game.initializePlayerData(p); + cancel(); + } + }.runTaskLater(Main.plugin, 20L); + } +} diff --git a/src/main/java/me/Demon/BlockWars/Listener/MinerChange.java b/src/main/java/me/Demon/BlockWars/Listener/MinerChange.java new file mode 100644 index 0000000..338131f --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Listener/MinerChange.java @@ -0,0 +1,16 @@ +package me.Demon.BlockWars.Listener; + +import me.Demon.BlockWars.Eventi.MinerChangeEvent; +import me.Demon.BlockWars.Game.GameData; +import me.Demon.BlockWars.Main; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; + +public class MinerChange implements Listener { + + @EventHandler + public void onChange(MinerChangeEvent e){ + GameData gameData = e.getGame(); + gameData.refreshBlockRgionList(16); + } +} diff --git a/src/main/java/me/Demon/BlockWars/Main.java b/src/main/java/me/Demon/BlockWars/Main.java index 1efb98a..84abcc9 100644 --- a/src/main/java/me/Demon/BlockWars/Main.java +++ b/src/main/java/me/Demon/BlockWars/Main.java @@ -1,4 +1,47 @@ package me.Demon.BlockWars; -public class Main { +import me.Demon.BlockWars.Game.GameData; +import me.Demon.BlockWars.Listener.GameListener; +import me.Demon.BlockWars.Listener.GamePotect; +import me.Demon.BlockWars.Listener.JoinEvent; +import me.Demon.BlockWars.Listener.MinerChange; +import me.Demon.BlockWars.Manager.MinerOperate; +import me.Demon.BlockWars.Util.ConfigYml; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.plugin.java.JavaPlugin; + +public class Main extends JavaPlugin { + + public static boolean Debug = true; + public static Main plugin; + public static GameData gameData; + public static ConfigYml configYml; + + + @Override + public void onEnable() { + plugin = this; + saveDefaultConfig(); + configYml = new ConfigYml(); + gameData = new GameData(); + + getServer().getPluginManager().registerEvents(new JoinEvent(),this); + getServer().getPluginManager().registerEvents(new MinerChange(),this); + getServer().getPluginManager().registerEvents(new GamePotect(),this); + getServer().getPluginManager().registerEvents(new GameListener(),this); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String Command, String[] args) { + if (Command.equalsIgnoreCase("game")) { + if(args[0].equalsIgnoreCase("test1")){ + MinerOperate.clearMinerAll(Main.gameData.getBlockRegionList()); + } + if(args[0].equalsIgnoreCase("test2")){ + MinerOperate.fillMinerAll(Main.gameData.getBlockRegionList()); + } + } + return false; + } } diff --git a/src/main/java/me/Demon/BlockWars/Manager/MinerOperate.java b/src/main/java/me/Demon/BlockWars/Manager/MinerOperate.java new file mode 100644 index 0000000..c573fd8 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Manager/MinerOperate.java @@ -0,0 +1,83 @@ +package me.Demon.BlockWars.Manager; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.regions.CuboidRegion; +import me.Demon.BlockWars.Game.BlockRegion; +import me.Demon.BlockWars.Game.GameData; +import me.Demon.BlockWars.Game.Point; +import me.Demon.BlockWars.Game.Region; +import me.Demon.BlockWars.Main; +import me.Demon.BlockWars.Util.ComputeBlock; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; + +public abstract class MinerOperate { + + /* + * 初始化矿区大小 + * */ + public static void initializeMinerSize() { + int min_minerY = 10; + int max_minerY = 18; + GameData gameData = Main.gameData; + Region region = new Region(Bukkit.getWorld("world"),new Point(103,min_minerY,-6),new Point(113, max_minerY, 4)); + gameData.setRegion(region); + gameData.setCompleteBlockGoal(ComputeBlock.getCompleteBlockGoal(region)); + } + public static void clearMinerAll(List blockRegionList){ + World world = Main.gameData.getWorld(); + Material material = Material.AIR; + for (BlockRegion blockRegion : blockRegionList) { + CompletableFuture.runAsync(() -> { + long startTime = System.currentTimeMillis(); // 记录开始时间 + int minX = blockRegion.getMinX(); + int maxX = blockRegion.getMaxX(); + CuboidRegion cuboidRegion = ComputeBlock.getCuboidRegion(minX,maxX); + try (EditSession editSession = WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(world))) { + // 在编辑会话中设置长方体区域内的所有方块为指定的材质 + editSession.setBlocks((com.sk89q.worldedit.regions.Region) cuboidRegion, BukkitAdapter.asBlockType(material)); + } catch (Exception e) { + // 捕获并打印任何可能发生的异常 + e.printStackTrace(); + } + if(Main.Debug) { + long endTime = System.currentTimeMillis(); // 记录结束时间 + long duration = endTime - startTime; // 计算耗时 + System.out.println("[调试 - 清理] 本次清理所有方块总计耗时 " + duration + " ms"); + } + }); + } + } + + public static void fillMinerAll(List blockRegionList){ + World world = Main.gameData.getWorld(); + Material material = Material.DIAMOND_BLOCK; + for (BlockRegion blockRegion : blockRegionList) { + CompletableFuture.runAsync(() -> { + long startTime = System.currentTimeMillis(); // 记录开始时间 + int minX = blockRegion.getMinX(); + int maxX = blockRegion.getMaxX(); + CuboidRegion cuboidRegion = ComputeBlock.getCuboidRegion(minX,maxX); + try (EditSession editSession = WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(world))) { + // 在编辑会话中设置长方体区域内的所有方块为指定的材质 + editSession.setBlocks((com.sk89q.worldedit.regions.Region) cuboidRegion, BukkitAdapter.asBlockType(material)); + } catch (Exception e) { + // 捕获并打印任何可能发生的异常 + e.printStackTrace(); + } + if(Main.Debug) { + long endTime = System.currentTimeMillis(); // 记录结束时间 + long duration = endTime - startTime; // 计算耗时 + System.out.println("[调试 - 修复] 本次修复所有方块总计耗时 " + duration + " ms"); + } + }); + } + } +} diff --git a/src/main/java/me/Demon/BlockWars/Util/BossBarUtil.java b/src/main/java/me/Demon/BlockWars/Util/BossBarUtil.java new file mode 100644 index 0000000..df8f53e --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Util/BossBarUtil.java @@ -0,0 +1,40 @@ +package me.Demon.BlockWars.Util; + +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BossBar; +import org.bukkit.entity.Player; + +import java.util.List; + +public class BossBarUtil { + + public static void setBarColor(BossBar bossBar,double percent){ + if (percent >= 0 && percent <= 0.3333) { + bossBar.setColor(BarColor.RED); + } else if (percent <= 0.6666) { + bossBar.setColor(BarColor.YELLOW); + } else { + bossBar.setColor(BarColor.GREEN); + } + } + public static void setBarProgress(BossBar bossBar,double percent){ + if (percent <= 0) { + percent = 0; + } else if (percent >= 1) { + percent = 1; + } + bossBar.setProgress(percent); + } + + public static void addBossBar(Player player, List bossBarList){ + for (BossBar bossBar : bossBarList) { + bossBar.addPlayer(player); + } + } + + public static void removeBossBar(Player player,List bossBarList){ + for (BossBar bossBar : bossBarList) { + bossBar.removePlayer(player); + } + } +} diff --git a/src/main/java/me/Demon/BlockWars/Util/ComputeBlock.java b/src/main/java/me/Demon/BlockWars/Util/ComputeBlock.java new file mode 100644 index 0000000..cc760b5 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Util/ComputeBlock.java @@ -0,0 +1,73 @@ +package me.Demon.BlockWars.Util; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import me.Demon.BlockWars.Game.BlockRegion; +import me.Demon.BlockWars.Game.Region; +import me.Demon.BlockWars.Main; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; + +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; + +public class ComputeBlock { + + public static int getCompleteBlockAmount(List blockRegionList){ + AtomicInteger totalBlockAmount = new AtomicInteger(0); + for (BlockRegion blockRegion : blockRegionList) { + CompletableFuture.runAsync(() -> { + long startTime = System.currentTimeMillis(); // 记录开始时间 + int minX = blockRegion.getMinX(); + int maxX = blockRegion.getMaxX(); + CuboidRegion cuboidRegion = getCuboidRegion(minX,maxX); + int airCount = countAirBlocks(cuboidRegion); // 计算 AIR 方块数量 + totalBlockAmount.addAndGet(airCount); // 线程安全地累加 AIR 方块数量 + if(Main.Debug) { + long endTime = System.currentTimeMillis(); // 记录结束时间 + long duration = endTime - startTime; // 计算耗时 + System.out.println("[调试 - 统计] 本次统计所有方块总计耗时 " + duration + " ms"); + } + }); + } + return totalBlockAmount.intValue(); + } + + public static int countAirBlocks(CuboidRegion cuboidRegion) { + World world = Main.gameData.getWorld(); + int blockCount = 0; + for (int y = cuboidRegion.getMinimumPoint().getBlockY(); y <= cuboidRegion.getMaximumPoint().getBlockY(); y++) { + for (int x = cuboidRegion.getMinimumPoint().getBlockX(); x <= cuboidRegion.getMaximumPoint().getBlockX(); x++) { + for (int z = cuboidRegion.getMinimumPoint().getBlockZ(); z <= cuboidRegion.getMaximumPoint().getBlockZ(); z++) { + Block block = world.getBlockAt(x, y, z); + if (!block.getType().equals(Material.AIR)) { + blockCount++; + } + } + } + } + return blockCount; + } + + public static CuboidRegion getCuboidRegion(int minX, int maxX){ + Region region = Main.gameData.getRegion(); + BlockVector3 vector1 = BlockVector3.at(minX, region.getMin().getY(), region.getMin().getZ()); + BlockVector3 vector2 = BlockVector3.at(maxX, region.getMax().getY(), region.getMax().getZ()); + return new CuboidRegion(BukkitAdapter.adapt(region.getWorld()), vector1, vector2); + } + + /* + * 每次矿区大小发生变化时需要调用一次!!!! + * */ + public static int getCompleteBlockGoal(Region region){ + int x = (int) Math.floor(region.getMax().getX()) - (int) Math.floor(region.getMin().getX()) + 1; + int y = (int) Math.floor(region.getMax().getY()) - (int) Math.floor(region.getMin().getY()) + 1; + int z = (int) Math.floor(region.getMax().getZ()) - (int) Math.floor(region.getMin().getZ()) + 1; + return x * y * z; + } +} diff --git a/src/main/java/me/Demon/BlockWars/Util/ConfigYml.java b/src/main/java/me/Demon/BlockWars/Util/ConfigYml.java new file mode 100644 index 0000000..01de7bc --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Util/ConfigYml.java @@ -0,0 +1,121 @@ +package me.Demon.BlockWars.Util; + +import me.Demon.BlockWars.Main; +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ConfigYml { + private String minersize; + private int countdownTime; + private int circularMax; + private int heightMax; + private int completeAmount; + private int dianzan_amount; + private int dianzan_need; + private String dianzan_event; + private HashMap> randonBoxList = new HashMap<>(); + private HashMap gameSettings = new HashMap<>(); + public ConfigYml(){ + this.dianzan_amount = 0; + FileConfiguration settings_yml = Main.plugin.getConfig(); + this.minersize = settings_yml.getString("minersize"); + this.circularMax = settings_yml.getInt("circularMax"); + this.heightMax = settings_yml.getInt("heightMax"); + this.completeAmount = settings_yml.getInt("completeAmount"); + this.countdownTime = settings_yml.getInt("countdownTime"); + Bukkit.getConsoleSender().sendMessage("[日志 - 炸弹填充] 游戏设置:"); + if(settings_yml.getConfigurationSection("Settings") != null){ + Bukkit.getConsoleSender().sendMessage("设置: 最大圈数 "+this.circularMax+"圈"); + Bukkit.getConsoleSender().sendMessage("设置: 最大高度 "+this.heightMax+"层"); + for (String buttKey : settings_yml.getConfigurationSection("Settings").getKeys(false)){ + int settings_type = settings_yml.getInt("Settings."+buttKey); + gameSettings.put(buttKey, settings_type); + Bukkit.getConsoleSender().sendMessage("设置: "+buttKey+" "+getSwitchString(settings_type)); + } + } + } + + public void LoadDianEvent(FileConfiguration yml){ + this.dianzan_need = 300; + if(yml.getInt("LiveLike.needamount") >= 1){ + this.dianzan_need = yml.getInt("LiveLike.needamount"); + } + this.dianzan_event = "小雷王"; + if(yml.getString("LiveLike.event") != null){ + this.dianzan_event = yml.getString("LiveLike.event"); + } + } + + // 保存配置文件 + public void SaveSettingsConfig(){ + FileConfiguration yml = Main.plugin.getConfig(); + yml.set("minersize",this.minersize); + yml.set("completeAmount",this.completeAmount); + yml.set("countdownTime",this.countdownTime); + for (String buttKey : gameSettings.keySet()) { + yml.set("Settings."+buttKey,gameSettings.get(buttKey)); + } + Main.plugin.saveConfig(); + } + + public List getRandonBoxList(String box_type) { + if(this.randonBoxList.get(box_type) != null){ + return this.randonBoxList.get(box_type); + } + return new ArrayList<>(); + } + + public boolean isGameSettings(String buttKey){ + if(gameSettings.get(buttKey) != null){ + int type = gameSettings.get(buttKey); + if(type == 1){ + return true; + } + } + return false; + } + public int getGameSettings(String buttKey){ + if(gameSettings.get(buttKey) != null){ + return gameSettings.get(buttKey); + } + return 0; + } + + public void setGameSettings(String buttKey,int settings_type){ + if(gameSettings.get(buttKey) != null){ + gameSettings.put(buttKey,settings_type); + } + gameSettings.put(buttKey,settings_type); + } + + public int getDianzan_need() { + return dianzan_need; + } + + public String getDianzan_event() { + return dianzan_event; + } + + public int getCountdownTime() { + return countdownTime; + } + public String getSwitchString(int butt){ + if(butt == 1){ + return "开启"; + } + return "关闭"; + } + public int getDianzan_amount() { + return dianzan_amount; + } + public void addDianzan_amount(int add_amount){ + setDianzan_amount(dianzan_amount+add_amount); + } + public void setDianzan_amount(int dianzan_amount) { + this.dianzan_amount = dianzan_amount; + } +} diff --git a/src/main/java/me/Demon/BlockWars/Util/GameUtil.java b/src/main/java/me/Demon/BlockWars/Util/GameUtil.java new file mode 100644 index 0000000..b670b1c --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Util/GameUtil.java @@ -0,0 +1,95 @@ +package me.Demon.BlockWars.Util; + +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.extent.clipboard.Clipboard; +import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats; +import com.sk89q.worldedit.math.BlockVector3; +import me.Demon.BlockWars.Main; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Pig; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.io.File; + +public class GameUtil { + + public static boolean AntiGiftEvent = false; + + public static void setAntiGiftEvent(boolean antiGiftEvent) { + AntiGiftEvent = antiGiftEvent; + } + + public static boolean isAntiGiftEvent() { + return AntiGiftEvent; + } + + public static void ClearWorldEntity(){ + for (Entity entity : Main.gameData.getWorld().getEntities()) { + if(!(entity instanceof Player)){ + if(Main.configYml.isGameSettings("pigkills")) { + if(!(entity instanceof Pig)){ + entity.remove(); + } + }else { + entity.remove(); + } + continue; + } + } + } + + public static void loadSchematics(String fileName) { + int minerY = 3; + File schema_file = new File("plugins/FastAsyncWorldEdit/schematics",fileName+".schem"); + Location location = new Location(Main.gameData.getWorld(),87.5,minerY,-1.5); + World world = location.getWorld(); + EditSession editSession = WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(world)); + Bukkit.getScheduler().runTaskAsynchronously (Main.plugin, () -> { + try { + Clipboard clipboard = ClipboardFormats.findByFile(schema_file).load(schema_file); + clipboard.paste(BukkitAdapter.adapt(world), BlockVector3.at(location.getBlockX(), location.getBlockY(), location.getBlockZ())); + clipboard.flush(); + } catch (Exception e) { + e.printStackTrace(); + } finally { + editSession.close(); + } + } + ); + } + + public static void refreshPlayerHandStack(Player p){ + Material material = Material.IRON_BLOCK; + int rand = RandomUtil.getRandomInt(1,100); + if(rand >= 75){ + material = Material.GOLD_BLOCK; + }else if(rand >= 50){ + material = Material.DIAMOND_BLOCK; + }else if(rand >= 25){ + material = Material.EMERALD_BLOCK; + } + Inventory inv = p.getInventory(); + for (int i = 0; i < 9;i++){ + ItemStack item = inv.getItem(i); + if(item != null && item.getType() != Material.AIR){ + if(item.getType().name().contains("_BLOCK")){ + inv.setItem(i, new ItemStack(Material.AIR)); + inv.setItem(i, new ItemStack(material)); + } + }else { + inv.setItem(i, new ItemStack(Material.AIR)); + inv.setItem(i, new ItemStack(material)); + } + } + } + +} diff --git a/src/main/java/me/Demon/BlockWars/Util/RandomUtil.java b/src/main/java/me/Demon/BlockWars/Util/RandomUtil.java new file mode 100644 index 0000000..962b5b1 --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/Util/RandomUtil.java @@ -0,0 +1,53 @@ +package me.Demon.BlockWars.Util; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.util.Random; + +public class RandomUtil { + + public static boolean random(double d) { + return d >= new Random().nextFloat(); + } + + public static boolean isEven(int number) { + return number % 2 == 0; + } + + public static int getRandomInt(int min, int max) { + if (min == max) { + return max; + } + Random r = new Random(); + int i = min < max ? min : max; + int a = min < max ? max : min; + return r.nextInt(a - i + 1) + i; + } + + public static double getRandomDouble(double min, double max, int scl) { + int pow = (int) Math.pow(10, scl); + return Math.floor((Math.random() * (max - min) + min) * pow) / pow; + } + + public static Location getRandomLocation(World world, double minX, double maxX, double minY, double maxY, double minZ, double maxZ) { + double rx = getRandomDouble(minX, maxX, 3); + double ry = getRandomDouble(minY, maxY, 3); + double rz = getRandomDouble(minZ, maxZ, 3); + Location location = new Location(world, rx, ry, rz); + return location; + } + public static Location getRandomLocation(Player zhubo,World world, double minX, double maxX, double minY, double maxY, double minZ, double maxZ) { + Location location = zhubo.getLocation().add(getRandomInt(-2,2),0,getRandomInt(-2,2)); + for (int i = 0; i < 10;i++) { + Location loc = new Location(world, getRandomDouble(minX, maxX, 3), getRandomDouble(minY, maxY, 3), getRandomDouble(minZ, maxZ, 3)); + if (loc.distance(zhubo.getLocation()) <= 50) { + location = loc; + break; + } + } + return location; + } + +} diff --git a/src/main/java/me/Demon/BlockWars/api/BlockWarsAPI.java b/src/main/java/me/Demon/BlockWars/api/BlockWarsAPI.java new file mode 100644 index 0000000..f9007cb --- /dev/null +++ b/src/main/java/me/Demon/BlockWars/api/BlockWarsAPI.java @@ -0,0 +1,25 @@ +package me.Demon.BlockWars.api; + +import me.Demon.BlockWars.Game.BlockRegion; +import me.Demon.BlockWars.Game.GameData; +import me.Demon.BlockWars.Game.Region; +import me.Demon.BlockWars.Main; + +import java.util.List; + +public class BlockWarsAPI { + + // 获取游戏Data + public static GameData getGameData(){ + return Main.gameData; + } + + // 获取区域 + public static Region getGameRegion(){ + return getGameData().getRegion(); + } + // 获取异步区块 + public static List getBlockRegionList(){ + return getGameData().getBlockRegionList(); + } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..4a12b98 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,5 @@ + +# 挑战次数 +completeAmount: 10 +# 完成倒计时 +countdownTime: 10 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 3e9a882..d6ec47e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,6 @@ name: BlockWars main: me.Demon.BlockWars.Main version: 1.0.0 +api-version: 1.18 commands: game: \ No newline at end of file