Added redfort world and improved team config.

This commit is contained in:
Andrew Lalis 2022-07-27 18:08:31 +02:00
parent d90bf7d6ee
commit 7cbfa258f4
9 changed files with 158 additions and 7 deletions

View File

@ -29,6 +29,14 @@ Setting up a server is quite easy. Just go to the [releases page](https://github
port: 25565 port: 25565
connectionBacklog: 5 connectionBacklog: 5
ticksPerSecond: 20.0 ticksPerSecond: 20.0
world: worlds.redfort
teams:
- name: Red
color: [0.8, 0, 0]
spawnPoint: A
- name: Blue
color: [0, 0, 0.8]
spawnPoint: B
physics: physics:
gravity: 29.43 gravity: 29.43
walkingSpeed: 4 walkingSpeed: 4

View File

@ -24,10 +24,19 @@ public class ColorPalette {
} }
public void setColor(byte value, float r, float g, float b) { public void setColor(byte value, float r, float g, float b) {
if (value < 0) return; if (value <= 0) return;
colors[value - 1].set(r, g, b); colors[value - 1].set(r, g, b);
} }
public void setColor(byte value, Color color) {
if (value <= 0) return;
colors[value - 1].set(
color.getRed() / 255f,
color.getGreen() / 255f,
color.getBlue() / 255f
);
}
public float[] toArray() { public float[] toArray() {
float[] array = new float[3 * MAX_COLORS]; float[] array = new float[3 * MAX_COLORS];
for (int i = 0; i < MAX_COLORS; i++) { for (int i = 0; i < MAX_COLORS; i++) {

View File

@ -3,6 +3,8 @@ package nl.andrewl.aos_core.model.world;
import org.joml.Vector3f; import org.joml.Vector3f;
import java.io.*; import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map; import java.util.Map;
/** /**
@ -43,6 +45,12 @@ public final class WorldIO {
} }
} }
public static void write(World world, Path filePath) throws IOException {
try (var out = Files.newOutputStream(filePath)) {
write(world, out);
}
}
/** /**
* Reads a world from an input stream. * Reads a world from an input stream.
* @param in The input stream to read from. * @param in The input stream to read from.
@ -78,4 +86,10 @@ public final class WorldIO {
} }
return world; return world;
} }
public static World read(Path filePath) throws IOException {
try (var in = Files.newInputStream(filePath)) {
return read(in);
}
}
} }

View File

@ -3,7 +3,9 @@ package nl.andrewl.aos_core.model.world;
import org.joml.Vector3f; import org.joml.Vector3f;
import org.joml.Vector3i; import org.joml.Vector3i;
import java.awt.*;
import java.util.Collections; import java.util.Collections;
import java.util.Random;
/** /**
* Simple container for a bunch of static methods for creating pre-made worlds * Simple container for a bunch of static methods for creating pre-made worlds
@ -25,7 +27,9 @@ public final class Worlds {
} }
} }
} }
return new World(ColorPalette.rainbow(), Collections.singleton(chunk)); World world = new World(ColorPalette.rainbow(), Collections.singleton(chunk));
world.setSpawnPoint("A", new Vector3f(Chunk.SIZE / 2f, Chunk.SIZE / 2f, Chunk.SIZE / 2f));
return world;
} }
/** /**
@ -151,4 +155,50 @@ public final class Worlds {
return world; return world;
} }
/**
* A square arena for up to 4 teams, with spawn points A, B, C, and D.
* @return The world.
*/
public static World arena() {
World world = new World();
ColorPalette palette = new ColorPalette();
palette.setColor((byte) 1, Color.BLACK);
palette.setColor((byte) 2, Color.WHITE);
palette.setColor((byte) 3, Color.GRAY);
palette.setColor((byte) 4, Color.DARK_GRAY);
palette.setColor((byte) 5, new Color(79, 58, 0));
palette.setColor((byte) 6, new Color(133, 118, 78));
palette.setColor((byte) 7, new Color(69, 59, 32));
palette.setColor((byte) 8, new Color(38, 77, 30));
palette.setColor((byte) 9, new Color(4, 107, 40));
palette.setColor((byte) 10, Color.RED.darker());
palette.setColor((byte) 11, Color.GREEN.darker());
palette.setColor((byte) 12, Color.BLUE.darker());
world.setPalette(palette);
Random rand = new Random(1L);
for (int cx = 0; cx < 9; cx++) {
for (int cz = 0; cz < 9; cz++) {
for (int cy = 0; cy < 5; cy++) {
world.addChunk(new Chunk(cx, cy, cz));
}
}
}
int surface = 3 * Chunk.SIZE;
for (int x = world.getMinX(); x < world.getMaxX(); x++) {
for (int z = world.getMinZ(); z < world.getMaxZ(); z++) {
for (int y = 0; y < surface - 1; y++) {
world.setBlockAt(x, y, z, (byte) rand.nextInt(5, 8));
}
world.setBlockAt(x, surface - 1, z, (byte) rand.nextInt(8, 10));
}
}
world.setSpawnPoint("A", new Vector3f(5.5f, surface, 5.5f));
world.setSpawnPoint("C", new Vector3f(world.getMaxX() - 5.5f, surface, 5.5f));
world.setSpawnPoint("D", new Vector3f(5.5f, surface, world.getMaxZ() - 5.5f));
world.setSpawnPoint("B", new Vector3f(world.getMaxX() - 5.5f, surface, world.getMaxZ() - 5.5f));
return world;
}
} }

View File

@ -4,9 +4,11 @@ import nl.andrewl.aos2_server.cli.ServerCli;
import nl.andrewl.aos2_server.config.ServerConfig; import nl.andrewl.aos2_server.config.ServerConfig;
import nl.andrewl.aos2_server.logic.WorldUpdater; import nl.andrewl.aos2_server.logic.WorldUpdater;
import nl.andrewl.aos2_server.model.ServerPlayer; import nl.andrewl.aos2_server.model.ServerPlayer;
import nl.andrewl.aos_core.FileUtils;
import nl.andrewl.aos_core.config.Config; import nl.andrewl.aos_core.config.Config;
import nl.andrewl.aos_core.model.item.BlockItemStack; import nl.andrewl.aos_core.model.item.BlockItemStack;
import nl.andrewl.aos_core.model.world.World; import nl.andrewl.aos_core.model.world.World;
import nl.andrewl.aos_core.model.world.WorldIO;
import nl.andrewl.aos_core.model.world.Worlds; import nl.andrewl.aos_core.model.world.Worlds;
import nl.andrewl.aos_core.net.UdpReceiver; import nl.andrewl.aos_core.net.UdpReceiver;
import nl.andrewl.aos_core.net.client.BlockColorMessage; import nl.andrewl.aos_core.net.client.BlockColorMessage;
@ -20,6 +22,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException; import java.io.IOException;
import java.net.*; import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.List; import java.util.List;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
@ -47,11 +50,29 @@ public class Server implements Runnable {
this.teamManager = new TeamManager(this); this.teamManager = new TeamManager(this);
this.projectileManager = new ProjectileManager(this); this.projectileManager = new ProjectileManager(this);
this.worldUpdater = new WorldUpdater(this, config.ticksPerSecond); this.worldUpdater = new WorldUpdater(this, config.ticksPerSecond);
this.world = Worlds.testingWorld();
// TODO: Add some way to configure teams with config files or commands. if (config.world.startsWith("worlds.")) {
teamManager.addTeam("Red", new Vector3f(0.8f, 0, 0), "A"); String worldName = config.world.substring("worlds.".length());
teamManager.addTeam("Blue", new Vector3f(0, 0, 0.8f), "B"); this.world = switch (worldName) {
case "testing" -> Worlds.testingWorld();
case "flat" -> Worlds.flatWorld();
case "cube" -> Worlds.smallCube();
case "arena" -> Worlds.arena();
default -> WorldIO.read(FileUtils.getClasspathResource("redfort.wld"));
};
} else {
Path worldFile = Path.of(config.world);
if (Files.isReadable(worldFile)) {
this.world = WorldIO.read(worldFile);
} else {
log.error("Cannot read world file: {}", worldFile.toAbsolutePath());
this.world = Worlds.arena();
}
}
for (var teamConfig : config.teams) {
teamManager.addTeam(teamConfig.name, new Vector3f(teamConfig.color), teamConfig.spawnPoint);
}
} }
@Override @Override

