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