From 9d34f9886a1c5e2f0e48fe938f6a7a0f95268e48 Mon Sep 17 00:00:00 2001
From: Anonymus Raccoon
Date: Mon, 2 Nov 2020 01:14:10 +0100
Subject: [PATCH] Adding map creation, lobby location calculation & spawn
calculations
---
.../java/moe/sdg/PluginSDG/GameManager.java | 109 +++++++++++++++---
src/main/java/moe/sdg/PluginSDG/GameMap.java | 34 ++++++
src/main/java/moe/sdg/PluginSDG/GameType.java | 1 +
src/main/java/moe/sdg/PluginSDG/MiniGame.java | 10 +-
.../java/moe/sdg/PluginSDG/TeamMiniGame.java | 4 +-
.../sdg/PluginSDG/commands/SDGCommand.java | 67 ++++++++---
.../exceptions/InvalidMapException.java | 10 ++
.../PluginSDG/exceptions/MapException.java | 3 +
.../exceptions/MapNotFoundException.java | 10 ++
.../moe/sdg/PluginSDG/games/DeathMatch.java | 2 +-
10 files changed, 205 insertions(+), 45 deletions(-)
create mode 100644 src/main/java/moe/sdg/PluginSDG/GameMap.java
create mode 100644 src/main/java/moe/sdg/PluginSDG/exceptions/InvalidMapException.java
create mode 100644 src/main/java/moe/sdg/PluginSDG/exceptions/MapException.java
create mode 100644 src/main/java/moe/sdg/PluginSDG/exceptions/MapNotFoundException.java
diff --git a/src/main/java/moe/sdg/PluginSDG/GameManager.java b/src/main/java/moe/sdg/PluginSDG/GameManager.java
index b1a3e53..303135b 100644
--- a/src/main/java/moe/sdg/PluginSDG/GameManager.java
+++ b/src/main/java/moe/sdg/PluginSDG/GameManager.java
@@ -1,22 +1,44 @@
package moe.sdg.PluginSDG;
+import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
+import com.sk89q.worldedit.WorldEditException;
+import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
+import com.sk89q.worldedit.extent.clipboard.Clipboard;
+import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
+import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats;
+import com.sk89q.worldedit.extent.clipboard.io.ClipboardReader;
+import com.sk89q.worldedit.function.operation.Operation;
+import com.sk89q.worldedit.function.operation.Operations;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.session.ClipboardHolder;
import moe.sdg.PluginSDG.commands.SDGCommand;
+import moe.sdg.PluginSDG.exceptions.InvalidMapException;
+import moe.sdg.PluginSDG.exceptions.MapNotFoundException;
import moe.sdg.PluginSDG.games.DeathMatch;
import moe.sdg.PluginSDG.commands.HubCommand;
import moe.sdg.PluginSDG.commands.SetHubCommand;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
+import org.bukkit.*;
import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.generator.BlockPopulator;
+import org.bukkit.generator.ChunkGenerator;
import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.util.Vector;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
import java.util.stream.Collectors;
public class GameManager extends JavaPlugin
{
private ArrayList _games;
private WorldEditPlugin _worldEdit;
+ private Vector nextGameLocation = new Vector(0, 150, 0);
@SuppressWarnings("ConstantConditions")
@Override
@@ -59,7 +81,7 @@ public class GameManager extends JavaPlugin
switch (type)
{
case DeathMatch:
- DeathMatch match = new DeathMatch(this, map, gameName != null ? gameName : this.generateNewName());
+ DeathMatch match = new DeathMatch(this, map, gameName);
this._games.add(match);
return match;
@@ -68,21 +90,6 @@ public class GameManager extends JavaPlugin
}
}
- public MiniGame createGame(GameType type, String map)
- {
- return this.createGame(type,map,null);
- }
-
- //! @brief generate a new possible game name of the form
- //! @return
- private String generateNewName()
- {
- String name = "Unnamed " + Math.random();
- if (this.getGameByName(name) != null)
- return this.generateNewName();
- return name;
- }
-
//! @brief delete a game
//! @param game the game to be deleted
public void deleteGame(MiniGame game)
@@ -112,4 +119,70 @@ public class GameManager extends JavaPlugin
.findFirst()
.orElse(null);
}
+
+ public GameMap generateMap(String name)
+ {
+ File dir = new File(this.getDataFolder(), "map");
+ if (!dir.exists())
+ throw new MapNotFoundException();
+
+ File file = new File(dir, name + ".schematic");
+ if (!file.exists())
+ throw new MapNotFoundException();
+ ClipboardFormat format = ClipboardFormats.findByFile(file);
+ if (format == null)
+ throw new InvalidMapException();
+ try (ClipboardReader reader = format.getReader(new FileInputStream(file)))
+ {
+ Clipboard clipboard = reader.read();
+ World world = this._getGameWorld();
+ try (EditSession editSession = WorldEdit.getInstance()
+ .getEditSessionFactory()
+ .getEditSession(BukkitAdapter.adapt(world), -1))
+ {
+ Operation operation = new ClipboardHolder(clipboard)
+ .createPaste(editSession)
+ .to(BlockVector3.at(nextGameLocation.getX(), nextGameLocation.getY(), nextGameLocation.getZ()))
+ .build();
+ Operations.complete(operation);
+ clipboard.setOrigin(BlockVector3.at(nextGameLocation.getX(), nextGameLocation.getY(), nextGameLocation.getZ()));
+ nextGameLocation.add(new Vector(200, 0, 0));
+ return new GameMap(clipboard, world);
+ }
+ }
+ catch (IOException | WorldEditException e)
+ {
+ e.printStackTrace();
+ throw new InvalidMapException();
+ }
+ }
+
+ private World _getGameWorld()
+ {
+ World world = Bukkit.getWorld("sdg_games");
+ if (world != null)
+ return world;
+ return Bukkit.createWorld(new WorldCreator("sdg_games")
+ .type(WorldType.FLAT)
+ .generator(new ChunkGenerator()
+ {
+ @Override
+ public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome)
+ {
+ return createChunkData(world);
+ }
+
+ @Override
+ public boolean shouldGenerateMobs()
+ {
+ return false;
+ }
+
+ @Override
+ public List getDefaultPopulators(World world)
+ {
+ return new ArrayList<>();
+ }
+ }));
+ }
}
diff --git a/src/main/java/moe/sdg/PluginSDG/GameMap.java b/src/main/java/moe/sdg/PluginSDG/GameMap.java
new file mode 100644
index 0000000..eafea29
--- /dev/null
+++ b/src/main/java/moe/sdg/PluginSDG/GameMap.java
@@ -0,0 +1,34 @@
+package moe.sdg.PluginSDG;
+
+import com.sk89q.worldedit.bukkit.BukkitAdapter;
+import com.sk89q.worldedit.extent.clipboard.Clipboard;
+import com.sk89q.worldedit.math.BlockVector3;
+import com.sk89q.worldedit.world.block.BlockState;
+import com.sk89q.worldedit.world.block.BlockType;
+import org.bukkit.Location;
+import org.bukkit.World;
+import java.util.ArrayList;
+
+public class GameMap
+{
+ public Location lobbyLocation;
+
+ public ArrayList spawnLocations;
+
+ public GameMap() { }
+
+ public GameMap(Clipboard clipboard, World world)
+ {
+ BlockVector3 o = clipboard.getOrigin();
+ this.lobbyLocation = new Location(world, o.getX(), o.getY(), o.getZ());
+ for (BlockVector3 b : clipboard.getRegion())
+ {
+ BlockState state = clipboard.getBlock(b);
+ if (state.getBlockType() == BlockType.REGISTRY.get("minecraft:respawn_anchor"))
+ {
+ System.out.println("RESPAWN BLOCK");
+ this.spawnLocations.add(new Location(world, b.getX(), b.getY(), b.getZ()));
+ }
+ }
+ }
+}
diff --git a/src/main/java/moe/sdg/PluginSDG/GameType.java b/src/main/java/moe/sdg/PluginSDG/GameType.java
index d2e3bda..448ffba 100644
--- a/src/main/java/moe/sdg/PluginSDG/GameType.java
+++ b/src/main/java/moe/sdg/PluginSDG/GameType.java
@@ -2,5 +2,6 @@ package moe.sdg.PluginSDG;
public enum GameType
{
+ None,
DeathMatch
}
diff --git a/src/main/java/moe/sdg/PluginSDG/MiniGame.java b/src/main/java/moe/sdg/PluginSDG/MiniGame.java
index 8dbea21..a565a02 100644
--- a/src/main/java/moe/sdg/PluginSDG/MiniGame.java
+++ b/src/main/java/moe/sdg/PluginSDG/MiniGame.java
@@ -8,17 +8,17 @@ public abstract class MiniGame
{
private final ArrayList _players;
private final GameManager _manager;
- private final Location _lobbyLocation;
+ private final GameMap _map;
private final String name;
protected int _maxPlayer = 4;
protected boolean enforceMaxPlayer = true;
- public MiniGame(GameManager manager, String name)
+ public MiniGame(GameManager manager, String mapName, String name)
{
this._manager = manager;
- this._lobbyLocation = null;
- this._players = new ArrayList();
+ this._map = this._manager.generateMap(mapName);;
+ this._players = new ArrayList<>();
this.name = name;
}
@@ -41,7 +41,7 @@ public abstract class MiniGame
if (this.getMaxPlayers() < this.getCurrentPlayers() + 1)
return false;
this._players.add(player);
- player.teleport(this._lobbyLocation);
+ player.teleport(this._map.lobbyLocation);
return true;
}
diff --git a/src/main/java/moe/sdg/PluginSDG/TeamMiniGame.java b/src/main/java/moe/sdg/PluginSDG/TeamMiniGame.java
index 5f3a04a..67fe245 100644
--- a/src/main/java/moe/sdg/PluginSDG/TeamMiniGame.java
+++ b/src/main/java/moe/sdg/PluginSDG/TeamMiniGame.java
@@ -38,9 +38,9 @@ public abstract class TeamMiniGame extends MiniGame
private final ArrayList _teams;
- public TeamMiniGame(GameManager manager, String gameName)
+ public TeamMiniGame(GameManager manager, String map, String gameName)
{
- super(manager, gameName);
+ super(manager, map, gameName);
this._teams = new ArrayList();
}
diff --git a/src/main/java/moe/sdg/PluginSDG/commands/SDGCommand.java b/src/main/java/moe/sdg/PluginSDG/commands/SDGCommand.java
index a6844aa..7359b1c 100644
--- a/src/main/java/moe/sdg/PluginSDG/commands/SDGCommand.java
+++ b/src/main/java/moe/sdg/PluginSDG/commands/SDGCommand.java
@@ -8,17 +8,19 @@ import com.sk89q.worldedit.extent.clipboard.io.BuiltInClipboardFormat;
import com.sk89q.worldedit.extent.clipboard.io.ClipboardWriter;
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
import com.sk89q.worldedit.function.operation.Operations;
+import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.Region;
+import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.io.Closer;
import moe.sdg.PluginSDG.GameManager;
import moe.sdg.PluginSDG.GameType;
import moe.sdg.PluginSDG.MiniGame;
+import moe.sdg.PluginSDG.exceptions.MapException;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-
import java.awt.*;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -92,28 +94,48 @@ public class SDGCommand implements CommandExecutor
return;
}
+ GameType type = GameType.None;
switch (args[1].toLowerCase())
{
case "deathmatch":
- if (args.length == 3)
- {
- _gameManager.createGame(GameType.DeathMatch, args[2]);
- commandSender.sendMessage(ChatColor.BLUE + "Created deathmatch game with a default name since no name where precised");
- }
- else
- {
- if (_gameManager.getGameByName(args[3]) != null)
- commandSender.sendMessage(ChatColor.BLUE + "Name is already used" + args[0]);
- else
- {
- _gameManager.createGame(GameType.DeathMatch, args[2], args[3]);
- commandSender.sendMessage(ChatColor.BLUE + "Created deathmatch game");
- }
- }
+ type = GameType.DeathMatch;
break;
default:
commandSender.sendMessage(ChatColor.BLUE + "Unknown game type " + args[1]);
- break;
+ return;
+ }
+
+ try
+ {
+ MiniGame game = null;
+ if (args.length == 3)
+ {
+ int i = 1;
+ String name = null;
+ while (name == null || _gameManager.getGameByName(name) != null)
+ name = commandSender.getName() + "#" + i++;
+ game = _gameManager.createGame(type, args[2], name);
+ commandSender.sendMessage(ChatColor.BLUE + "Created deathmatch game with a default name since no name where precised");
+ }
+ else
+ {
+ if (args[3].contains(" "))
+ commandSender.sendMessage(ChatColor.BLUE + "A game can't have a space in it's name.");
+ else if (_gameManager.getGameByName(args[3]) != null)
+ commandSender.sendMessage(ChatColor.BLUE + "Name is already used" + args[0]);
+ else
+ {
+ game = _gameManager.createGame(type, args[2], args[3]);
+ commandSender.sendMessage(ChatColor.BLUE + "Created deathmatch game");
+ }
+ }
+
+ if (commandSender instanceof Player && game != null)
+ game.join((Player)commandSender);
+ }
+ catch (MapException e)
+ {
+ commandSender.sendMessage(e.toString());
}
}
@@ -240,14 +262,21 @@ public class SDGCommand implements CommandExecutor
{
Region region = session.getSelection(wePlayer.getWorld());
Clipboard cb = new BlockArrayClipboard(region);
+ cb.setOrigin(session.getPlacementPosition(wePlayer));
ForwardExtentCopy copy = new ForwardExtentCopy(editSession, region, cb, region.getMinimumPoint());
+ copy.setCopyingEntities(true);
+ copy.setCopyingBiomes(true);
Operations.complete(copy);
LocalConfiguration config = this._worldEdit.getWorldEdit().getConfiguration();
File dir = new File(this._gameManager.getDataFolder(), args[1]);
if (!dir.exists() && !dir.mkdirs())
throw new IOException("Could not create directory " + config.saveDir);
File schematicFile = new File(dir, args[2] + ".schematic");
- schematicFile.createNewFile();
+ if (!schematicFile.createNewFile())
+ {
+ player.sendMessage("A map with the same name already exists.");
+ return;
+ }
FileOutputStream fos = closer.register(new FileOutputStream(schematicFile));
BufferedOutputStream bos = closer.register(new BufferedOutputStream(fos));
@@ -267,6 +296,6 @@ public class SDGCommand implements CommandExecutor
}
catch (IOException ignore) { }
}
- player.sendMessage(Color.BLUE + "Map saved successfully.");
+ player.sendMessage(ChatColor.BLUE + "Map saved successfully.");
}
}
diff --git a/src/main/java/moe/sdg/PluginSDG/exceptions/InvalidMapException.java b/src/main/java/moe/sdg/PluginSDG/exceptions/InvalidMapException.java
new file mode 100644
index 0000000..4c22d9b
--- /dev/null
+++ b/src/main/java/moe/sdg/PluginSDG/exceptions/InvalidMapException.java
@@ -0,0 +1,10 @@
+package moe.sdg.PluginSDG.exceptions;
+
+public class InvalidMapException extends MapException
+{
+ @Override
+ public String toString()
+ {
+ return "The specified map is invalid or corrupted and couldn't be loaded.";
+ }
+}
diff --git a/src/main/java/moe/sdg/PluginSDG/exceptions/MapException.java b/src/main/java/moe/sdg/PluginSDG/exceptions/MapException.java
new file mode 100644
index 0000000..1359c19
--- /dev/null
+++ b/src/main/java/moe/sdg/PluginSDG/exceptions/MapException.java
@@ -0,0 +1,3 @@
+package moe.sdg.PluginSDG.exceptions;
+
+public class MapException extends RuntimeException { }
diff --git a/src/main/java/moe/sdg/PluginSDG/exceptions/MapNotFoundException.java b/src/main/java/moe/sdg/PluginSDG/exceptions/MapNotFoundException.java
new file mode 100644
index 0000000..5d1ebd9
--- /dev/null
+++ b/src/main/java/moe/sdg/PluginSDG/exceptions/MapNotFoundException.java
@@ -0,0 +1,10 @@
+package moe.sdg.PluginSDG.exceptions;
+
+public class MapNotFoundException extends MapException
+{
+ @Override
+ public String toString()
+ {
+ return "The specified map couldn't be found.";
+ }
+}
diff --git a/src/main/java/moe/sdg/PluginSDG/games/DeathMatch.java b/src/main/java/moe/sdg/PluginSDG/games/DeathMatch.java
index c4d04a5..3894944 100644
--- a/src/main/java/moe/sdg/PluginSDG/games/DeathMatch.java
+++ b/src/main/java/moe/sdg/PluginSDG/games/DeathMatch.java
@@ -11,7 +11,7 @@ public class DeathMatch extends MiniGame
public DeathMatch(GameManager gameManager, String map, String name)
{
- super(gameManager, name);
+ super(gameManager, map, name);
}
@Override