mirror of
https://github.com/zoriya/PluginSDG.git
synced 2025-12-06 06:46:09 +00:00
Adding map creation, lobby location calculation & spawn calculations
This commit is contained in:
@@ -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<>();
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
34
src/main/java/moe/sdg/PluginSDG/GameMap.java
Normal file
34
src/main/java/moe/sdg/PluginSDG/GameMap.java
Normal 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()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,6 @@ package moe.sdg.PluginSDG;
|
||||
|
||||
public enum GameType
|
||||
{
|
||||
None,
|
||||
DeathMatch
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>();
|
||||
}
|
||||
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package moe.sdg.PluginSDG.exceptions;
|
||||
|
||||
public class MapException extends RuntimeException { }
|
||||
@@ -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.";
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user