From 63354c563fa692021f5ab381e989db6ba79e213c Mon Sep 17 00:00:00 2001 From: LunarAkai Date: Tue, 19 Mar 2024 23:25:18 +0100 Subject: [PATCH] first commit --- .gitignore | 3 + Minecleaner.iml | 12 + pom.xml | 84 +++++++ .../de/lunarakai/minecleaner/ArenaList.java | 94 +++++++ .../de/lunarakai/minecleaner/ArenaStatus.java | 8 + .../minecleaner/MinecleanerArena.java | 110 ++++++++ .../minecleaner/MinecleanerListener.java | 53 ++++ .../minecleaner/MinecleanerManager.java | 33 +++ .../minecleaner/MinecleanerPlugin.java | 51 ++++ .../de/lunarakai/minecleaner/game/Board.java | 54 ++++ .../lunarakai/minecleaner/game/BoardSize.java | 17 ++ .../de/lunarakai/minecleaner/game/Cell.java | 29 +++ .../de/lunarakai/minecleaner/game/Game.java | 235 ++++++++++++++++++ .../de/lunarakai/minecleaner/game/Tile.java | 34 +++ .../lunarakai/minecleaner/game/Tilemap.java | 39 +++ .../minecleaner/utils/BoardUtils.java | 14 ++ .../minecleaner/utils/MathUtils.java | 7 + src/main/resources/mcl_arenas.yml | 0 src/main/resources/plugin.yml | 8 + 19 files changed, 885 insertions(+) create mode 100644 .gitignore create mode 100644 Minecleaner.iml create mode 100644 pom.xml create mode 100644 src/main/java/de/lunarakai/minecleaner/ArenaList.java create mode 100644 src/main/java/de/lunarakai/minecleaner/ArenaStatus.java create mode 100644 src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java create mode 100644 src/main/java/de/lunarakai/minecleaner/MinecleanerListener.java create mode 100644 src/main/java/de/lunarakai/minecleaner/MinecleanerManager.java create mode 100644 src/main/java/de/lunarakai/minecleaner/MinecleanerPlugin.java create mode 100644 src/main/java/de/lunarakai/minecleaner/game/Board.java create mode 100644 src/main/java/de/lunarakai/minecleaner/game/BoardSize.java create mode 100644 src/main/java/de/lunarakai/minecleaner/game/Cell.java create mode 100644 src/main/java/de/lunarakai/minecleaner/game/Game.java create mode 100644 src/main/java/de/lunarakai/minecleaner/game/Tile.java create mode 100644 src/main/java/de/lunarakai/minecleaner/game/Tilemap.java create mode 100644 src/main/java/de/lunarakai/minecleaner/utils/BoardUtils.java create mode 100644 src/main/java/de/lunarakai/minecleaner/utils/MathUtils.java create mode 100644 src/main/resources/mcl_arenas.yml create mode 100644 src/main/resources/plugin.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b3e3d23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# Project exclude paths +/target/ +/.vscode \ No newline at end of file diff --git a/Minecleaner.iml b/Minecleaner.iml new file mode 100644 index 0000000..fa63d4b --- /dev/null +++ b/Minecleaner.iml @@ -0,0 +1,12 @@ + + + + + + + SPIGOT + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..e861afd --- /dev/null +++ b/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + de.lunarakai + Minecleaner + 1.0-SNAPSHOT + jar + + Minecleaner + + + 1.8 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 16 + 16 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + brokkonaut + https://www.iani.de/nexus/content/groups/public + + + + + + org.spigotmc + spigot-api + 1.20.4-R0.1-SNAPSHOT + provided + + + de.iani.cubeside + CubesideUtilsBukkit + 1.16-SNAPSHOT + provided + + + diff --git a/src/main/java/de/lunarakai/minecleaner/ArenaList.java b/src/main/java/de/lunarakai/minecleaner/ArenaList.java new file mode 100644 index 0000000..519a65d --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/ArenaList.java @@ -0,0 +1,94 @@ +package de.lunarakai.minecleaner; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.UUID; +import java.util.logging.Level; +import org.bukkit.Location; +import org.bukkit.block.Block; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; + +public class ArenaList { + private static final String ARENAS_FILENAME = "mcl_arenas.yml"; + private final MinecleanerPlugin plugin; + private File arenaFile; + private final HashMap arenas; + private final HashMap playersInArena; + private final HashMap arenaBlocks; + + public ArenaList(MinecleanerPlugin plugin) { + this.plugin = plugin; + this.arenas = new HashMap<>(); + this.arenaFile = new File(plugin.getDataFolder(), ARENAS_FILENAME); + this.arenaBlocks = new HashMap<>(); + this.playersInArena = new HashMap<>(); + } + + public void load() { + arenas.clear(); + if(!this.arenaFile.isFile()) { + return; + } + + YamlConfiguration conf = new YamlConfiguration(); + try { + conf.load(this.arenaFile); + } catch(IOException | InvalidConfigurationException e) { + plugin.getLogger().log(Level.SEVERE, "Could not load arenas file", e); + } + ConfigurationSection arenasSection = conf.getConfigurationSection("arenas"); + if(arenasSection != null) { + for(String arenaName : arenasSection.getKeys(false)) { + ConfigurationSection arenaSection = arenasSection.getConfigurationSection(arenaName); + if(arenaSection != null) { + MinecleanerArena arena = new MinecleanerArena(plugin, arenaSection); + this.arenas.put(arena.getName(), arena); + + } + } + } + } + + public void save() { + YamlConfiguration conf = new YamlConfiguration(); + ConfigurationSection arenaSection = conf.createSection("arenas"); + int i = 0; + for(MinecleanerArena arena : this.arenas.values()) { + arena.save(arenaSection.createSection(Integer.toString(i++))); + } + this.arenaFile.getParentFile().mkdirs(); + try { + conf.save(this.arenaFile); + } catch(IOException e) { + plugin.getLogger().log(Level.SEVERE, "Could not save arenas file", e); + } + } + + /*private void setArenaBlocks(MinecleanerArena arena) { + for(Location location : arena.getBlocks()) { + arenaBlocks + } + }*/ + + public void setArenaForPlayer(Player player, MinecleanerArena arena) { + if(arena != null) { + playersInArena.put(player.getUniqueId(), arena); + } else { + playersInArena.remove(player.getUniqueId()); + } + } + + public MinecleanerArena getPlayerArena(Player player) { + return playersInArena.get(player.getUniqueId()); + } + + public MinecleanerArena getArenaAtBlock(Block block) { + return arenaBlocks.get(block.getLocation()); + } + + +} diff --git a/src/main/java/de/lunarakai/minecleaner/ArenaStatus.java b/src/main/java/de/lunarakai/minecleaner/ArenaStatus.java new file mode 100644 index 0000000..c348494 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/ArenaStatus.java @@ -0,0 +1,8 @@ +package de.lunarakai.minecleaner; + +public enum ArenaStatus { + INACTIVE, + CONFIRM_PLAYING, + PLAYING, + COMPLETED +} diff --git a/src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java b/src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java new file mode 100644 index 0000000..b1ed6e1 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java @@ -0,0 +1,110 @@ +package de.lunarakai.minecleaner; + +import java.util.UUID; +import org.bukkit.Location; +import org.bukkit.block.BlockFace; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import com.google.common.base.Preconditions; +import de.lunarakai.minecleaner.game.Game; + +public class MinecleanerArena { + private final MinecleanerPlugin plugin; + private final String name; + private final Location location; + private final Location centerLocation; + private final BlockFace orientation; + private ArenaStatus arenaStatus = ArenaStatus.INACTIVE; + private UUID[] displayEntities; + + private Player currentPlayer; + private long currentGameStartTime; + private Game currentMinecleanerGame; + + public MinecleanerArena(MinecleanerPlugin plugin, ConfigurationSection arenaSection) { + this.plugin = plugin; + this.name = Preconditions.checkNotNull(arenaSection.getString("name")); + this.location = Preconditions.checkNotNull(arenaSection.getLocation("location")); + BlockFace orientation = BlockFace.NORTH; + try { + orientation = BlockFace.valueOf(arenaSection.getString("orientation")); + } catch(IllegalArgumentException ignored) { + + } + this.orientation = orientation; + + this.centerLocation = location.clone().add(0.5, 0, 0.5); + displayEntities = new UUID[Game.width * Game.height]; + } + + public MinecleanerArena(MinecleanerPlugin plugin, String name, Location location, BlockFace orientation) { + this.plugin = plugin; + this.name = Preconditions.checkNotNull(name, "name"); + this.location = Preconditions.checkNotNull(location, "location"); + Preconditions.checkArgument(Math.abs(orientation.getModX()) + Math.abs(orientation.getModZ()) == 1, "no cardinal direction"); + this.orientation = orientation; + int d0x = orientation.getModX(); + int d0z = orientation.getModZ(); + int d1x = -d0z; + int d1z = d0x; + this.centerLocation = location.clone().add(0.5, 0, 0.5); + } + + public void save(ConfigurationSection arenaSection) { + arenaSection.set("name", this.name); + arenaSection.set("location", this.location); + arenaSection.set("orientation", this.orientation.name()); + } + + public void startNewGame() { + currentMinecleanerGame.start(); + arenaStatus = ArenaStatus.PLAYING; + } + + public void removePlayer() { + this.arenaStatus = ArenaStatus.INACTIVE; + this.currentPlayer = null; + } + + public String getName() { + return name; + } + + public boolean hasPlayer() { + return currentPlayer != null; + } + + public Player getCurrentPlayer() { + return currentPlayer; + } + + public Location getLocation() { + return location; + } + + public ArenaStatus getArenaStatus() { + return arenaStatus; + } + + public void flagCell(int x, int y) { + if(currentMinecleanerGame != null) { + int id = x + y * 8; + boolean unflaggedCell = currentMinecleanerGame.flag(x, y); + if(!unflaggedCell) { + // todo set flag head on block display + } else { + // todo set normal head on block display + } + } + } + + public void revealCell(int x, int y) { + if(currentMinecleanerGame != null) { + int id = x + y * 8; + // todo check if cell is flagged already + currentMinecleanerGame.reveal(x, y); + // todo update block of blockdisplay + } + } + +} diff --git a/src/main/java/de/lunarakai/minecleaner/MinecleanerListener.java b/src/main/java/de/lunarakai/minecleaner/MinecleanerListener.java new file mode 100644 index 0000000..807d090 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/MinecleanerListener.java @@ -0,0 +1,53 @@ +package de.lunarakai.minecleaner; + +import org.bukkit.block.Block; +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.player.PlayerInteractEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.inventory.EquipmentSlot; +import net.md_5.bungee.api.ChatColor; + +public class MinecleanerListener implements Listener { + private final MinecleanerPlugin plugin; + + public MinecleanerListener(MinecleanerPlugin plugin) { + this.plugin = plugin; + } + + @EventHandler(priority = EventPriority.LOWEST) + public void onPlayerInteract(PlayerInteractEvent e) { + if((e.getAction() == Action.LEFT_CLICK_BLOCK || e.getAction() == Action.RIGHT_CLICK_BLOCK)) { + Block block = e.getClickedBlock(); + MinecleanerArena arena = plugin.getArenaList().getPlayerArena(e.getPlayer()); + if(arena != null) { + + // TODO + + } else { + arena = plugin.getArenaList().getArenaAtBlock(block); + if(arena != null) { + e.setCancelled(true); + if(e.getHand() == EquipmentSlot.HAND) { + if(arena.getArenaStatus() == ArenaStatus.INACTIVE) { + plugin.getManager().joinArena(e.getPlayer(), arena); + } else { + e.getPlayer().sendMessage(ChatColor.YELLOW + "Hier spielt schon jemand anderes"); + } + } + } + } + } + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent e) { + MinecleanerArena arena = plugin.getArenaList().getPlayerArena(e.getPlayer()); + if(arena != null) { + plugin.getManager().leaveArena(e.getPlayer(), false); + } + } + +} diff --git a/src/main/java/de/lunarakai/minecleaner/MinecleanerManager.java b/src/main/java/de/lunarakai/minecleaner/MinecleanerManager.java new file mode 100644 index 0000000..c7cc855 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/MinecleanerManager.java @@ -0,0 +1,33 @@ +package de.lunarakai.minecleaner; + +import org.bukkit.entity.Player; +import com.google.common.base.Preconditions; +import net.md_5.bungee.api.ChatColor; + +public class MinecleanerManager { + private final MinecleanerPlugin plugin; + + public MinecleanerManager(MinecleanerPlugin plugin) { + this.plugin = plugin; + } + + public void joinArena(Player player, MinecleanerArena arena) { + if (!player.hasPermission(MinecleanerPlugin.PERMISSION_PLAY)) { + return; + } + Preconditions.checkArgument(plugin.getArenaList().getPlayerArena(player) == null, "player is in an arena"); + Preconditions.checkArgument(arena.getArenaStatus() == ArenaStatus.INACTIVE, "arena is in use"); + arena.addJoiningPlayer(player); + plugin.getArenaList().setArenaForPlayer(player, arena); + } + + public void leaveArena(Player player, boolean message) { + MinecleanerArena arena = plugin.getArenaList().getPlayerArena(player); + Preconditions.checkArgument(arena != null, "player is in no arena"); + arena.removePlayer(); + plugin.getArenaList().setArenaForPlayer(player, null); + if(message) { + player.sendMessage(ChatColor.YELLOW + "Das Minecleanerspiel wurde abgebrochen."); + } + } +} diff --git a/src/main/java/de/lunarakai/minecleaner/MinecleanerPlugin.java b/src/main/java/de/lunarakai/minecleaner/MinecleanerPlugin.java new file mode 100644 index 0000000..846e3a8 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/MinecleanerPlugin.java @@ -0,0 +1,51 @@ +package de.lunarakai.minecleaner; + +import org.bukkit.plugin.java.JavaPlugin; + +public final class MinecleanerPlugin extends JavaPlugin { + + + // ------------------------------ + // TODO: start a new game (via ui) + // TODO: For testing purposes -> write coords of cell into chat + // Format: Cell(X,Y) - CellType: Type + // ------------------------------ + + public static final String PERMISSION_PLAY = "minecleaner.play"; + public static final String PERMISSION_ADMIN = "minecleaner.admin"; + + private MinecleanerManager minecleanerManager; + private ArenaList arenaList; + + @Override + public void onEnable() { + // Plugin startup logic + + arenaList = new ArenaList(this); + arenaList.load(); + + //CommandRouter minecleanerCommand = new CommandRouter(getCommand("minecleaner")); + //minecleanerCommand.addCommandMapping(new CreateCommand(this), "create"); + //minecleanerCommand.addCommandMapping(new DeleteCommand(this), "delete"); + //minecleanerCommand.addCommandMapping(new ListCommand(this), "list"); + + + + //Test Commands + //minecleanerCommand.addCommandMapping(new TestCommand(this), "testSingle"); + //minecleanerCommand.addCommandMapping(new TestArrayCommand(this), "testArray"); + } + + @Override + public void onDisable() { + // Plugin shutdown logic + } + + public ArenaList getArenaList() { + return arenaList; + } + + public MinecleanerManager getManager() { + return minecleanerManager; + } +} diff --git a/src/main/java/de/lunarakai/minecleaner/game/Board.java b/src/main/java/de/lunarakai/minecleaner/game/Board.java new file mode 100644 index 0000000..bfaa507 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/game/Board.java @@ -0,0 +1,54 @@ +package de.lunarakai.minecleaner.game; + +public class Board { + + public Tilemap tilemap; + + public void draw(Cell[][] state) { + tilemap.clearAllTiles(); + + int width = state[0].length; + int height = state[1].length; + + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + Cell cell = state[x][y]; + tilemap.setTile(cell.position, getTile(cell)); + } + } + } + + private Tile.TileType getTile(Cell cell) { + if(cell.revealed) { + return getRevealedTile(cell); + } else if (cell.flagged) { + return Tile.TileType.TileFlag; + } else { + return Tile.TileType.TileUnknown; + } + } + + private Tile.TileType getRevealedTile(Cell cell) { + switch (cell.type) { + case Empty: return Tile.TileType.TileEmpty; + case Mine: return cell.exploded ? Tile.TileType.TileExploded : Tile.TileType.TileMine; + case Number: return getNumberTile(cell); + default: return null; + } + } + + private Tile.TileType getNumberTile(Cell cell) { + switch (cell.number) { + case 1: return Tile.TileType.TileNum1; + case 2: return Tile.TileType.TileNum2; + case 3: return Tile.TileType.TileNum3; + case 4: return Tile.TileType.TileNum4; + case 5: return Tile.TileType.TileNum5; + case 6: return Tile.TileType.TileNum6; + case 7: return Tile.TileType.TileNum7; + case 8: return Tile.TileType.TileNum8; + default: return null; + } + } + +} diff --git a/src/main/java/de/lunarakai/minecleaner/game/BoardSize.java b/src/main/java/de/lunarakai/minecleaner/game/BoardSize.java new file mode 100644 index 0000000..789cc69 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/game/BoardSize.java @@ -0,0 +1,17 @@ +package de.lunarakai.minecleaner.game; + +public class BoardSize { + public int[] boardSizes = { + 8, + 16, + 32, // nicht größer als 24 + 64 + }; + + public int[] mineCounter = { + 10, + 40, + 128, + 512 + }; +} diff --git a/src/main/java/de/lunarakai/minecleaner/game/Cell.java b/src/main/java/de/lunarakai/minecleaner/game/Cell.java new file mode 100644 index 0000000..0e9ae5b --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/game/Cell.java @@ -0,0 +1,29 @@ +package de.lunarakai.minecleaner.game; + +import org.joml.Vector3i; + +public class Cell { + public enum CellType { + Invalid, + Empty, + Mine, + Number, + } + + + public Vector3i position; + public CellType type; + public int number; + public boolean revealed; + public boolean flagged; + public boolean exploded; + + public void setType(CellType type) { + this.type = type; + } + + public CellType getType() { + return type; + } + +} diff --git a/src/main/java/de/lunarakai/minecleaner/game/Game.java b/src/main/java/de/lunarakai/minecleaner/game/Game.java new file mode 100644 index 0000000..a0aa0d7 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/game/Game.java @@ -0,0 +1,235 @@ +package de.lunarakai.minecleaner.game; + +import org.joml.Vector3i; +import de.lunarakai.minecleaner.utils.MathUtils; + +public class Game { + + public static int width; + public static int height; + private int mineCount = 10; + private Cell[][] state; + private boolean gameover; + private Board board; + private BoardSize boardSize; + + private void onValidate() { + mineCount = MathUtils.clamp(mineCount, 0, width*height); + } + + public void start() { + int[] _boardSizes = boardSize.boardSizes; + int[] _mineCounter = boardSize.mineCounter; + + int _boardSizeIndex = 0; + width = _boardSizes[_boardSizeIndex]; + height = _boardSizes[_boardSizeIndex]; + mineCount = _mineCounter[_boardSizeIndex]; + + newGame(); + } + + private void newGame() { + state = new Cell[width][height]; + + gameover = false; + + generateCells(); + generateMines(); + generateNumbers(); + + board.draw(state); + } + + private void generateCells() { + for (int x = 0; x < width; x ++) { + for (int y = 0; y < height; y++) { + Cell cell = new Cell(); + cell.position = new Vector3i(x, 0, y); + cell.setType(Cell.CellType.Empty); + state[x][y] = cell; + } + } + } + + private void generateMines() { + for (int i = 0; i < mineCount; i++) { + int x = (int) (Math.random() * width); + int y = (int) (Math.random() * height); + + while (state[x][y].type == Cell.CellType.Mine) { + x++; + + if(x >= width) { + x = 0; + y++; + + if(y >= height) { + y=0; + } + } + } + state[x][y].setType(Cell.CellType.Mine); + } + } + + private void generateNumbers() { + for(int x = 0; x < width; x++) { + for(int y = 0; y < height; y++) { + Cell cell = state[x][y]; + + if(cell.getType() == Cell.CellType.Mine) { + continue; + } + + cell.number = countMines(x, y); + + if(cell.number > 0) { + cell.setType(Cell.CellType.Number); + } + + state[x][y] = cell; + } + } + } + + private int countMines(int cellX, int cellY) { + int count = 0; + + for (int adjacentX = -1; adjacentX <= 1; adjacentX++){ + for (int adjacentY = -1; adjacentY <= 1; adjacentY++) { + if(adjacentX == 0 && adjacentY == 0) { + continue; + } + + int x = cellX + adjacentX; + int y = cellY + adjacentY; + + if (getCell(x,y).getType() == Cell.CellType.Mine) { + count++; + } + } + } + return count; + } + + public boolean flag(int x, int y) { + // TODO: Vector3 worldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); <- Unity + //Vector3i cellPosition = null; // TODO board.tilemap.WorldToCell(worldPosition); <- Unity + Cell cell = getCell(x, y); + + if (cell.getType() == Cell.CellType.Invalid || cell.revealed) { + return false; + } + + boolean isFlaggedAlready = false; + if(cell.flagged) { + isFlaggedAlready = true; + } + + cell.flagged = !cell.flagged; + state[x][y] = cell; + board.draw(state); + return isFlaggedAlready; + } + + public boolean reveal(int x, int y) { + // TODO: Vector3 worldPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition); <- Unity + //Vector3i cellPosition = null; // TODO board.tilemap.WorldToCell(worldPosition); <- Unity + Cell cell = getCell(x, y); + + if(cell.getType() == Cell.CellType.Invalid || cell.revealed || cell.flagged) { + return false; + } + + boolean hitMine = false; + + switch (cell.getType()) { + case Mine: + explode(cell); + hitMine = true; + break; + case Empty: + flood(cell); + checkWinCondition(); + break; + default: + cell.revealed = true; + state[x][y] = cell; + checkWinCondition(); + break; + } + board.draw(state); + return hitMine; + } + + public void flood(Cell cell) { + if(cell.revealed) return; + if(cell.getType() == Cell.CellType.Mine || cell.getType() == Cell.CellType.Invalid) return; + + cell.revealed = true; + state[cell.position.x][cell.position.z] = cell; + + if(cell.getType() == Cell.CellType.Empty) { + flood(getCell(cell.position.x -1, cell.position.z)); + flood(getCell(cell.position.x +1, cell.position.z)); + flood(getCell(cell.position.x, cell.position.z -1)); + flood(getCell(cell.position.x, cell.position.z +1)); + } + + // TODO return cellpos of flooded cell to update the block displays + } + + private void explode(Cell cell) { + gameover = true; + cell.revealed = true; + cell.exploded = true; + state[cell.position.x][cell.position.z] = cell; + + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + cell = state[x][y]; + if(cell.getType() == Cell.CellType.Mine) { + cell.revealed = true; + state[x][y] = cell; + } + } + } + } + + private void checkWinCondition() { + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + Cell cell = state[x][y]; + if(cell.getType() != Cell.CellType.Mine && !cell.revealed) { + return; + } + } + } + + gameover = true; + + for(int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + Cell cell = state[x][y]; + + if(cell.getType() == Cell.CellType.Mine) { + cell.flagged = true; + state[x][y] = cell; + } + } + } + } + + private Cell getCell(int x, int y) { + if(isValid(x,y)) { + return state[x][y]; + } else { + return new Cell(); + } + } + + private boolean isValid(int x, int y) { + return x >= 0 && x < width && y >= 0 && y < height; + } +} diff --git a/src/main/java/de/lunarakai/minecleaner/game/Tile.java b/src/main/java/de/lunarakai/minecleaner/game/Tile.java new file mode 100644 index 0000000..96c0789 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/game/Tile.java @@ -0,0 +1,34 @@ +package de.lunarakai.minecleaner.game; + +public class Tile { + public enum TileType { + TileUnknown, + TileNum1, + TileNum2, + TileNum3, + TileNum4, + TileNum5, + TileNum6, + TileNum7, + TileNum8, + TileEmpty, + TileMine, + TileExploded, + TileFlag, + + } + + public Tile.TileType tileType; + + public Tile() { + setTileType(TileType.TileUnknown); + } + + public void setTileType(Tile.TileType tileType) { + this.tileType = tileType; + } + + public Tile.TileType getTileType() { + return tileType; + } +} diff --git a/src/main/java/de/lunarakai/minecleaner/game/Tilemap.java b/src/main/java/de/lunarakai/minecleaner/game/Tilemap.java new file mode 100644 index 0000000..03c51c5 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/game/Tilemap.java @@ -0,0 +1,39 @@ +package de.lunarakai.minecleaner.game; + +import org.joml.Vector3i; + +public class Tilemap { + + private Tile[][] tiles; + + public Tilemap(Tile[][] tiles) { + this.tiles = tiles; + } + + public void clearAllTiles() { + for(int i = 0; i < tiles.length; i++) { + for(int j = 0; j < tiles[0].length; j++) { + tiles[i][j] = new Tile(); + } + } + } + + public Tile getTile(int x, int y) { + if (x >= 0 && x < tiles.length && y >= 0 && y < tiles[0].length) { + return tiles[x][y]; + } else { + throw new IllegalArgumentException("Invalid coordinates"); + } + } + // Set method + public void setTile(Vector3i pos, Tile.TileType tileType) { + int x = pos.x(); + int y = pos.z(); + + if (x >= 0 && x < tiles.length && y >= 0 && y < tiles[0].length) { + tiles[x][y].setTileType(tileType); + } else { + throw new IllegalArgumentException("Invalid coordinates"); + } + } +} diff --git a/src/main/java/de/lunarakai/minecleaner/utils/BoardUtils.java b/src/main/java/de/lunarakai/minecleaner/utils/BoardUtils.java new file mode 100644 index 0000000..a7bc4d2 --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/utils/BoardUtils.java @@ -0,0 +1,14 @@ +package de.lunarakai.minecleaner.utils; + +import org.bukkit.entity.Display; +import de.lunarakai.minecleaner.game.Tile; + +public class BoardUtils { + public static Display matchTileToBlockDisplay(Tile tile) { + + switch (tile.getTileType()) { + case TileEmpty: + } + return null; + } +} diff --git a/src/main/java/de/lunarakai/minecleaner/utils/MathUtils.java b/src/main/java/de/lunarakai/minecleaner/utils/MathUtils.java new file mode 100644 index 0000000..69ccdcf --- /dev/null +++ b/src/main/java/de/lunarakai/minecleaner/utils/MathUtils.java @@ -0,0 +1,7 @@ +package de.lunarakai.minecleaner.utils; + +public class MathUtils { + public static int clamp(int value, int min, int max) { + return Math.max(min, Math.min(max, value)); + } +} diff --git a/src/main/resources/mcl_arenas.yml b/src/main/resources/mcl_arenas.yml new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..6cc291e --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,8 @@ +name: Minecleaner +version: '${project.version}' +main: de.lunarakai.minecleaner.MinecleanerPlugin +api-version: '1.20' +commands: + minecleaner: + description: main command + aliases: "mcl" \ No newline at end of file