commit 910c578f9934d1e575ac84dfad18561bf017eb65 Author: YuTian <2953516620@qq.com> Date: Fri Jul 5 00:07:50 2024 +0800 第一次提交 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..16e8794 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/ColorblindWar.iml +/.idea/ +/target/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..046248a --- /dev/null +++ b/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + com.io.yutian + ColorblindWar + 1.0-SNAPSHOT + jar + + ColorblindWar + + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + papermc-repo + https://repo.papermc.io/repository/maven-public/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + public + http://111.230.48.153:18081/repository/public/ + + + + + + io.papermc.paper + paper-api + 1.18.2-R0.1-SNAPSHOT + provided + + + com.fastasyncworldedit.bukkit + FastAsyncWorldEdit + 2.9.1 + 660 + + + diff --git a/src/main/java/com/io/yutian/colorblindwar/ColorblindWar.java b/src/main/java/com/io/yutian/colorblindwar/ColorblindWar.java new file mode 100644 index 0000000..bb6f3d4 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/ColorblindWar.java @@ -0,0 +1,86 @@ +package com.io.yutian.colorblindwar; + +import com.io.yutian.colorblindwar.game.DirectionPoint; +import com.io.yutian.colorblindwar.game.Game; +import com.io.yutian.colorblindwar.listener.PlayerListener; +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.java.JavaPlugin; + +public final class ColorblindWar extends JavaPlugin { + + private static ColorblindWar instance; + private static Game game; + + @Override + public void onEnable() { + instance = this; + game = new Game(); + Bukkit.getPluginManager().registerEvents(new PlayerListener(), this); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) { + sender.sendMessage("/cw create - 创建游戏"); + sender.sendMessage("/cw start - 开始游戏"); + sender.sendMessage("/cw stop - 结束游戏"); + sender.sendMessage("/gw reload - 重载"); + return true; + } else { + String subCommand = args[0]; + if (subCommand.equalsIgnoreCase("create")) { + if (!(sender instanceof Player)) { + sender.sendMessage("非玩家无法创建游戏"); + return true; + } + Player player = (Player) sender; + game.setWorld(player.getWorld()); + game.setSpawnPoint(DirectionPoint.of(player.getLocation())); + game.reload(); + player.sendMessage("成功创建游戏"); + } else if (subCommand.equalsIgnoreCase("start")) { + if (!(sender instanceof Player)) { + sender.sendMessage("非玩家无法开始游戏"); + return true; + } + if (game.isStarted()) { + sender.sendMessage("游戏已开始"); + return true; + } + Player player = (Player) sender; + game.start(player); + } else if (subCommand.equalsIgnoreCase("stop")) { + if (!game.isStarted()) { + sender.sendMessage("游戏未开始"); + return true; + } + Player player = (Player) sender; + game.stop(false); + } else if (subCommand.equalsIgnoreCase("reload")) { + game.reload(); + sender.sendMessage("重载成功"); + } else if (subCommand.equalsIgnoreCase("test")) { + if (args[1].equalsIgnoreCase("spawn")) { + game.spawnBuild(); + } else if (args[1].equalsIgnoreCase("clear")) { + game.clearBlock(); + } else if (args[1].equalsIgnoreCase("v")) { + game.vanishBlock(); + } + } + } + return true; + } + + public static ColorblindWar inst() { + return instance; + } + + public static Game getGame() { + return game; + } + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/game/DirectionPoint.java b/src/main/java/com/io/yutian/colorblindwar/game/DirectionPoint.java new file mode 100644 index 0000000..2ebb655 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/game/DirectionPoint.java @@ -0,0 +1,84 @@ +package com.io.yutian.colorblindwar.game; + +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; + +import java.util.Objects; + +public class DirectionPoint extends Point { + + private float yaw; + private float pitch; + + public DirectionPoint(int x, int y, int z, float yaw, float pitch) { + super(x, y, z); + this.yaw = yaw; + this.pitch = pitch; + } + + public DirectionPoint(double x, double y, double z) { + this(x, y, z, 0f, 0f); + } + + public DirectionPoint(double x, double y, double z, float yaw, float pitch) { + super(x, y, z); + this.yaw = yaw; + this.pitch = pitch; + } + + public float getPitch() { + return pitch; + } + + public float getYaw() { + return yaw; + } + + public void setYaw(float yaw) { + this.yaw = yaw; + } + + public void setPitch(float pitch) { + this.pitch = pitch; + } + + @Override + public Location toLocation(World world) { + return new Location(world, getX(), getY(), getZ(), yaw, pitch); + } + + public static DirectionPoint of(Location location) { + return new DirectionPoint(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); + } + + @Override + public String toString() { + return "DirectionPoint{" + + "x=" + getX() + + ", y=" + getY() + + ", z=" + getZ() + + ", yaw=" + yaw + + ", pitch=" + pitch + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + DirectionPoint that = (DirectionPoint) o; + return super.equals(o) && Float.compare(that.yaw, yaw) == 0 && Float.compare(that.pitch, pitch) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), yaw, pitch); + } + + public static DirectionPoint deserialize(ConfigurationSection section) { + return new DirectionPoint(section.getDouble("x"), section.getDouble("y"), section.getDouble("z"), (float) section.getDouble("yaw"), (float) section.getDouble("pitch")); + } + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/game/Game.java b/src/main/java/com/io/yutian/colorblindwar/game/Game.java new file mode 100644 index 0000000..b1db256 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/game/Game.java @@ -0,0 +1,359 @@ +package com.io.yutian.colorblindwar.game; + +import com.io.yutian.colorblindwar.ColorblindWar; +import com.io.yutian.colorblindwar.util.*; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import com.sk89q.worldedit.function.mask.BlockTypeMask; +import com.sk89q.worldedit.function.mask.InverseSingleBlockTypeMask; +import com.sk89q.worldedit.function.mask.Mask; +import com.sk89q.worldedit.function.operation.Operations; +import com.sk89q.worldedit.math.BlockVector3; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.world.block.BlockTypes; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.TextColor; +import org.bukkit.*; +import org.bukkit.boss.BarColor; +import org.bukkit.boss.BarStyle; +import org.bukkit.boss.BossBar; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Firework; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.scheduler.BukkitTask; + +import java.util.*; + +public class Game { + + private static final List MATERIAL_LIST = Arrays.asList(Material.WHITE_WOOL, Material.BLACK_WOOL, Material.BROWN_WOOL, Material.BLUE_WOOL, Material.GREEN_WOOL, Material.RED_WOOL, Material.YELLOW_WOOL, Material.PURPLE_WOOL, Material.ORANGE_WOOL, Material.PINK_WOOL, Material.LIGHT_BLUE_WOOL, Material.LIME_WOOL); + + + private World world; + private DirectionPoint spawnPoint; + + private Player player; + + private BossBar bossBar1; + private BossBar bossBar2; + private BossBar bossBar3; + private BossBar bossBar4; + + private List tasks = new ArrayList<>(); + private List entities = new ArrayList<>(); + + private int challengeAmount = 0; + private int vanishCountdown = 0; + private int vanishCooldown = 0; + private Material vanishMaterial = Material.AIR; + + private boolean started = false; + + private GameConfig gameConfig; + private BuildSpawner buildSpawner; + + public Game() { + reload(); + this.bossBar1 = Bukkit.createBossBar("今日挑战进度", BarColor.WHITE, BarStyle.SEGMENTED_10); + this.bossBar2 = Bukkit.createBossBar("爬塔进度", BarColor.WHITE, BarStyle.SEGMENTED_20); + this.bossBar3 = Bukkit.createBossBar("方块消失倒计时", BarColor.WHITE, BarStyle.SOLID); + this.bossBar4 = Bukkit.createBossBar("方块出现倒计时", BarColor.WHITE, BarStyle.SOLID); + } + + public void reload() { + ColorblindWar.inst().saveDefaultConfig(); + ColorblindWar.inst().reloadConfig(); + FileConfiguration config = ColorblindWar.inst().getConfig(); + if (config.contains("world")) { + this.world = Bukkit.getWorld(config.getString("world")); + } + if (config.contains("spawnPoint") && config.isConfigurationSection("spawnPoint")) { + this.spawnPoint = DirectionPoint.deserialize(config.getConfigurationSection("spawnPoint")); + } + if (world == null || spawnPoint == null) { + return; + } + BuildSpawner.Direction initialDirection = BuildSpawner.Direction.NORTH; + int chunkWight = 2; + int chunkLength = 2; + int ladderLength = 3; + int ladderAmount = 5; + int platformWidth = 3; + int platformLength = 7; + int levelAmount = 10; + BuildSpawner.SpawnMode spawnMode = BuildSpawner.SpawnMode.MODE_2; + int completeAmount = config.getInt("completeAmount", 10); + int countdownTime = config.getInt("countdownTime", 15); + this.gameConfig = new GameConfig(initialDirection, chunkWight, chunkLength, ladderLength, ladderAmount, platformWidth, platformLength, levelAmount, spawnMode, MATERIAL_LIST, completeAmount, countdownTime); + this.buildSpawner = gameConfig.getSpawner(world, spawnPoint); + this.vanishCountdown = gameConfig.getCountdownTime() * 20; + } + + public void start(Player player) { + if (started) { + return; + } + if (world == null || spawnPoint == null) { + return; + } + this.started = true; + this.player = player; + this.challengeAmount = 0; + this.vanishCountdown = gameConfig.getCountdownTime() * 20; + initWorld(); + updateBossBar(); + this.bossBar1.addPlayer(player); + this.bossBar2.addPlayer(player); + this.bossBar3.addPlayer(player); + this.bossBar4.addPlayer(player); + spawnBuild(); + changeVanishMaterial(); + player.teleport(spawnPoint.toLocation(world)); + this.tasks.add(new BukkitRunnable() { + @Override + public void run() { + updateBossBar(); + } + }.runTaskTimer(ColorblindWar.inst(), 0L, 10L)); + this.tasks.add(new BukkitRunnable() { + @Override + public void run() { + updateVanishCountdown(); + } + }.runTaskTimer(ColorblindWar.inst(), 0L, 1L)); + } + + private void initWorld() { + this.world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false); + this.world.setGameRule(GameRule.DO_WEATHER_CYCLE, false); + this.world.setGameRule(GameRule.DO_MOB_SPAWNING, false); + this.world.setGameRule(GameRule.DO_MOB_LOOT, false); + this.world.setGameRule(GameRule.MOB_GRIEFING, false); + this.world.setTime(6000); + } + + public void stop(boolean win) { + if (!started) { + return; + } + this.started = false; + for (Entity entity : entities) { + entity.remove(); + } + this.bossBar1.removeAll(); + this.bossBar2.removeAll(); + this.bossBar3.removeAll(); + this.bossBar4.removeAll(); + this.player.getInventory().clear(); + this.player.teleport(spawnPoint.toLocation(world)); + this.entities.clear(); + if (win) { + new BukkitRunnable() { + private int i = 0; + @Override + public void run() { + if (i >= 20) { + cancel(); + return; + } + player.getWorld().spawn(player.getLocation(), Firework.class, (firework -> { + FireworkMeta fireworkMeta = firework.getFireworkMeta(); + fireworkMeta.addEffect(FireworkEffect.builder().withColor(Color.TEAL, Color.RED, Color.GREEN, Color.YELLOW, Color.LIME).trail(true).build()); + Random random = new Random(); + for (int i = 0; i < RandomUtil.getRandomInt(1, 2); i++) { + FireworkEffect effect = FireworkEffect.builder().flicker(random.nextBoolean()).withColor(Color.fromRGB(RandomUtil.getRandomInt(100, 255), RandomUtil.getRandomInt(100, 255), RandomUtil.getRandomInt(100, 255))).withFade(Color.fromRGB(RandomUtil.getRandomInt(100, 255), RandomUtil.getRandomInt(100, 255), RandomUtil.getRandomInt(100, 255))).with(FireworkEffect.Type.values()[random.nextInt(FireworkEffect.Type.values().length)]).trail(random.nextBoolean()).build(); + fireworkMeta.addEffect(effect); + } + fireworkMeta.setPower(random.nextInt(2)); + firework.setFireworkMeta(fireworkMeta); + })); + i++; + } + }.runTaskTimer(ColorblindWar.inst(), 0L, 5L); + player.sendMessage("§c[系统]§ a今日挑战已完成! 恭喜你!"); + start(player); + } else { + player.sendMessage("§c[系统] §a游戏已被强制结束!"); + } + tasks.forEach(task -> { + if (!task.isCancelled()) { + task.cancel(); + } + }); + } + + private void updateBossBar() { + int completeAmount = gameConfig.getCompleteAmount(); + double d = (double) challengeAmount / (double) completeAmount; + bossBar1.setTitle("§6今日挑战进度: §f"+challengeAmount+"/"+completeAmount); + if (d < 0) { + d = 0; + } + bossBar1.setProgress(d); + bossBar1.setColor(BossBarUtil.getBarColor(d)); + int maxHeight = spawnPoint.getBlockY() + buildSpawner.getHeight(); + int nowHeight = player.getLocation().getBlockY(); + int c1 = nowHeight - spawnPoint.getBlockY(); + c1 = Math.max(c1, 0); + double d1 = (double) c1 / (double) buildSpawner.getHeight(); + d1 = Math.min(d1, 1.0); + double d2 = MathUtil.round(d1 * 100, 2); + bossBar2.setTitle("§6爬塔进度: §f"+c1+"/"+buildSpawner.getHeight()+" §b("+d2+"%)"); + bossBar2.setProgress(d1); + bossBar2.setColor(BossBarUtil.getBarColor(d1)); + sendActionBar(); + } + + private void updateVanishCountdown() { + if (vanishCooldown > 0) { + vanishCooldown--; + if (bossBar3.isVisible()) { + bossBar3.setVisible(false); + } + if (!bossBar4.isVisible()) { + bossBar4.setVisible(true); + } + bossBar4.setTitle("§6方块出现倒计时: §f"+ MathUtil.round(vanishCooldown / (double) 20, 1) +"s"); + double p = vanishCooldown / (double) 60; + bossBar4.setProgress(p); + bossBar4.setColor(BossBarUtil.getBarColor(p)); + if (vanishCooldown == 0) { + bossBar4.setVisible(false); + startVanishCountdown(); + return; + } + return; + } else { + if (!bossBar3.isVisible()) { + bossBar3.setVisible(true); + } + if (bossBar4.isVisible()) { + bossBar4.setVisible(false); + } + } + if (vanishCountdown > 0) { + vanishCountdown--; + if (vanishCountdown <= 100 && vanishCountdown % 20 == 0) { + player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_GUITAR, 1.0F, 1.0F); + } + bossBar3.setTitle("§6方块消失倒计时: §f"+ MathUtil.round(vanishCountdown / (double) 20, 1) +"s"); + double p = vanishCountdown / (double) (gameConfig.getCountdownTime() * 20); + bossBar3.setProgress(p); + bossBar3.setColor(BossBarUtil.getBarColor(p)); + } else { + vanishBlock(); + for (int i = 0; i < 9; i++) { + player.getInventory().setItem(i, null); + } + vanishCooldown = 60; + bossBar3.setVisible(false); + } + } + + private void startVanishCountdown() { + vanishCountdown = gameConfig.getCountdownTime() * 20; + spawnBuild(); + changeVanishMaterial(); + } + + private void changeVanishMaterial() { + vanishMaterial = buildSpawner.getRandomMaterial(); + ItemStack itemStack = new ItemStack(vanishMaterial); + ItemMeta itemMeta = itemStack.getItemMeta(); + itemMeta.setDisplayName(""); + itemStack.setItemMeta(itemMeta); + for (int i = 0; i < 9; i++) { + player.getInventory().setItem(i, itemStack); + } + } + + private void sendActionBar() { + Component message = Component.text("§l"+ ColorUtil.getColorName(vanishMaterial)) + .color(TextColor.fromHexString(ColorUtil.getColorHex(vanishMaterial))); + player.sendActionBar(message); + } + + public void spawnBuild() { + buildSpawner.spawn(); + } + + public void vanishBlock() { + Material material = vanishMaterial; + Region region = buildSpawner.getEffectiveRegion(world); + Point minPoint = region.getMin(); + Point maxPoint = region.getMax(); + BlockVector3 newVector1 = BlockVector3.at(minPoint.getX(), minPoint.getY(), minPoint.getZ()); + BlockVector3 newVector2 = BlockVector3.at(maxPoint.getX(), maxPoint.getY(), maxPoint.getZ()); + CuboidRegion cuboidRegion = new CuboidRegion(BukkitAdapter.adapt(region.getWorld()),newVector1,newVector2); + try (EditSession editSession = WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(region.getWorld()))) { + Mask mask = new InverseSingleBlockTypeMask(editSession, BukkitAdapter.asBlockType(material)); + editSession.replaceBlocks(cuboidRegion, mask, BlockTypes.AIR.getDefaultState()); + Operations.complete(editSession.commit()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void clearBlock() { + Region region = buildSpawner.getEffectiveRegion(world); + Point minPoint = region.getMin(); + Point maxPoint = region.getMax(); + BlockVector3 newVector1 = BlockVector3.at(minPoint.getX(), minPoint.getY(), minPoint.getZ()); + BlockVector3 newVector2 = BlockVector3.at(maxPoint.getX(), maxPoint.getY(), maxPoint.getZ()); + CuboidRegion cuboidRegion = new CuboidRegion(BukkitAdapter.adapt(region.getWorld()),newVector1,newVector2); + try (EditSession editSession = WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(region.getWorld()))) { + editSession.setBlocks((com.sk89q.worldedit.regions.Region) cuboidRegion, BlockTypes.AIR.getDefaultState()); + Operations.complete(editSession.commit()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void setWorld(World world) { + this.world = world; + FileConfiguration config = ColorblindWar.inst().getConfig(); + config.set("world", world.getName()); + ColorblindWar.inst().saveConfig(); + } + + public void setSpawnPoint(DirectionPoint spawnPoint) { + this.spawnPoint = spawnPoint; + FileConfiguration config = ColorblindWar.inst().getConfig(); + ConfigurationSection section1 = config.getConfigurationSection("spawnPoint"); + section1.set("x", spawnPoint.getX()); + section1.set("y", spawnPoint.getY()); + section1.set("z", spawnPoint.getZ()); + section1.set("yaw", spawnPoint.getYaw()); + section1.set("pitch", spawnPoint.getPitch()); + ColorblindWar.inst().saveConfig(); + } + + public boolean isStarted() { + return started; + } + + public World getWorld() { + return world; + } + + public Point getSpawnPoint() { + return spawnPoint; + } + + public GameConfig getGameConfig() { + return gameConfig; + } + + public BuildSpawner getBuildSpawner() { + return buildSpawner; + } + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/game/GameConfig.java b/src/main/java/com/io/yutian/colorblindwar/game/GameConfig.java new file mode 100644 index 0000000..8426c72 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/game/GameConfig.java @@ -0,0 +1,91 @@ +package com.io.yutian.colorblindwar.game; + +import com.io.yutian.colorblindwar.util.BuildSpawner; +import org.bukkit.Material; +import org.bukkit.World; + +import java.util.List; + +public class GameConfig { + + private BuildSpawner.Direction initialDirection; + private int chunkWight; + private int chunkHeight; + private int ladderLength; + private int ladderAmount; + private int platformWidth; + private int platformLength; + private int levelAmount; + private BuildSpawner.SpawnMode spawnMode; + private List materials; + + private int completeAmount = 10; + private int countdownTime = 15; + + public GameConfig(BuildSpawner.Direction initialDirection, int chunkWight, int chunkHeight, int ladderLength, int ladderAmount, int platformWidth, int platformLength, int levelAmount, BuildSpawner.SpawnMode spawnMode, List materials, int completeAmount, int countdownTime) { + this.initialDirection = initialDirection; + this.chunkWight = chunkWight; + this.chunkHeight = chunkHeight; + this.ladderLength = ladderLength; + this.ladderAmount = ladderAmount; + this.platformWidth = platformWidth; + this.platformLength = platformLength; + this.levelAmount = levelAmount; + this.spawnMode = spawnMode; + this.materials = materials; + this.completeAmount = completeAmount; + this.countdownTime = countdownTime; + } + + public BuildSpawner.Direction getInitialDirection() { + return initialDirection; + } + + public int getChunkWight() { + return chunkWight; + } + + public int getChunkHeight() { + return chunkHeight; + } + + public int getLadderLength() { + return ladderLength; + } + + public int getLadderAmount() { + return ladderAmount; + } + + public int getPlatformWidth() { + return platformWidth; + } + + public int getPlatformLength() { + return platformLength; + } + + public int getLevelAmount() { + return levelAmount; + } + + public BuildSpawner.SpawnMode getSpawnMode() { + return spawnMode; + } + + public List getMaterials() { + return materials; + } + + public int getCompleteAmount() { + return completeAmount; + } + + public int getCountdownTime() { + return countdownTime; + } + + public BuildSpawner getSpawner(World world, Point point) { + return new BuildSpawner(world, initialDirection, point.getBlockX(), point.getBlockY() - 1, point.getBlockZ(), chunkWight, chunkHeight, ladderLength, ladderAmount, platformWidth, platformLength, levelAmount, spawnMode, materials); + } +} diff --git a/src/main/java/com/io/yutian/colorblindwar/game/Point.java b/src/main/java/com/io/yutian/colorblindwar/game/Point.java new file mode 100644 index 0000000..fbe0158 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/game/Point.java @@ -0,0 +1,106 @@ +package com.io.yutian.colorblindwar.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 int getBlockX() { + return (int) Math.floor(x); + } + + public int getBlockY() { + return (int) Math.floor(y); + } + + public int getBlockZ() { + return (int) Math.floor(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 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/com/io/yutian/colorblindwar/game/Region.java b/src/main/java/com/io/yutian/colorblindwar/game/Region.java new file mode 100644 index 0000000..700ed64 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/game/Region.java @@ -0,0 +1,51 @@ +package com.io.yutian.colorblindwar.game; + +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 World getWorld() { + return world; + } + + public Point getMin() { + return min; + } + + public Point getMax() { + return max; + } + + 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 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()); + } + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/listener/PlayerListener.java b/src/main/java/com/io/yutian/colorblindwar/listener/PlayerListener.java new file mode 100644 index 0000000..b2e21ae --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/listener/PlayerListener.java @@ -0,0 +1,85 @@ +package com.io.yutian.colorblindwar.listener; + +import com.io.yutian.colorblindwar.ColorblindWar; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.*; +import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerDropItemEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.weather.WeatherChangeEvent; + +public class PlayerListener implements Listener { + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (ColorblindWar.getGame().isStarted()) { + ColorblindWar.getGame().stop(false); + } + } + + @EventHandler + public void onPlayerDropItem(PlayerDropItemEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.setCancelled(true); + } + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.setCancelled(true); + } + } + + @EventHandler + public void onEntityExplode(EntityExplodeEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.blockList().clear(); + } + } + + @EventHandler + public void onBlockExplode(BlockExplodeEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.blockList().clear(); + } + } + + @EventHandler + public void onWeatherChange(WeatherChangeEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockFire(BlockBurnEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.setCancelled(true); + } + } + + @EventHandler + public void onBlockIgnite(BlockIgniteEvent event) { + if (ColorblindWar.getGame().isStarted()) { + event.setCancelled(true); + } + } + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/util/BossBarUtil.java b/src/main/java/com/io/yutian/colorblindwar/util/BossBarUtil.java new file mode 100644 index 0000000..09dee61 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/util/BossBarUtil.java @@ -0,0 +1,17 @@ +package com.io.yutian.colorblindwar.util; + +import org.bukkit.boss.BarColor; + +public class BossBarUtil { + + public static BarColor getBarColor(double d) { + if (d >= 0 && d <= 0.3333) { + return BarColor.RED; + } else if (d <= 0.6666) { + return BarColor.YELLOW; + } else { + return BarColor.GREEN; + } + } + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/util/BuildSpawner.java b/src/main/java/com/io/yutian/colorblindwar/util/BuildSpawner.java new file mode 100644 index 0000000..1f8d356 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/util/BuildSpawner.java @@ -0,0 +1,415 @@ +package com.io.yutian.colorblindwar.util; + +import com.io.yutian.colorblindwar.game.Point; +import com.io.yutian.colorblindwar.game.Region; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.util.Vector; + +import java.util.List; + +public class BuildSpawner { + + private World world; + private Direction initialDirection; + private int originX; + private int originY; + private int originZ; + private int chunkWight; + private int chunkLength; + private int ladderLength; + private int ladderAmount; + private int platformWidth; + private int platformLength; + private int levelAmount; + private SpawnMode spawnMode; + + private int nowX; + private int nowY; + private int nowZ; + private Direction nowDirection; + + private List materials; + + protected ISpawnModeHander spawnModeHander; + + public BuildSpawner(World world, Direction initialDirection, int originX, int originY, int originZ, int chunkWight, int chunkLength, int ladderLength, int ladderAmount, int platformWidth, int platformLength, int levelAmount, SpawnMode spawnMode, List materials) { + this.world = world; + this.initialDirection = initialDirection; + this.originX = originX; + this.originY = originY; + this.originZ = originZ; + this.chunkWight = chunkWight; + this.chunkLength = chunkLength; + this.ladderLength = ladderLength; + this.ladderAmount = ladderAmount; + this.platformWidth = platformWidth; + this.platformLength = platformLength; + this.levelAmount = levelAmount; + this.spawnMode = spawnMode; + this.materials = materials; + + nowX = originX; + nowY = originY; + nowZ = originZ; + nowDirection = initialDirection; + if (spawnMode == SpawnMode.MODE_1) { + spawnModeHander = new SpawnModeHandler_1(); + } else if (spawnMode == SpawnMode.MODE_2) { + spawnModeHander = new SpawnModeHandler_2(); + } + } + + public void spawn() { + nowX = originX; + nowY = originY; + nowZ = originZ; + nowDirection = initialDirection; + if (spawnModeHander != null) { + spawnModeHander.spawn(); + } + } + + private void spawnPlatform(int x, int y, int z, Direction direction) { + if (direction == Direction.EAST || direction == Direction.WEST) { + for (int i = 0; i < platformLength; i++) { + for (int j = 0; j < platformWidth; j++) { + int x1 = x + (i * chunkWight) * direction.getPlatformVector().getBlockX(); + int z1 = z + (j * chunkLength) * direction.getPlatformVector().getBlockZ(); + spawnPlatformChunk(x1, y, z1, direction); + } + } + } else if (direction == Direction.NORTH || direction == Direction.SOUTH) { + for (int i = 0; i < platformLength; i++) { + for (int j = 0; j < platformWidth; j++) { + int x1 = x + (j * chunkLength) * direction.getPlatformVector().getBlockX(); + int z1 = z + (i * chunkWight) * direction.getPlatformVector().getBlockZ(); + spawnPlatformChunk(x1, y, z1, direction); + } + } + } + } + + private void spawnLadder(int x, int y, int z, Direction direction) { + for (int i = 0; i < ladderAmount; i++) { + for (int j = 0; j < ladderLength; j++) { + int x1 = getLadderX(i, j, x, z, direction); + int z1 = getLadderZ(i, j, x, z, direction); + spawnLadderChunk(x1, y + i + 1, z1, direction); + } + } + } + + private int getLadderX(int i, int j, int x, int z, Direction direction) { + switch (direction) { + case EAST: + case WEST: + return x + (i * chunkWight) * direction.getLadderVector().getBlockX(); + case SOUTH: + case NORTH: + return x + (j * chunkLength) * direction.getLadderVector().getBlockX(); + } + return x; + } + + private int getLadderZ(int i, int j, int x, int z, Direction direction) { + switch (direction) { + case EAST: + case WEST: + return z + (j * chunkLength) * direction.getLadderVector().getBlockZ(); + case SOUTH: + case NORTH: + return z + (i * chunkWight) * direction.getLadderVector().getBlockZ(); + } + return z; + } + + private void spawnPlatformChunk(int x, int y, int z, Direction direction) { + Material material = getRandomMaterial(); + if (direction == Direction.EAST || direction == Direction.WEST) { + for (int i = 0; i < chunkWight; i++) { + for (int j = 0; j < chunkLength; j++) { + int x1 = x + i * direction.getPlatformVector().getBlockX(); + int z1 = z + j * direction.getPlatformVector().getBlockZ(); + world.getBlockAt(x1, y, z1).setType(material); + } + } + } else if (direction == Direction.NORTH || direction == Direction.SOUTH) { + for (int i = 0; i < chunkWight; i++) { + for (int j = 0; j < chunkLength; j++) { + int x1 = x + j * direction.getPlatformVector().getBlockX(); + int z1 = z + i * direction.getPlatformVector().getBlockZ(); + world.getBlockAt(x1, y, z1).setType(material); + } + } + } + } + + private void spawnLadderChunk(int x, int y, int z, Direction direction) { + Material material = getRandomMaterial(); + if (direction == Direction.EAST || direction == Direction.WEST) { + for (int i = 0; i < chunkWight; i++) { + for (int j = 0; j < chunkLength; j++) { + int x1 = x + i * direction.getLadderVector().getBlockX(); + int z1 = z + j * direction.getLadderVector().getBlockZ(); + world.getBlockAt(x1, y, z1).setType(material); + } + } + } else if (direction == Direction.NORTH || direction == Direction.SOUTH) { + for (int i = 0; i < chunkLength; i++) { + for (int j = 0; j < chunkWight; j++) { + int x1 = x + i * direction.getLadderVector().getBlockX(); + int z1 = z + j * direction.getLadderVector().getBlockZ(); + world.getBlockAt(x1, y, z1).setType(material); + } + } + } + } + + private void transformDirection() { + nowDirection = nowDirection.getRightDirection(); + } + + private enum TransformType { + PLATFORM, + LADDER + } + + public enum Direction { + + NORTH(new Vector(1.0, 1.0, -1.0), new Vector(-1.0, 1.0, -1.0), new Vector(1.0, 1.0, -1.0)), + EAST(new Vector(1.0, 1.0, 1.0), new Vector(1.0, 1.0, -1.0), new Vector(1.0, 1.0, 1.0)), + SOUTH(new Vector(-1.0, 1.0, 1.0), new Vector(1.0, 1.0, 1.0), new Vector(-1.0, 1.0, 1.0)), + WEST(new Vector(-1.0, 1.0, -1.0), new Vector(-1.0, 1.0, 1.0), new Vector(-1.0, 1.0, -1.0)); + + private final Vector vector; + private final Vector platformVector; + private final Vector ladderVector; + + Direction(Vector vector, Vector platformVector, Vector ladderVector) { + this.vector = vector; + this.platformVector = platformVector; + this.ladderVector = ladderVector; + } + + public Vector getVector() { + return vector; + } + + public Vector getPlatformVector() { + return platformVector; + } + + public Vector getLadderVector() { + return ladderVector; + } + + public Direction getRightDirection() { + switch (this) { + case NORTH: + return EAST; + case EAST: + return SOUTH; + case SOUTH: + return WEST; + case WEST: + return NORTH; + } + return null; + } + + } + + public Region getEffectiveRegion(World world) { + return spawnModeHander.getEffectiveRegion(world); + } + + public int getHeight() { + return spawnModeHander.getHeight(); + } + + public enum SpawnMode { + + MODE_1, + MODE_2; + + } + + private class SpawnModeHandler_1 implements ISpawnModeHander { + @Override + public void spawn() { + for (int i = 0; i < levelAmount; i++) { + spawnPlatform(nowX, nowY, nowZ, nowDirection); + transformXYZ(TransformType.PLATFORM, nowDirection); + transformDirection(); + spawnLadder(nowX, nowY, nowZ, nowDirection); + transformXYZ(TransformType.LADDER, nowDirection); + transformDirection(); + } + spawnPlatform(nowX, nowY, nowZ, nowDirection); + } + + @Override + public Region getEffectiveRegion(World world) { + if (initialDirection == Direction.NORTH || initialDirection == Direction.SOUTH) { + int minX = originX + (platformWidth * chunkWight) * initialDirection.getPlatformVector().getBlockX(); + int minY = originY; + int minZ = originZ; + int maxX = originX + ladderAmount * ladderLength * chunkLength * initialDirection.getLadderVector().getBlockX() + (platformWidth * chunkWight) * initialDirection.getPlatformVector().getBlockX() + 1; + int maxY = originY + levelAmount * 5 + 1; + int maxZ = originZ + (platformLength * chunkLength) * initialDirection.getPlatformVector().getBlockZ() + 1; + return new Region(world, new Point(minX, minY, minZ), new Point(maxX, maxY, maxZ)); + } else if (initialDirection == Direction.EAST || initialDirection == Direction.WEST) { + int minX = originX; + int minY = originY; + int minZ = originZ + (platformWidth * chunkWight) * initialDirection.getPlatformVector().getBlockZ(); + int maxX = originX + (platformLength * chunkLength) * initialDirection.getPlatformVector().getBlockX() + 1; + int maxY = originY + levelAmount * 5 + 1; + int maxZ = originZ + ladderAmount * ladderLength * chunkLength * initialDirection.getLadderVector().getBlockX() + (platformWidth * chunkWight) * initialDirection.getPlatformVector().getBlockZ() + 1; + return new Region(world, new Point(minX, minY, minZ), new Point(maxX, maxY, maxZ)); + } + return null; + } + + @Override + public int getHeight() { + return levelAmount * 5; + } + + private void transformXYZ(TransformType transformType, Direction direction) { + if (transformType == TransformType.PLATFORM) { + if (direction == Direction.EAST || direction == Direction.WEST) { + nowX += (platformLength * chunkWight - 1) * direction.getPlatformVector().getX(); + } else if (direction == Direction.NORTH || direction == Direction.SOUTH) { + nowZ += (platformLength * chunkWight - 1) * direction.getPlatformVector().getZ(); + } + switch (nowDirection) { + case EAST: + nowZ += 1; + break; + case SOUTH: + nowX -= 1; + break; + case WEST: + nowZ -= 1; + break; + case NORTH: + nowX += 1; + break; + } + } else if (transformType == TransformType.LADDER) { + nowY += ladderAmount; + if (direction == Direction.EAST || direction == Direction.WEST) { + nowX += (ladderAmount * chunkWight) * direction.getLadderVector().getBlockX(); + } else if (direction == Direction.NORTH || direction == Direction.SOUTH) { + nowZ += (ladderAmount * chunkWight) * direction.getLadderVector().getBlockZ(); + } + } + } + } + + private class SpawnModeHandler_2 implements ISpawnModeHander { + + @Override + public void spawn() { + for (int i = 0; i < levelAmount; i++) { + spawnPlatform(nowX, nowY, nowZ, nowDirection); + transformXYZ(TransformType.PLATFORM, nowDirection, 0); + spawnLadder(nowX, nowY, nowZ, nowDirection); + transformXYZ(TransformType.LADDER, nowDirection, 0); + transformDirection(); + } + spawnPlatform(nowX, nowY, nowZ, nowDirection); + } + + @Override + public Region getEffectiveRegion(World world) { + if (initialDirection == Direction.NORTH || initialDirection == Direction.SOUTH) { + int minX = originX + (platformWidth * chunkWight) * initialDirection.getPlatformVector().getBlockX(); + int minZ = originZ; + minZ += (platformLength * chunkLength) * initialDirection.getPlatformVector().getBlockZ(); + minZ += (ladderAmount * chunkLength) * initialDirection.getLadderVector().getBlockZ(); + minZ += (platformWidth * chunkWight) * initialDirection.getRightDirection().getPlatformVector().getBlockZ(); + int maxX = originX + ladderAmount * ladderLength * chunkLength * initialDirection.getLadderVector().getBlockX() + (platformWidth * chunkWight) * initialDirection.getPlatformVector().getBlockX()+ 1; + int maxZ = originZ; + int maxY = originY + levelAmount * 5 + 1; + return new Region(world, new Point(minX, originY, minZ), new Point(maxX, maxY, maxZ)); + } else if (initialDirection == Direction.EAST || initialDirection == Direction.WEST) { + int minX = originX; + int minZ = originZ + (platformWidth * chunkWight) * initialDirection.getPlatformVector().getBlockZ(); + minX += (platformLength * chunkLength) * initialDirection.getPlatformVector().getBlockX(); + minX += (ladderAmount * chunkLength) * initialDirection.getLadderVector().getBlockX(); + minX += (platformWidth * chunkWight) * initialDirection.getRightDirection().getPlatformVector().getBlockX(); + int maxX = originX; + int maxZ = originZ + ladderAmount * ladderLength * chunkLength * initialDirection.getLadderVector().getBlockZ() + (platformWidth * chunkWight) * initialDirection.getPlatformVector().getBlockZ()+ 1; + int maxY = originY + levelAmount * 5 + 1; + return new Region(world, new Point(minX, originY, minZ), new Point(maxX, maxY, maxZ)); + } + return null; + } + + @Override + public int getHeight() { + return levelAmount * 5; + } + + private void transformXYZ(TransformType transformType, Direction direction, int type) { + if (transformType == TransformType.PLATFORM) { + if (type == 0) { + if (direction == Direction.EAST || direction == Direction.WEST) { + nowX += (platformLength * chunkWight) * direction.getPlatformVector().getX(); + nowZ += (platformWidth * chunkLength - 1) * direction.getPlatformVector().getZ(); + } else if (direction == Direction.NORTH || direction == Direction.SOUTH) { + nowX += (platformWidth * chunkLength - 1) * direction.getPlatformVector().getX(); + nowZ += (platformLength * chunkWight) * direction.getPlatformVector().getZ(); + } + } else if (type == 1) { + if (direction == Direction.EAST || direction == Direction.WEST) { + nowX += (platformLength * chunkWight - 1) * direction.getPlatformVector().getX(); + } else if (direction == Direction.NORTH || direction == Direction.SOUTH) { + nowZ += (platformLength * chunkWight - 1) * direction.getPlatformVector().getZ(); + } + switch (nowDirection) { + case EAST: + nowZ += 1; + break; + case SOUTH: + nowX -= 1; + break; + case WEST: + nowZ -= 1; + break; + case NORTH: + nowX += 1; + break; + } + } + } else if (transformType == TransformType.LADDER) { + nowY += ladderAmount; + if (direction == Direction.EAST || direction == Direction.WEST) { + nowX += (ladderAmount * chunkWight) * direction.getLadderVector().getBlockX(); + } else if (direction == Direction.NORTH || direction == Direction.SOUTH) { + nowZ += (ladderAmount * chunkWight) * direction.getLadderVector().getBlockZ(); + } + } + } + + } + + public void setInitialDirection(Direction initialDirection) { + this.initialDirection = initialDirection; + } + + private interface ISpawnModeHander { + void spawn(); + + Region getEffectiveRegion(World world); + + int getHeight(); + } + + public Material getRandomMaterial() { + return materials.get(RandomUtil.getRandomInt(0, materials.size() - 1)); + } + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/util/ColorUtil.java b/src/main/java/com/io/yutian/colorblindwar/util/ColorUtil.java new file mode 100644 index 0000000..3ed0268 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/util/ColorUtil.java @@ -0,0 +1,77 @@ +package com.io.yutian.colorblindwar.util; + +import org.bukkit.Material; + +public class ColorUtil { + + public static String getColorName(Material material) { + switch (material) { + case WHITE_WOOL: + return "白色"; + case BLACK_WOOL: + return "黑色"; + case BROWN_WOOL: + return "棕色"; + case BLUE_WOOL: + return "蓝色"; + case GREEN_WOOL: + return "绿色"; + case RED_WOOL: + return "红色"; + case YELLOW_WOOL: + return "黄色"; + case PURPLE_WOOL: + return "紫色"; + case ORANGE_WOOL: + return "橙色"; + case PINK_WOOL: + return "粉色"; + case LIGHT_BLUE_WOOL: + return "淡蓝色"; + case LIME_WOOL: + return "黄绿色"; + default: + return "未知"; + } + } + + public static String getColorHex(Material material) { + switch (material) { + case WHITE_WOOL: + return "#DDDDDD"; + case ORANGE_WOOL: + return "#DB7D3E"; + case MAGENTA_WOOL: + return "#B350BC"; + case LIGHT_BLUE_WOOL: + return "#6B8AC9"; + case YELLOW_WOOL: + return "#E0C240"; + case LIME_WOOL: + return "#41AE38"; + case PINK_WOOL: + return "#D08499"; + case GRAY_WOOL: + return "#404040"; + case LIGHT_GRAY_WOOL: + return "#9A9A9A"; + case CYAN_WOOL: + return "#2E6E89"; + case PURPLE_WOOL: + return "#7E3DB5"; + case BLUE_WOOL: + return "#2E388D"; + case BROWN_WOOL: + return "#4F321F"; + case GREEN_WOOL: + return "#35461B"; + case RED_WOOL: + return "#C05A5A"; + case BLACK_WOOL: + return "#191616"; + default: + return "#000000"; + } + } + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/util/MathUtil.java b/src/main/java/com/io/yutian/colorblindwar/util/MathUtil.java new file mode 100644 index 0000000..f59f303 --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/util/MathUtil.java @@ -0,0 +1,29 @@ +package com.io.yutian.colorblindwar.util; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +public class MathUtil { + + public static double round(double d) { + return new BigDecimal(Double.toString(d)).setScale(2, RoundingMode.HALF_UP).doubleValue(); + } + + public static double round(double d, int scale) { + return new BigDecimal(Double.toString(d)).setScale(scale, RoundingMode.HALF_UP).doubleValue(); + } + + public static int clamp(int value, int min, int max) { + return Math.max(min, Math.min(max, value)); + } + + public static double clamp(double value, double min, double max) { + return Math.max(min, Math.min(max, value)); + } + + public static float clamp(float value, float min, float max) { + return Math.max(min, Math.min(max, value)); + } + + +} diff --git a/src/main/java/com/io/yutian/colorblindwar/util/RandomUtil.java b/src/main/java/com/io/yutian/colorblindwar/util/RandomUtil.java new file mode 100644 index 0000000..0643cff --- /dev/null +++ b/src/main/java/com/io/yutian/colorblindwar/util/RandomUtil.java @@ -0,0 +1,45 @@ +package com.io.yutian.colorblindwar.util; + +import com.io.yutian.colorblindwar.game.Point; +import com.io.yutian.colorblindwar.game.Region; +import org.bukkit.Location; +import org.bukkit.World; + +import java.util.Random; + +public class RandomUtil { + + public static Location getRandomLocation(Region region) { + Point min = region.getMin(); + Point max = region.getMax(); + return getRandomLocation(region.getWorld(), min.getX(), max.getX(), min.getY(), max.getY(), min.getZ(), max.getZ()); + } + + public static boolean random(double d) { + return d >= new Random().nextFloat(); + } + + 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; + } + +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..bfc5249 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,2 @@ +completeAmount: 10 +countdownTime: 10 \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..86a43e5 --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,9 @@ +name: ColorblindWar +version: '${project.version}' +main: com.io.yutian.colorblindwar.ColorblindWar +api-version: '1.18' +depend: + - WorldEdit +commands: + colorblindwar: + aliases: [cw] \ No newline at end of file