Start on game logic

This commit is contained in:
ruby
2024-08-07 23:07:31 +12:00
parent 294b2c1e15
commit 1c1c51d5ca
5 changed files with 115 additions and 25 deletions

View File

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

View File

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

View File

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

View File

@ -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);
}
}
FillWalls(xzCorner.getBlockY() + 2, xzCorner.getBlockY() + 4, material);
}
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);
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);
}
}
}
}

View File

@ -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);
});
}
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));
new BukkitRunnable() {
public void run() {
GameLoopTask();
}
}.runTaskTimerAsynchronously(FloorGame.GetInstance(), 0, 10_000);
}
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,10 +60,21 @@ public class GameInstance {
}
public void Stop() {
floor.Clear();
new BukkitRunnable() {
public void run() {
floor.Clear();
players.forEach(player -> player.teleport(config.getPostGameTpLocation()));
spectators.forEach(player -> player.teleport(config.getPostGameTpLocation()));
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) {