first commit
This commit is contained in:
commit
63354c563f
19 changed files with 885 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# Project exclude paths
|
||||
/target/
|
||||
/.vscode
|
||||
12
Minecleaner.iml
Normal file
12
Minecleaner.iml
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="minecraft" name="Minecraft">
|
||||
<configuration>
|
||||
<autoDetectTypes>
|
||||
<platformType>SPIGOT</platformType>
|
||||
</autoDetectTypes>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
</module>
|
||||
84
pom.xml
Normal file
84
pom.xml
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>de.lunarakai</groupId>
|
||||
<artifactId>Minecleaner</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>Minecleaner</name>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>16</source>
|
||||
<target>16</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigotmc-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/groups/public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>brokkonaut</id>
|
||||
<url>https://www.iani.de/nexus/content/groups/public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.iani.cubeside</groupId>
|
||||
<artifactId>CubesideUtilsBukkit</artifactId>
|
||||
<version>1.16-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
94
src/main/java/de/lunarakai/minecleaner/ArenaList.java
Normal file
94
src/main/java/de/lunarakai/minecleaner/ArenaList.java
Normal file
|
|
@ -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<String, MinecleanerArena> arenas;
|
||||
private final HashMap<UUID, MinecleanerArena> playersInArena;
|
||||
private final HashMap<Location, MinecleanerArena> 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());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
8
src/main/java/de/lunarakai/minecleaner/ArenaStatus.java
Normal file
8
src/main/java/de/lunarakai/minecleaner/ArenaStatus.java
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package de.lunarakai.minecleaner;
|
||||
|
||||
public enum ArenaStatus {
|
||||
INACTIVE,
|
||||
CONFIRM_PLAYING,
|
||||
PLAYING,
|
||||
COMPLETED
|
||||
}
|
||||
110
src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java
Normal file
110
src/main/java/de/lunarakai/minecleaner/MinecleanerArena.java
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
54
src/main/java/de/lunarakai/minecleaner/game/Board.java
Normal file
54
src/main/java/de/lunarakai/minecleaner/game/Board.java
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
17
src/main/java/de/lunarakai/minecleaner/game/BoardSize.java
Normal file
17
src/main/java/de/lunarakai/minecleaner/game/BoardSize.java
Normal file
|
|
@ -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
|
||||
};
|
||||
}
|
||||
29
src/main/java/de/lunarakai/minecleaner/game/Cell.java
Normal file
29
src/main/java/de/lunarakai/minecleaner/game/Cell.java
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
235
src/main/java/de/lunarakai/minecleaner/game/Game.java
Normal file
235
src/main/java/de/lunarakai/minecleaner/game/Game.java
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
34
src/main/java/de/lunarakai/minecleaner/game/Tile.java
Normal file
34
src/main/java/de/lunarakai/minecleaner/game/Tile.java
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
39
src/main/java/de/lunarakai/minecleaner/game/Tilemap.java
Normal file
39
src/main/java/de/lunarakai/minecleaner/game/Tilemap.java
Normal file
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/main/java/de/lunarakai/minecleaner/utils/BoardUtils.java
Normal file
14
src/main/java/de/lunarakai/minecleaner/utils/BoardUtils.java
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
0
src/main/resources/mcl_arenas.yml
Normal file
0
src/main/resources/mcl_arenas.yml
Normal file
8
src/main/resources/plugin.yml
Normal file
8
src/main/resources/plugin.yml
Normal file
|
|
@ -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"
|
||||
Loading…
Add table
Add a link
Reference in a new issue