测试版

This commit is contained in:
yaohunya 2024-07-23 20:26:29 +08:00
parent 0fe6d0f3e2
commit f0ed4534e7
21 changed files with 1459 additions and 1 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/.idea/

20
pom.xml
View File

@ -13,4 +13,24 @@
<maven.compiler.target>8</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>public</id>
<url>https://repo.aurora-pixels.com/repository/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.18.2</version>
</dependency>
<dependency>
<groupId>com.fastasyncworldedit.bukkit</groupId>
<artifactId>FastAsyncWorldEdit</artifactId>
<version>1.18.2</version>
</dependency>
</dependencies>
</project>

View File

@ -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;
}
}

View File

@ -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 +
'}';
}
}

View File

@ -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<BlockRegion> blockRegionList = new ArrayList<>();
private int totalBlockAmount = 0; // 当前矿坑中的方块数量
private int completeBlockGoal = 0;
private List<BukkitTask> 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<BlockRegion> 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<BlockRegion> 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;
}
}

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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<Block> 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<Block> 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();
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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<BlockRegion> 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<BlockRegion> 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");
}
});
}
}
}

View File

@ -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<BossBar> bossBarList){
for (BossBar bossBar : bossBarList) {
bossBar.addPlayer(player);
}
}
public static void removeBossBar(Player player,List<BossBar> bossBarList){
for (BossBar bossBar : bossBarList) {
bossBar.removePlayer(player);
}
}
}

View File

@ -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<BlockRegion> 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;
}
}

View File

@ -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<String,List<String>> randonBoxList = new HashMap<>();
private HashMap<String, Integer> 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<String> 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;
}
}

View File

@ -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));
}
}
}
}

View File

@ -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;
}
}

View File

@ -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<BlockRegion> getBlockRegionList(){
return getGameData().getBlockRegionList();
}
}

View File

@ -0,0 +1,5 @@
# 挑战次数
completeAmount: 10
# 完成倒计时
countdownTime: 10

View File

@ -1,5 +1,6 @@
name: BlockWars
main: me.Demon.BlockWars.Main
version: 1.0.0
api-version: 1.18
commands:
game: