Adding map creation, lobby location calculation & spawn calculations

This commit is contained in:
Anonymus Raccoon
2020-11-02 01:14:10 +01:00
parent d3cd4b60cc
commit 9d34f9886a
10 changed files with 205 additions and 45 deletions

View File

@@ -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<MiniGame> _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 <unnamed: number>
//! @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<BlockPopulator> getDefaultPopulators(World world)
{
return new ArrayList<>();
}
}));
}
}

View File

@@ -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<Location> 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()));
}
}
}
}

View File

@@ -2,5 +2,6 @@ package moe.sdg.PluginSDG;
public enum GameType
{
None,
DeathMatch
}

View File

@@ -8,17 +8,17 @@ public abstract class MiniGame
{
private final ArrayList<Player> _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<Player>();
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;
}

View File

@@ -38,9 +38,9 @@ public abstract class TeamMiniGame extends MiniGame
private final ArrayList<Team> _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<Team>();
}

View File

@@ -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.");
}
}

View File

@@ -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.";
}
}

View File

@@ -0,0 +1,3 @@
package moe.sdg.PluginSDG.exceptions;
public class MapException extends RuntimeException { }

View File

@@ -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.";
}
}

View File

@@ -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