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