Start on game logic
This commit is contained in:
@ -35,6 +35,7 @@ public final class FloorGame extends JavaPlugin {
|
||||
public static boolean StartGame() {
|
||||
if (gameInstance == null) {
|
||||
gameInstance = new GameInstance(GameConfig.LoadFromFile());
|
||||
gameInstance.Start();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -13,6 +13,11 @@ public class CommandFloorGame implements CommandExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!sender.hasPermission("floorGame.admin")) {
|
||||
sender.sendMessage(ChatColor.RED + "You do not have permission to run this command");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0)
|
||||
return false;
|
||||
|
||||
|
||||
@ -4,23 +4,30 @@ import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TabCompleterFloorGame implements TabCompleter {
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args.length == 1)
|
||||
return List.of("start", "stop", "config");
|
||||
|
||||
if (!args[0].equalsIgnoreCase("config"))
|
||||
if (!sender.hasPermission("floorGame.admin") || args.length == 0)
|
||||
return List.of();
|
||||
|
||||
if (args.length == 2)
|
||||
return List.of("playerJoinArea", "spectatorJoinArea", "postGameTpLocation", "floorCenter", "tileSize",
|
||||
List<String> options;
|
||||
|
||||
if (args.length == 1)
|
||||
options = List.of("start", "stop", "config");
|
||||
|
||||
else if (!args[0].equalsIgnoreCase("config"))
|
||||
return List.of();
|
||||
|
||||
else if (args.length == 2)
|
||||
options = List.of("playerJoinArea", "spectatorJoinArea", "postGameTpLocation", "floorCenter", "tileSize",
|
||||
"gridSize", "failLimit", "playersHaveKnockbackStick", "playersHaveFishingRod", "spectatorsCanMessWithPlayers");
|
||||
|
||||
return switch (args[1]) {
|
||||
else options = switch (args[1]) {
|
||||
case "playerJoinArea", "spectatorJoinArea" -> AreaCompleter(sender, args, 3);
|
||||
case "postGameTpLocation", "floorCenter" -> LocationCompleter(sender, args, 3);
|
||||
case "playersHaveKnockbackStick", "playersHaveFishingRod", "spectatorsCanMessWithPlayers" ->
|
||||
@ -28,8 +35,7 @@ public class TabCompleterFloorGame implements TabCompleter {
|
||||
default -> List.of();
|
||||
};
|
||||
|
||||
// TODO: limit options based on current arg value
|
||||
// https://www.spigotmc.org/threads/how-to-create-a-tabcompleter-for-a-command.591865/
|
||||
return StringUtil.copyPartialMatches(args[args.length - 1].toLowerCase(), options, new ArrayList<>());
|
||||
}
|
||||
|
||||
private List<String> AreaCompleter(CommandSender sender, String[] args, int locationArgIndex) {
|
||||
@ -47,8 +53,6 @@ public class TabCompleterFloorGame implements TabCompleter {
|
||||
if (!(sender instanceof Player))
|
||||
return List.of();
|
||||
|
||||
sender.sendMessage(Integer.toString(args.length));
|
||||
|
||||
if (args.length - locationArgIndex >= 3)
|
||||
return List.of();
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package com.pobnellion.floorGame.game;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Random;
|
||||
@ -34,12 +35,20 @@ public class Floor {
|
||||
colours = colourSet.toArray(new Material[0]);
|
||||
}
|
||||
|
||||
public void Init() {
|
||||
Reset();
|
||||
FillWalls(xzCorner.getBlockY(), xzCorner.getBlockY() + 15, Material.BARRIER);
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
for (int row = 0; row < gridSize; row++) {
|
||||
for (int col = 0; col < gridSize; col++) {
|
||||
FillTile(xzCorner.clone().add(row * tileSize, 0, col * tileSize), colourGrid[row][col]);
|
||||
FillTile(xzCorner.getBlockX() + row * tileSize,
|
||||
xzCorner.getBlockZ() + col * tileSize,
|
||||
colourGrid[row][col]);
|
||||
}
|
||||
}
|
||||
FillWalls(xzCorner.getBlockY() + 2, xzCorner.getBlockY() + 4, Material.BARRIER);
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
@ -48,21 +57,72 @@ public class Floor {
|
||||
xzCorner.clone().add(row, 0, col).getBlock().setType(Material.AIR);
|
||||
}
|
||||
}
|
||||
FillWalls(xzCorner.getBlockY(), xzCorner.getBlockY() + 15, Material.AIR);
|
||||
}
|
||||
|
||||
public void SoloTile(Material material) {
|
||||
for (int row = 0; row < gridSize; row++) {
|
||||
for (int col = 0; col < gridSize; col++) {
|
||||
if (colourGrid[row][col] != material)
|
||||
FillTile(xzCorner.clone().add(row * tileSize, 0, col * tileSize), Material.AIR);
|
||||
}
|
||||
FillTile(xzCorner.getBlockX() + row * tileSize,
|
||||
xzCorner.getBlockZ() + col * tileSize,
|
||||
Material.AIR);
|
||||
}
|
||||
}
|
||||
|
||||
private void FillTile(Location location, Material material) {
|
||||
for (int row = 0; row < tileSize; row++) {
|
||||
for (int col = 0; col < tileSize; col++) {
|
||||
location.clone().add(row, 0, col).getBlock().setType(material);
|
||||
FillWalls(xzCorner.getBlockY() + 2, xzCorner.getBlockY() + 4, material);
|
||||
}
|
||||
|
||||
private void FillTile(int xMin, int zMin, Material material) {
|
||||
FillArea(xzCorner.getWorld(), xMin, xzCorner.getBlockY(), zMin,
|
||||
xMin + tileSize, xzCorner.getBlockY(), zMin + tileSize, material);
|
||||
}
|
||||
|
||||
private void FillWalls(int yMin, int yMax, Material material) {
|
||||
var floorSize = tileSize * gridSize + 1;
|
||||
FillArea(xzCorner.getWorld(),
|
||||
xzCorner.getBlockX() - 1,
|
||||
yMin,
|
||||
xzCorner.getBlockZ() - 1,
|
||||
xzCorner.getBlockX() - 1,
|
||||
yMax,
|
||||
xzCorner.getBlockZ() + floorSize,
|
||||
material);
|
||||
|
||||
FillArea(xzCorner.getWorld(),
|
||||
xzCorner.getBlockX() - 1,
|
||||
yMin,
|
||||
xzCorner.getBlockZ() - 1,
|
||||
xzCorner.getBlockX() + floorSize,
|
||||
yMax,
|
||||
xzCorner.getBlockZ() - 1,
|
||||
material);
|
||||
|
||||
FillArea(xzCorner.getWorld(),
|
||||
xzCorner.getBlockX() + floorSize,
|
||||
yMin,
|
||||
xzCorner.getBlockZ() - 1,
|
||||
xzCorner.getBlockX() + floorSize,
|
||||
yMax,
|
||||
xzCorner.getBlockX() + floorSize,
|
||||
material);
|
||||
|
||||
FillArea(xzCorner.getWorld(),
|
||||
xzCorner.getBlockX() + floorSize,
|
||||
yMin,
|
||||
xzCorner.getBlockZ() + floorSize,
|
||||
xzCorner.getBlockX() - 1,
|
||||
yMax,
|
||||
xzCorner.getBlockX() + floorSize,
|
||||
material);
|
||||
}
|
||||
|
||||
private void FillArea(World world, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax, Material material) {
|
||||
for (int x = xMin; x < xMax; x++) {
|
||||
for (int y = yMin; y < yMax; y++) {
|
||||
for (int z = zMin; z < zMax; z++) {
|
||||
world.getBlockAt(x, y, z).setType(material);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ public class GameInstance {
|
||||
private final ArrayList<Player> players = new ArrayList<>();
|
||||
private final ArrayList<Player> spectators = new ArrayList<>();
|
||||
private final GameConfig config;
|
||||
public int round;
|
||||
|
||||
public GameInstance(GameConfig config) {
|
||||
floor = new Floor(config.getFloorCenter(), config.getGridSize(), config.getTileSize(), config.getAvailableColours());
|
||||
@ -30,12 +31,18 @@ public class GameInstance {
|
||||
else if (IsInBounds(player.getLocation(), config.getSpectatorJoinArea()[0], config.getSpectatorJoinArea()[1]))
|
||||
spectators.add(player);
|
||||
});
|
||||
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
GameLoopTask();
|
||||
}
|
||||
}.runTaskTimerAsynchronously(FloorGame.GetInstance(), 0, 10_000);
|
||||
|
||||
public void Start() {
|
||||
floor.Init();
|
||||
|
||||
var playerTpLocation = config.getFloorCenter().clone().add(0, 2, 0);
|
||||
var spectatorTpLocation = config.getFloorCenter().clone().add(0, 15, 0);
|
||||
players.forEach(player -> player.teleport(playerTpLocation));
|
||||
spectators.forEach(player -> player.teleport(spectatorTpLocation));
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void GameLoopTask() {
|
||||
@ -43,6 +50,8 @@ public class GameInstance {
|
||||
var colour = floor.colours[rand.nextInt(floor.colours.length)];
|
||||
floor.SoloTile(colour);
|
||||
|
||||
var roundTime = 1 + floor.tileSize * 0.5 - round * (0.2 * floor.tileSize);
|
||||
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
floor.Reset();
|
||||
@ -51,11 +60,22 @@ public class GameInstance {
|
||||
}
|
||||
|
||||
public void Stop() {
|
||||
new BukkitRunnable() {
|
||||
public void run() {
|
||||
floor.Clear();
|
||||
|
||||
players.forEach(player -> player.teleport(config.getPostGameTpLocation()));
|
||||
spectators.forEach(player -> player.teleport(config.getPostGameTpLocation()));
|
||||
}
|
||||
}.runTask(FloorGame.GetInstance());
|
||||
}
|
||||
|
||||
private double GetRoundTime() {
|
||||
if (round < 40)
|
||||
return 1 + 0.5 * floor.tileSize - 0.08 * floor.tileSize * round * 0.1;
|
||||
|
||||
// TODO: flatter line after round 40
|
||||
}
|
||||
|
||||
private boolean IsInBounds(Location location, Location bounds1, Location bounds2) {
|
||||
return location.getX() > Math.min(bounds1.getX(), bounds2.getX())
|
||||
|
||||
Reference in New Issue
Block a user