View File

@ -0,0 +1,30 @@
package nl.andrewl.aos2_server.cli;
import nl.andrewl.aos_core.model.world.WorldIO;
import picocli.CommandLine;
import java.io.IOException;
import java.nio.file.Path;
@CommandLine.Command(
name = "save-world",
description = "Saves the current world to a file.",
mixinStandardHelpOptions = true
)
public class SaveWorldCommand implements Runnable {
@CommandLine.ParentCommand ServerCli cli;
@CommandLine.Option(names = {"-o", "--output"}, description = "The file to save to.", defaultValue = "world.wld")
Path file;
@Override
public void run() {
try {
cli.out.println("Saving world...");
WorldIO.write(cli.server.getWorld(), file);
cli.out.println("Saved server's world to " + file.toAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -22,7 +22,7 @@ import java.nio.file.Path;
name = "", name = "",
description = "Interactive shell for server commands.", description = "Interactive shell for server commands.",
footer = {"", "Press Ctrl-D to exit."}, footer = {"", "Press Ctrl-D to exit."},
subcommands = {StopCommand.class, PlayersCommand.class} subcommands = {StopCommand.class, PlayersCommand.class, SaveWorldCommand.class}
) )
public class ServerCli implements Runnable { public class ServerCli implements Runnable {
final Server server; final Server server;

View File

@ -4,8 +4,13 @@ public class ServerConfig {
public int port = 25565; public int port = 25565;
public int connectionBacklog = 5; public int connectionBacklog = 5;
public float ticksPerSecond = 20.0f; public float ticksPerSecond = 20.0f;
public String world = "worlds.redfort";
public PhysicsConfig physics = new PhysicsConfig(); public PhysicsConfig physics = new PhysicsConfig();
public ActionsConfig actions = new ActionsConfig(); public ActionsConfig actions = new ActionsConfig();
public TeamConfig[] teams = new TeamConfig[]{
new TeamConfig("Red", new float[]{0.8f, 0, 0}, "A"),
new TeamConfig("Blue", new float[]{0, 0, 0.8f}, "B")
};
public static class PhysicsConfig { public static class PhysicsConfig {
public float gravity = 9.81f * 3; public float gravity = 9.81f * 3;
@ -30,4 +35,18 @@ public class ServerConfig {
public float movementAccuracyDecreaseFactor = 0.01f; public float movementAccuracyDecreaseFactor = 0.01f;
public boolean friendlyFire = false; public boolean friendlyFire = false;
} }
public static class TeamConfig {
public String name;
public float[] color;
public String spawnPoint;
public TeamConfig() {}
public TeamConfig(String name, float[] color, String spawnPoint) {
this.name = name;
this.color = color;
this.spawnPoint = spawnPoint;
}
}
} }

Binary file not shown.