Added:
- SnowballProjectile - ZombieCreature - About (us/game) command - Credits command - Stop command - Terminal All Color phases are now working
This commit is contained in:
parent
b82cdb3a4b
commit
90ddb82640
29 changed files with 1024 additions and 300 deletions
10
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
10
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<Languages>
|
||||||
|
<language minSize="50" name="Java" />
|
||||||
|
</Languages>
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
|
@ -3,7 +3,13 @@ plugins {
|
||||||
alias(libs.plugins.shadowJar)
|
alias(libs.plugins.shadowJar)
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "dev.celestialfox"
|
tasks.withType<Jar> {
|
||||||
|
manifest {
|
||||||
|
attributes["Main-Class"] = "dev.celestialfox.spectrumsurvival.Server"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "dev.celestialfox.spectrumsurvival"
|
||||||
version = "1.0"
|
version = "1.0"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -15,6 +21,8 @@ dependencies {
|
||||||
implementation("dev.hollowcube:polar:1.11.1")
|
implementation("dev.hollowcube:polar:1.11.1")
|
||||||
implementation("net.kyori:adventure-text-minimessage:4.17.0")
|
implementation("net.kyori:adventure-text-minimessage:4.17.0")
|
||||||
implementation("org.slf4j:slf4j-api:2.0.13")
|
implementation("org.slf4j:slf4j-api:2.0.13")
|
||||||
|
implementation("org.jline:jline-terminal:3.26.3")
|
||||||
|
implementation("org.jline:jline-reader:3.26.3")
|
||||||
implementation("ch.qos.logback:logback-classic:1.5.6")
|
implementation("ch.qos.logback:logback-classic:1.5.6")
|
||||||
testImplementation(platform("org.junit:junit-bom:5.9.1"))
|
testImplementation(platform("org.junit:junit-bom:5.9.1"))
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
package dev.cfox.gamejam;
|
package dev.celestialfox.spectrumsurvival;
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.commands.QueueCommand;
|
import dev.celestialfox.spectrumsurvival.game.commands.*;
|
||||||
import dev.cfox.gamejam.utils.config.Checks;
|
import dev.celestialfox.spectrumsurvival.utils.config.Checks;
|
||||||
import dev.cfox.gamejam.utils.config.Settings;
|
import dev.celestialfox.spectrumsurvival.utils.config.Settings;
|
||||||
import dev.cfox.gamejam.utils.events.MiscEvents;
|
import dev.celestialfox.spectrumsurvival.utils.events.MiscEvents;
|
||||||
import dev.cfox.gamejam.utils.events.StartEvents;
|
import dev.celestialfox.spectrumsurvival.utils.events.StartEvents;
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.command.CommandManager;
|
import net.minestom.server.command.CommandManager;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -32,6 +32,8 @@ public class Server {
|
||||||
MiscEvents.register();
|
MiscEvents.register();
|
||||||
registerCommands();
|
registerCommands();
|
||||||
|
|
||||||
|
Terminal.start();
|
||||||
|
|
||||||
// Server Start
|
// Server Start
|
||||||
server.start(Settings.getIP(), Settings.getPort());
|
server.start(Settings.getIP(), Settings.getPort());
|
||||||
logger.info("Server Started at " + Settings.getIP() + ":" + Settings.getPort() + " (MC: " + MinecraftServer.VERSION_NAME + ")");
|
logger.info("Server Started at " + Settings.getIP() + ":" + Settings.getPort() + " (MC: " + MinecraftServer.VERSION_NAME + ")");
|
||||||
|
@ -40,5 +42,8 @@ public class Server {
|
||||||
public static void registerCommands() {
|
public static void registerCommands() {
|
||||||
CommandManager commandManager = MinecraftServer.getCommandManager();
|
CommandManager commandManager = MinecraftServer.getCommandManager();
|
||||||
commandManager.register(new QueueCommand());
|
commandManager.register(new QueueCommand());
|
||||||
|
commandManager.register(new AboutCommand());
|
||||||
|
commandManager.register(new CreditsCommand());
|
||||||
|
commandManager.register(new StopCommand());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,9 @@
|
||||||
package dev.cfox.gamejam.game.classes;
|
package dev.celestialfox.spectrumsurvival.game.classes;
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.managers.GameManager;
|
import dev.celestialfox.spectrumsurvival.game.managers.GameManager;
|
||||||
import dev.cfox.gamejam.game.managers.QueueManager;
|
import dev.celestialfox.spectrumsurvival.game.phases.Phase;
|
||||||
import dev.cfox.gamejam.game.phases.Phase;
|
import dev.celestialfox.spectrumsurvival.utils.Misc;
|
||||||
import dev.cfox.gamejam.utils.Misc;
|
import dev.celestialfox.spectrumsurvival.utils.classes.Randomized;
|
||||||
import dev.cfox.gamejam.utils.classes.Randomized;
|
|
||||||
import net.kyori.adventure.sound.Sound;
|
import net.kyori.adventure.sound.Sound;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
@ -87,10 +86,16 @@ public class GameLobby {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setInstance(Instance instance) {
|
||||||
|
this.instance = instance;
|
||||||
|
players.forEach(uuid ->
|
||||||
|
Misc.getPlayer(uuid).setInstance(instance));
|
||||||
|
}
|
||||||
|
|
||||||
public void setInstance(Instance instance, Pos pos) {
|
public void setInstance(Instance instance, Pos pos) {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
players.forEach(uuid ->
|
players.forEach(uuid ->
|
||||||
Misc.getPlayer(uuid).setInstance(instance).thenRun(() -> Misc.getPlayer(uuid).teleport(pos)));
|
Misc.getPlayer(uuid).setInstance(instance, pos));
|
||||||
}
|
}
|
||||||
public Instance getInstance() {
|
public Instance getInstance() {
|
||||||
return instance;
|
return instance;
|
|
@ -1,14 +1,12 @@
|
||||||
package dev.cfox.gamejam.game.classes;
|
package dev.celestialfox.spectrumsurvival.game.classes;
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.managers.QueueManager;
|
import dev.celestialfox.spectrumsurvival.game.managers.QueueManager;
|
||||||
import dev.cfox.gamejam.utils.Misc;
|
import dev.celestialfox.spectrumsurvival.utils.Misc;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.entity.GameMode;
|
import net.minestom.server.entity.GameMode;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class GameQueue {
|
public class GameQueue {
|
||||||
|
@ -27,7 +25,7 @@ public class GameQueue {
|
||||||
public void removePlayer(UUID uuid) {
|
public void removePlayer(UUID uuid) {
|
||||||
if (players.contains(uuid)) {
|
if (players.contains(uuid)) {
|
||||||
players.remove(uuid);
|
players.remove(uuid);
|
||||||
Misc.getPlayer(uuid).setGameMode(GameMode.SURVIVAL);
|
Misc.getPlayer(uuid).setGameMode(GameMode.ADVENTURE);
|
||||||
Misc.getPlayer(uuid).sendMessage(Component.text("You have left the queue", NamedTextColor.RED));
|
Misc.getPlayer(uuid).sendMessage(Component.text("You have left the queue", NamedTextColor.RED));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.game.classes;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
|
import net.minestom.server.entity.PlayerProjectile;
|
||||||
|
|
||||||
|
public class SnowballProjectile extends PlayerProjectile {
|
||||||
|
public SnowballProjectile(Entity shooter) {
|
||||||
|
super(shooter, EntityType.SNOWBALL);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.game.classes;
|
||||||
|
|
||||||
|
import net.minestom.server.entity.EntityCreature;
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.entity.ai.goal.MeleeAttackGoal;
|
||||||
|
import net.minestom.server.entity.ai.target.ClosestEntityTarget;
|
||||||
|
import net.minestom.server.entity.attribute.Attribute;
|
||||||
|
import net.minestom.server.utils.time.TimeUnit;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ZombieCreature extends EntityCreature {
|
||||||
|
|
||||||
|
public ZombieCreature() {
|
||||||
|
super(EntityType.ZOMBIE);
|
||||||
|
|
||||||
|
getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.15);
|
||||||
|
|
||||||
|
addAIGroup(
|
||||||
|
List.of(
|
||||||
|
new MeleeAttackGoal(this, 1.6, 20, TimeUnit.SERVER_TICK) // Attack the target
|
||||||
|
),
|
||||||
|
List.of(
|
||||||
|
new ClosestEntityTarget(this, 50,
|
||||||
|
entity -> entity instanceof Player && ((Player) entity).getGameMode() != GameMode.SPECTATOR) // Target the nearest player
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.game.commands;
|
||||||
|
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.managers.GameManager;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.managers.QueueManager;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
|
import net.minestom.server.command.builder.Command;
|
||||||
|
import net.minestom.server.command.builder.arguments.ArgumentType;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
|
||||||
|
public class AboutCommand extends Command {
|
||||||
|
public AboutCommand() {
|
||||||
|
super("about");
|
||||||
|
addSyntax(((sender, context) -> {
|
||||||
|
final String arg1 = context.get("arg1");
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
if (arg1.equals("us")) {
|
||||||
|
player.sendMessage(
|
||||||
|
Component.text("\n§lAbout CelestialFox Studio\n", NamedTextColor.GOLD)
|
||||||
|
.append(Component.text("We are a passionate indie game studio creating unique experiences.\n", NamedTextColor.YELLOW))
|
||||||
|
.append(Component.text("Want to know more? Check our website: ", NamedTextColor.YELLOW))
|
||||||
|
.append(Component.text("https://celestial-fox.com/", NamedTextColor.LIGHT_PURPLE, TextDecoration.UNDERLINED)
|
||||||
|
.clickEvent(ClickEvent.openUrl("https://celestial-fox.com/")))
|
||||||
|
);
|
||||||
|
} else if (arg1.equals("game")) {
|
||||||
|
player.sendMessage(
|
||||||
|
Component.text("\n§lAbout Spectrum Survival\n", NamedTextColor.DARK_AQUA)
|
||||||
|
.append(Component.text("Dive into Spectrum Survival, where each color phase brings a new challenge! Every 30 seconds, the color changes, creating a chaotic 3-minute survival test.\n\n", NamedTextColor.AQUA))
|
||||||
|
.append(Component.text("§lColor Phases:\n", NamedTextColor.LIGHT_PURPLE))
|
||||||
|
.append(Component.text("- §lRed: §cFlames spread across the map. Avoid getting burned!\n", NamedTextColor.RED))
|
||||||
|
.append(Component.text("- §lBlue: §9Snowball fight frenzy! Knock back your foes.\n", NamedTextColor.BLUE))
|
||||||
|
.append(Component.text("- §lGreen: §aWatch out for wither roses and zombies. Roses hurt, zombies eliminate instantly.\n", NamedTextColor.GREEN))
|
||||||
|
.append(Component.text("- §lYellow: §eDodge lightning or be struck! §8§o(You can punch players into the lightning)\n", NamedTextColor.YELLOW))
|
||||||
|
.append(Component.text("- §lGray: §7Darkness falls, pvp enabled. Fight to survive!\n", NamedTextColor.GRAY))
|
||||||
|
.append(Component.text("\nSurvive all phases and adapt to win! Good luck!", NamedTextColor.AQUA))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), ArgumentType.String("arg1"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.game.commands;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.ComponentBuilder;
|
||||||
|
import net.kyori.adventure.text.TextComponent;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.minestom.server.command.builder.Command;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CreditsCommand extends Command {
|
||||||
|
public CreditsCommand() {
|
||||||
|
super("credits");
|
||||||
|
addSyntax(((sender, context) -> {
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
player.sendMessage(generateCredits());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Component generateCredits() {
|
||||||
|
ComponentBuilder<TextComponent, TextComponent.Builder> messageBuilder = Component.text().content("\n§lCredits\n").color(NamedTextColor.GOLD);
|
||||||
|
|
||||||
|
messageBuilder.append(Component.text("- §lDeveloper: §eAndus\n", NamedTextColor.YELLOW));
|
||||||
|
messageBuilder.append(Component.text("- §lIdeas: §7" + randomizeNames(List.of("Andus", "LucePric", "xnlx0000")) + "\n", NamedTextColor.GRAY));
|
||||||
|
messageBuilder.append(Component.text("- §lMaps: §e" + randomizeNames(List.of("LucePric", "Bali__0", "GummyW0rm", "xnlx0000")) + "\n", NamedTextColor.YELLOW));
|
||||||
|
|
||||||
|
return messageBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String randomizeNames(List<String> names) {
|
||||||
|
List<String> shuffledNames = new ArrayList<>(names);
|
||||||
|
Collections.shuffle(shuffledNames);
|
||||||
|
return String.join(", ", shuffledNames);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.game.commands;
|
||||||
|
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.managers.GameManager;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.managers.QueueManager;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.minestom.server.command.builder.Command;
|
||||||
|
import net.minestom.server.command.builder.arguments.ArgumentType;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.potion.Potion;
|
||||||
|
import net.minestom.server.potion.PotionEffect;
|
||||||
|
|
||||||
|
public class QueueCommand extends Command {
|
||||||
|
public QueueCommand() {
|
||||||
|
super("queue", "q");
|
||||||
|
addSyntax(((sender, context) -> {
|
||||||
|
final String arg1 = context.get("arg1");
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
if (arg1.equals("join")) {
|
||||||
|
QueueManager.joinPlayer(player);
|
||||||
|
} else if (arg1.equals("leave")) {
|
||||||
|
QueueManager.removePlayer(player);
|
||||||
|
} else if (arg1.equals("force")) {
|
||||||
|
if (QueueManager.getPlayerQueue(player) != null) {
|
||||||
|
GameManager.startGame(QueueManager.getPlayerQueue(player));
|
||||||
|
} else {
|
||||||
|
player.sendMessage(Component.text("You're not in a queue!", NamedTextColor.RED));
|
||||||
|
}
|
||||||
|
} else if (arg1.equals("a")) {
|
||||||
|
player.getInventory().addItemStack(ItemStack.of(Material.SNOWBALL, 16));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), ArgumentType.String("arg1"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.game.commands;
|
||||||
|
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.command.builder.Command;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
|
||||||
|
public class StopCommand extends Command {
|
||||||
|
public StopCommand() {
|
||||||
|
super("stop");
|
||||||
|
addSyntax(((sender, context) -> {
|
||||||
|
if (sender instanceof Player player) {
|
||||||
|
player.sendMessage("No.");
|
||||||
|
} else {
|
||||||
|
MinecraftServer.stopCleanly();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.game.commands;
|
||||||
|
|
||||||
|
import dev.celestialfox.spectrumsurvival.Server;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.command.builder.Command;
|
||||||
|
import net.minestom.server.command.builder.suggestion.Suggestion;
|
||||||
|
import net.minestom.server.command.builder.suggestion.SuggestionEntry;
|
||||||
|
import net.minestom.server.listener.TabCompleteListener;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jline.reader.*;
|
||||||
|
import org.jline.terminal.TerminalBuilder;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Terminal {
|
||||||
|
private static final String PROMPT = "> ";
|
||||||
|
private static volatile org.jline.terminal.Terminal terminal;
|
||||||
|
static volatile LineReader reader;
|
||||||
|
private static volatile boolean running = false;
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(Terminal.class);
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public static void start() {
|
||||||
|
final Thread thread = new Thread(null, () -> {
|
||||||
|
try {
|
||||||
|
terminal = TerminalBuilder.terminal();
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
}
|
||||||
|
reader = LineReaderBuilder.builder()
|
||||||
|
.completer(new MinestomCompleter())
|
||||||
|
.terminal(terminal)
|
||||||
|
.build();
|
||||||
|
running = true;
|
||||||
|
|
||||||
|
while (running) {
|
||||||
|
String command;
|
||||||
|
try {
|
||||||
|
command = reader.readLine(PROMPT);
|
||||||
|
var commandManager = MinecraftServer.getCommandManager();
|
||||||
|
commandManager.execute(commandManager.getConsoleSender(), command);
|
||||||
|
} catch (UserInterruptException e) {
|
||||||
|
// Handle Ctrl + C
|
||||||
|
System.exit(0);
|
||||||
|
return;
|
||||||
|
} catch (EndOfFileException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "Jline");
|
||||||
|
thread.setDaemon(true);
|
||||||
|
thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class MinestomCompleter implements Completer {
|
||||||
|
@Override
|
||||||
|
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
|
||||||
|
final var commandManager = MinecraftServer.getCommandManager();
|
||||||
|
final var consoleSender = commandManager.getConsoleSender();
|
||||||
|
if (line.wordIndex() == 0) {
|
||||||
|
final String commandString = line.word().toLowerCase();
|
||||||
|
candidates.addAll(
|
||||||
|
commandManager.getDispatcher().getCommands().stream()
|
||||||
|
.map(Command::getName)
|
||||||
|
.filter(name -> commandString.isBlank() || name.toLowerCase().startsWith(commandString))
|
||||||
|
.map(Candidate::new)
|
||||||
|
.toList()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
final String text = line.line();
|
||||||
|
final Suggestion suggestion = TabCompleteListener.getSuggestion(consoleSender, text);
|
||||||
|
if (suggestion != null) {
|
||||||
|
suggestion.getEntries().stream()
|
||||||
|
.map(SuggestionEntry::getEntry)
|
||||||
|
.map(Candidate::new)
|
||||||
|
.forEach(candidates::add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
package dev.cfox.gamejam.game.managers;
|
package dev.celestialfox.spectrumsurvival.game.managers;
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.classes.GameLobby;
|
import dev.celestialfox.spectrumsurvival.game.classes.GameLobby;
|
||||||
import dev.cfox.gamejam.game.classes.GameQueue;
|
import dev.celestialfox.spectrumsurvival.game.classes.GameQueue;
|
||||||
|
import dev.celestialfox.spectrumsurvival.utils.Misc;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -27,7 +29,12 @@ public class ConversionManager {
|
||||||
|
|
||||||
logger.debug("GameLobby removed: " + game.getName());
|
logger.debug("GameLobby removed: " + game.getName());
|
||||||
game.sendMessage(Component.text("Game ended!", NamedTextColor.RED));
|
game.sendMessage(Component.text("Game ended!", NamedTextColor.RED));
|
||||||
game.setInstance(QueueManager.lobbyInstance, new Pos(0, 60, 0, 180, 0));
|
game.setInstance(QueueManager.lobbyInstance, new Pos(0, 66, 0, 180, 0));
|
||||||
|
game.getPlayers().forEach(uuid -> {
|
||||||
|
Misc.getPlayer(uuid).setGameMode(GameMode.ADVENTURE);
|
||||||
|
Misc.getPlayer(uuid).setHealth(20);
|
||||||
|
});
|
||||||
|
GameManager.sendEndTitles(game);
|
||||||
GameManager.gameLobbies.remove(game.getName());
|
GameManager.gameLobbies.remove(game.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,9 @@
|
||||||
package dev.cfox.gamejam.game.managers;
|
package dev.celestialfox.spectrumsurvival.game.managers;
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.classes.GameLobby;
|
import dev.celestialfox.spectrumsurvival.game.phases.PhaseLogic;
|
||||||
import dev.cfox.gamejam.game.classes.GameQueue;
|
import dev.celestialfox.spectrumsurvival.utils.Misc;
|
||||||
import dev.cfox.gamejam.game.phases.PhaseLogic;
|
import dev.celestialfox.spectrumsurvival.game.classes.GameLobby;
|
||||||
import dev.cfox.gamejam.utils.Misc;
|
import dev.celestialfox.spectrumsurvival.game.classes.GameQueue;
|
||||||
import dev.cfox.gamejam.utils.events.StartEvents;
|
|
||||||
import net.hollowcube.polar.PolarLoader;
|
import net.hollowcube.polar.PolarLoader;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
@ -60,7 +59,7 @@ public class GameManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startGame(GameLobby game) {
|
public static void startGame(GameLobby game) {
|
||||||
logger.debug("Creating Lobby Instance");
|
logger.debug("Creating Game Instance");
|
||||||
InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
||||||
InstanceContainer instanceContainer = instanceManager.createInstanceContainer();
|
InstanceContainer instanceContainer = instanceManager.createInstanceContainer();
|
||||||
try {
|
try {
|
||||||
|
@ -83,10 +82,10 @@ public class GameManager {
|
||||||
|
|
||||||
for (Player player : instance.getPlayers()) {
|
for (Player player : instance.getPlayers()) {
|
||||||
if (eliminated.contains(player.getUuid())) {
|
if (eliminated.contains(player.getUuid())) {
|
||||||
player.showTitle(Title.title(Component.text("Eliminated!", NamedTextColor.RED, TextDecoration.BOLD), Component.text("")));
|
player.showTitle(Title.title(Component.text("You Lost.", NamedTextColor.RED, TextDecoration.BOLD), Component.text("")));
|
||||||
} else {
|
} else {
|
||||||
// Player is a winner if they were not eliminated
|
// Player is a winner if they were not eliminated
|
||||||
player.showTitle(Title.title(Component.text("Qualified!", NamedTextColor.GREEN, TextDecoration.BOLD), Component.text("")));
|
player.showTitle(Title.title(Component.text("You Win!", NamedTextColor.GREEN, TextDecoration.BOLD), Component.text("")));
|
||||||
winners.add(player.getUsername());
|
winners.add(player.getUsername());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package dev.cfox.gamejam.game.managers;
|
package dev.celestialfox.spectrumsurvival.game.managers;
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.classes.GameQueue;
|
import dev.celestialfox.spectrumsurvival.utils.Misc;
|
||||||
import dev.cfox.gamejam.utils.Misc;
|
import dev.celestialfox.spectrumsurvival.game.classes.GameQueue;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.title.Title;
|
import net.kyori.adventure.title.Title;
|
||||||
|
@ -23,6 +23,7 @@ public class QueueManager {
|
||||||
public static Instance lobbyInstance;
|
public static Instance lobbyInstance;
|
||||||
|
|
||||||
public static void joinPlayer(Player player) {
|
public static void joinPlayer(Player player) {
|
||||||
|
if (!GameManager.isPlayerInGame(player)) {
|
||||||
boolean queueFound = false;
|
boolean queueFound = false;
|
||||||
|
|
||||||
if (!queues.isEmpty()) {
|
if (!queues.isEmpty()) {
|
||||||
|
@ -46,6 +47,7 @@ public class QueueManager {
|
||||||
player.sendMessage(Component.text("One queue can hold up to §e10 players.", NamedTextColor.GRAY));
|
player.sendMessage(Component.text("One queue can hold up to §e10 players.", NamedTextColor.GRAY));
|
||||||
player.sendMessage(Component.text("§e§lWaiting for too long? §rUse §a/queue force §rto start now.", NamedTextColor.GRAY));
|
player.sendMessage(Component.text("§e§lWaiting for too long? §rUse §a/queue force §rto start now.", NamedTextColor.GRAY));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void removePlayer(Player player) {
|
public static void removePlayer(Player player) {
|
||||||
GameQueue queue = getPlayerQueue(player);
|
GameQueue queue = getPlayerQueue(player);
|
|
@ -1,9 +1,9 @@
|
||||||
package dev.cfox.gamejam.game.phases;
|
package dev.celestialfox.spectrumsurvival.game.phases;
|
||||||
|
|
||||||
public enum Phase {
|
public enum Phase {
|
||||||
RED,
|
RED,
|
||||||
BLUE,
|
BLUE,
|
||||||
GREEN,
|
GREEN,
|
||||||
YELLOW,
|
YELLOW,
|
||||||
PURPLE;
|
GRAY;
|
||||||
}
|
}
|
|
@ -0,0 +1,400 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.game.phases;
|
||||||
|
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.classes.ZombieCreature;
|
||||||
|
import dev.celestialfox.spectrumsurvival.utils.Misc;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.classes.GameLobby;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.managers.ConversionManager;
|
||||||
|
import net.hollowcube.polar.PolarLoader;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.instance.InstanceContainer;
|
||||||
|
import net.minestom.server.instance.InstanceManager;
|
||||||
|
import net.minestom.server.instance.Weather;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.potion.Potion;
|
||||||
|
import net.minestom.server.potion.PotionEffect;
|
||||||
|
import net.minestom.server.timer.SchedulerManager;
|
||||||
|
import net.minestom.server.timer.Task;
|
||||||
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class PhaseLogic {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(PhaseLogic.class);
|
||||||
|
private static final SchedulerManager scheduler = MinecraftServer.getSchedulerManager();
|
||||||
|
private static final int phaseDuration = 20; // in seconds
|
||||||
|
private static final int gameTime = 180; // 3 minutes in seconds
|
||||||
|
private static Task repeatTask;
|
||||||
|
private static Task endTask;
|
||||||
|
|
||||||
|
private static final int zombiesSpawn = 5;
|
||||||
|
|
||||||
|
public static void random(GameLobby game) {
|
||||||
|
if (repeatTask != null) {
|
||||||
|
repeatTask.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
repeatTask = scheduler.buildTask(() -> {
|
||||||
|
// Check if all players are eliminated
|
||||||
|
if (game.getEliminated().size() == game.getPlayers().size()) {
|
||||||
|
ConversionManager.fromGame(game);
|
||||||
|
repeatTask.cancel();
|
||||||
|
endTask.cancel();
|
||||||
|
} else {
|
||||||
|
logger.debug("Starting random phase selection for GameLobby: {}", game.getName());
|
||||||
|
try {
|
||||||
|
Phase[] phases = Phase.values();
|
||||||
|
Phase selectedPhase;
|
||||||
|
do {
|
||||||
|
int randomIndex = new Random().nextInt(phases.length);
|
||||||
|
selectedPhase = phases[randomIndex];
|
||||||
|
} while (
|
||||||
|
(selectedPhase == game.getPhase())
|
||||||
|
|| ((selectedPhase == Phase.GRAY) && (game.getPlayers().size() == game.getEliminated().size()+1)));
|
||||||
|
game.setPhase(selectedPhase);
|
||||||
|
|
||||||
|
logger.debug("Selected phase: {} for GameLobby: {}", selectedPhase.name(), game.getName());
|
||||||
|
if (game.getTask() != null) {
|
||||||
|
game.getTask().cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (selectedPhase) {
|
||||||
|
case RED -> red(game);
|
||||||
|
case BLUE -> blue(game);
|
||||||
|
case GREEN -> green(game);
|
||||||
|
case YELLOW -> yellow(game);
|
||||||
|
case GRAY -> gray(game);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Exception occurred during phase execution: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).repeat(TaskSchedule.seconds(phaseDuration)).schedule();
|
||||||
|
|
||||||
|
endTask = scheduler.buildTask(() -> {
|
||||||
|
try {
|
||||||
|
logger.debug("Ending game for GameLobby: {}", game.getName());
|
||||||
|
ConversionManager.fromGame(game);
|
||||||
|
repeatTask.cancel();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Exception occurred during game ending: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}).delay(TaskSchedule.seconds(gameTime)).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void red(GameLobby game) {
|
||||||
|
setupPhase(game, Phase.RED, "New color picked! §cRED",
|
||||||
|
"Dodge the fire! It does damage to you.",
|
||||||
|
"Red", NamedTextColor.RED, 13000, Weather.CLEAR);
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
List<Pos> positions = new ArrayList<>();
|
||||||
|
int minX = -10;
|
||||||
|
int maxX = 10;
|
||||||
|
int minZ = -10;
|
||||||
|
int maxZ = 10;
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
for (int y = 55; y < 75; y++) {
|
||||||
|
Pos pos = new Pos(x, y, z);
|
||||||
|
if (new Random().nextInt(10) < 2) {
|
||||||
|
if (isFlamableBlock(game.getInstance().getBlock(pos))) {
|
||||||
|
positions.add(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Pos> iterator = positions.iterator();
|
||||||
|
Task task;
|
||||||
|
task = scheduler.buildTask(() -> {
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
Pos pos = iterator.next();
|
||||||
|
game.getInstance().setBlock(pos, Block.FIRE);
|
||||||
|
}
|
||||||
|
}).repeat(Duration.ofMillis(250)).schedule();
|
||||||
|
|
||||||
|
scheduler.buildTask(() -> {
|
||||||
|
task.cancel();
|
||||||
|
resetInstance(game);
|
||||||
|
}).delay(TaskSchedule.seconds(phaseDuration-1)).schedule();
|
||||||
|
}
|
||||||
|
public static void blue(GameLobby game) {
|
||||||
|
setupPhase(game, Phase.BLUE, "New color picked! §9BLUE",
|
||||||
|
"Battle it out with snowballs! Knock back and disorient your opponents.",
|
||||||
|
"Blue", NamedTextColor.BLUE, 1000, Weather.CLEAR);
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
int minX = -20;
|
||||||
|
int maxX = 20;
|
||||||
|
int minZ = -20;
|
||||||
|
int maxZ = 20;
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
for (int y = 55; y < 75; y++) {
|
||||||
|
Pos pos = new Pos(x, y, z);
|
||||||
|
Block block = game.getInstance().getBlock(pos);
|
||||||
|
if (block.compare(Block.GRASS_BLOCK) || block.compare(Block.SAND) || block.compare(Block.MOSS_BLOCK)) {
|
||||||
|
game.getInstance().setBlock(pos, Block.SNOW_BLOCK);
|
||||||
|
}
|
||||||
|
if (block.compare(Block.MOSS_CARPET) || block.compare(Block.SHORT_GRASS) || block.compare(Block.TALL_GRASS)) {
|
||||||
|
game.getInstance().setBlock(pos, Block.AIR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snowball Supply
|
||||||
|
game.getPlayers().forEach(uuid -> {
|
||||||
|
Player player = Misc.getPlayer(uuid);
|
||||||
|
player.getInventory().addItemStack(ItemStack.of(Material.SNOWBALL, 64));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Phase end
|
||||||
|
scheduler.buildTask(() -> {
|
||||||
|
game.getPlayers().forEach(uuid -> {
|
||||||
|
Player player = Misc.getPlayer(uuid);
|
||||||
|
player.getInventory().clear();
|
||||||
|
});
|
||||||
|
resetInstance(game);
|
||||||
|
}).delay(TaskSchedule.seconds(phaseDuration-1)).schedule();
|
||||||
|
}
|
||||||
|
public static void green(GameLobby game) {
|
||||||
|
setupPhase(game, Phase.GREEN, "New color picked! §aGREEN",
|
||||||
|
"Avoid wither roses and zombies! Wither roses deal damage, while zombies eliminate players instantly.",
|
||||||
|
"Green", NamedTextColor.GREEN, 18000, Weather.CLEAR);
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
scheduler.buildTask(() -> spawnZombies(game)).delay(TaskSchedule.seconds(zombiesSpawn)).schedule();
|
||||||
|
|
||||||
|
int minX = -20;
|
||||||
|
int maxX = 20;
|
||||||
|
int minZ = -20;
|
||||||
|
int maxZ = 20;
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
for (int y = 55; y < 75; y++) {
|
||||||
|
Pos pos = new Pos(x, y, z);
|
||||||
|
Block block = game.getInstance().getBlock(pos);
|
||||||
|
if (block.compare(Block.SHORT_GRASS)) {
|
||||||
|
game.getInstance().setBlock(pos, Block.WITHER_ROSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static void yellow(GameLobby game) {
|
||||||
|
setupPhase(game, Phase.YELLOW, "New color picked! §eYELLOW",
|
||||||
|
"Thunder is coming! Find a place to hide!",
|
||||||
|
"Yellow", NamedTextColor.YELLOW, 18000, Weather.RAIN);
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
scheduler.buildTask(() -> {
|
||||||
|
Task task = scheduler.buildTask(() -> {
|
||||||
|
List<UUID> uuids = game.getPlayers();
|
||||||
|
List<Player> eligiblePlayers = new ArrayList<>();
|
||||||
|
|
||||||
|
for (UUID uuid : uuids) {
|
||||||
|
Player player = Misc.getPlayer(uuid);
|
||||||
|
if (player.getGameMode() == GameMode.ADVENTURE && !isUnderBlock(player)) {
|
||||||
|
eligiblePlayers.add(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eligiblePlayers.isEmpty()) {
|
||||||
|
Random random = new Random();
|
||||||
|
Player randomPlayer = eligiblePlayers.get(random.nextInt(eligiblePlayers.size()));
|
||||||
|
Entity lightning = new Entity(EntityType.LIGHTNING_BOLT);
|
||||||
|
lightning.setInstance(randomPlayer.getInstance(), randomPlayer.getPosition());
|
||||||
|
lightning.spawn();
|
||||||
|
game.eliminate(randomPlayer);
|
||||||
|
} else {
|
||||||
|
Random random = new Random();
|
||||||
|
Player randomPlayer = Misc.getPlayer(uuids.get(random.nextInt(uuids.size())));
|
||||||
|
Pos playerPos = randomPlayer.getPosition();
|
||||||
|
Pos lightningPos = playerPos.add(random.nextInt(11) - 5, 0, random.nextInt(11) - 5
|
||||||
|
);
|
||||||
|
|
||||||
|
Entity lightning = new Entity(EntityType.LIGHTNING_BOLT);
|
||||||
|
lightning.setInstance(randomPlayer.getInstance(), lightningPos);
|
||||||
|
lightning.spawn();
|
||||||
|
}
|
||||||
|
}).repeat(Duration.ofSeconds(5)).schedule();
|
||||||
|
game.setTask(task);
|
||||||
|
}).delay(Duration.ofSeconds(5)).schedule();
|
||||||
|
}
|
||||||
|
public static void gray(GameLobby game) {
|
||||||
|
setupPhase(game, Phase.GRAY, "New color picked! §8GRAY",
|
||||||
|
"Darkness everywhere, PvP active. Fight everyone to survive.",
|
||||||
|
"Gray", NamedTextColor.DARK_GRAY, 18000, Weather.CLEAR);
|
||||||
|
|
||||||
|
// Logic
|
||||||
|
game.getPlayers().forEach(uuid -> {
|
||||||
|
if (Misc.getPlayer(uuid).getGameMode() == GameMode.ADVENTURE) {
|
||||||
|
Misc.getPlayer(uuid).addEffect(new Potion(PotionEffect.DARKNESS, (byte) 1, phaseDuration*20));
|
||||||
|
Misc.getPlayer(uuid).addEffect(new Potion(PotionEffect.BLINDNESS, (byte) 1, phaseDuration*20));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scheduler.buildTask(() -> {
|
||||||
|
startHealthRegeneration(game);
|
||||||
|
}).delay(TaskSchedule.seconds(phaseDuration)).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setupPhase(GameLobby game, Phase phase, String colorPicked, String desc,
|
||||||
|
String colorText, NamedTextColor color, int time, Weather weather) {
|
||||||
|
game.setPhase(phase);
|
||||||
|
game.sendMessage(Component.text(colorPicked, NamedTextColor.GRAY));
|
||||||
|
game.sendMessage(Component.text(desc, color));
|
||||||
|
Misc.showTitle(game.getInstance(), Component.text("■", color), Component.text(colorText, color));
|
||||||
|
|
||||||
|
long currentGameTime = game.getInstance().getTime();
|
||||||
|
if (time != currentGameTime) {
|
||||||
|
Misc.transitionToTime(game, Duration.ofSeconds(2), currentGameTime, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
game.getInstance().setWeather(weather);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isUnderBlock(Player player) {
|
||||||
|
Pos playerPosition = player.getPosition();
|
||||||
|
for (int i = 1; i <= 5; i++) {
|
||||||
|
Pos posAbove = playerPosition.add(0, i, 0);
|
||||||
|
Block blockAbove = player.getInstance().getBlock(posAbove);
|
||||||
|
if (blockAbove.isSolid()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void spawnZombies(GameLobby game) {
|
||||||
|
List<Pos> spawnLocations = Arrays.asList(
|
||||||
|
new Pos(8, 65, 15),
|
||||||
|
new Pos(-15, 67, 7),
|
||||||
|
new Pos(11, 66, -12),
|
||||||
|
new Pos(18, 64, 3)
|
||||||
|
);
|
||||||
|
Collections.shuffle(spawnLocations);
|
||||||
|
|
||||||
|
int numZombiesToSpawn = Math.min(3, spawnLocations.size());
|
||||||
|
for (int i = 0; i < numZombiesToSpawn; i++) {
|
||||||
|
Pos pos = spawnLocations.get(i);
|
||||||
|
Entity zombie = new ZombieCreature();
|
||||||
|
zombie.setInstance(game.getInstance(), pos);
|
||||||
|
zombie.spawn();
|
||||||
|
}
|
||||||
|
|
||||||
|
scheduler.buildTask(() -> endGreen(game))
|
||||||
|
.delay(TaskSchedule.seconds(phaseDuration - zombiesSpawn))
|
||||||
|
.schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void endGreen(GameLobby game) {
|
||||||
|
for (Entity entity : game.getInstance().getEntities()) {
|
||||||
|
if (entity.getEntityType() == EntityType.ZOMBIE) {
|
||||||
|
entity.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int minX = -100;
|
||||||
|
int maxX = 100;
|
||||||
|
int minZ = -100;
|
||||||
|
int maxZ = 100;
|
||||||
|
|
||||||
|
for (int x = minX; x <= maxX; x++) {
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
|
for (int y = 55; y < 75; y++) {
|
||||||
|
Pos pos = new Pos(x, y, z);
|
||||||
|
Block block = game.getInstance().getBlock(pos);
|
||||||
|
if (block.compare(Block.WITHER_ROSE)) {
|
||||||
|
game.getInstance().setBlock(pos, Block.SHORT_GRASS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startHealthRegeneration(game);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isFlamableBlock(Block block) {
|
||||||
|
return !block.compare(Block.AIR)
|
||||||
|
&& !block.compare(Block.GRASS_BLOCK)
|
||||||
|
&& !block.compare(Block.FARMLAND)
|
||||||
|
&& !block.compare(Block.STONE)
|
||||||
|
&& !block.compare(Block.ANDESITE)
|
||||||
|
&& !block.compare(Block.ANDESITE_STAIRS)
|
||||||
|
&& !block.compare(Block.ANDESITE_SLAB)
|
||||||
|
&& !block.compare(Block.GRAVEL)
|
||||||
|
&& !block.compare(Block.DIRT_PATH)
|
||||||
|
&& !block.compare(Block.OAK_FENCE)
|
||||||
|
&& !block.compare(Block.OAK_FENCE_GATE)
|
||||||
|
&& !block.compare(Block.STONE_BRICKS)
|
||||||
|
&& !block.compare(Block.MOSSY_STONE_BRICK_WALL)
|
||||||
|
&& !block.compare(Block.MOSSY_STONE_BRICKS)
|
||||||
|
&& !block.compare(Block.MOSSY_STONE_BRICK_STAIRS)
|
||||||
|
&& !block.compare(Block.STONE_BRICK_STAIRS)
|
||||||
|
&& !block.compare(Block.MOSSY_STONE_BRICK_SLAB)
|
||||||
|
&& !block.compare(Block.STONE_BRICK_WALL)
|
||||||
|
&& !block.compare(Block.BRICK_SLAB)
|
||||||
|
&& !block.compare(Block.BRICK_STAIRS)
|
||||||
|
&& !block.compare(Block.CHAIN)
|
||||||
|
&& !block.compare(Block.WATER_CAULDRON)
|
||||||
|
&& !block.compare(Block.OAK_TRAPDOOR)
|
||||||
|
&& !block.compare(Block.SPRUCE_FENCE)
|
||||||
|
&& !block.compare(Block.SPRUCE_FENCE_GATE)
|
||||||
|
&& !block.compare(Block.SPRUCE_TRAPDOOR)
|
||||||
|
&& !block.compare(Block.SPRUCE_WALL_SIGN)
|
||||||
|
&& !block.compare(Block.SPRUCE_STAIRS)
|
||||||
|
&& !block.compare(Block.BARRIER)
|
||||||
|
&& !block.compare(Block.SAND)
|
||||||
|
&& !block.compare(Block.MOSS_BLOCK)
|
||||||
|
&& !block.compare(Block.WATER)
|
||||||
|
&& !block.compare(Block.SEA_LANTERN)
|
||||||
|
&& !block.compare(Block.RED_CARPET)
|
||||||
|
&& !block.compare(Block.WHITE_CARPET)
|
||||||
|
&& !block.compare(Block.TRIPWIRE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void resetInstance(GameLobby game) {
|
||||||
|
InstanceManager instanceManager = MinecraftServer.getInstanceManager();
|
||||||
|
InstanceContainer instanceContainer = instanceManager.createInstanceContainer();
|
||||||
|
try {
|
||||||
|
instanceContainer.setChunkLoader(new PolarLoader(Path.of("worlds/game.polar")));
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
game.setInstance(instanceContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startHealthRegeneration(GameLobby game) {
|
||||||
|
int regenerationInterval = 20; // in seconds
|
||||||
|
|
||||||
|
Task healthRegenTask = scheduler.buildTask(() -> {
|
||||||
|
for (UUID playerId : game.getPlayers()) {
|
||||||
|
Player player = Misc.getPlayer(playerId);
|
||||||
|
if (player != null && player.getGameMode() == GameMode.ADVENTURE) {
|
||||||
|
player.addEffect(new Potion(PotionEffect.REGENERATION, (byte) 1, 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).repeat(TaskSchedule.seconds(regenerationInterval)).schedule();
|
||||||
|
|
||||||
|
scheduler.buildTask(healthRegenTask::cancel).delay(TaskSchedule.seconds(phaseDuration)).schedule();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.utils;
|
||||||
|
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.classes.GameLobby;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.title.Title;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.instance.Instance;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.timer.Task;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class Misc {
|
||||||
|
static Task timeTask;
|
||||||
|
|
||||||
|
public static Player getPlayer(UUID uuid) {
|
||||||
|
return MinecraftServer.getConnectionManager().getOnlinePlayerByUuid(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showTitle(Instance instance, Component title, Component subtitle) {
|
||||||
|
for (Player player : instance.getPlayers()) { // Get all players in the instance
|
||||||
|
player.showTitle(Title.title(title, subtitle)); // Send the title to each player
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void replaceInRegion(Instance instance, Pos start, Pos end, Block newBlockType) {
|
||||||
|
int startX = (int) Math.min(start.x(), end.x());
|
||||||
|
int startY = (int) Math.min(start.y(), end.y());
|
||||||
|
int startZ = (int) Math.min(start.z(), end.z());
|
||||||
|
|
||||||
|
int endX = (int) Math.max(start.x(), end.x());
|
||||||
|
int endY = (int) Math.max(start.y(), end.y());
|
||||||
|
int endZ = (int) Math.max(start.z(), end.z());
|
||||||
|
|
||||||
|
for (int x = startX; x <= endX; x++) {
|
||||||
|
for (int y = startY; y <= endY; y++) {
|
||||||
|
for (int z = startZ; z <= endZ; z++) {
|
||||||
|
Pos pos = new Pos(x, y, z);
|
||||||
|
if (instance.getBlock(pos).compare(Block.AIR)
|
||||||
|
|| instance.getBlock(pos).compare(Block.MOSS_CARPET)
|
||||||
|
|| instance.getBlock(pos).compare(Block.SHORT_GRASS)
|
||||||
|
|| instance.getBlock(pos).compare(Block.TALL_GRASS)
|
||||||
|
|| instance.getBlock(pos).compare(Block.WHEAT)
|
||||||
|
|| instance.getBlock(pos).compare(Block.CREEPER_HEAD)
|
||||||
|
|| instance.getBlock(pos).compare(Block.RED_CARPET)
|
||||||
|
|| instance.getBlock(pos).compare(Block.WHITE_CARPET)) {
|
||||||
|
instance.setBlock(pos, newBlockType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void transitionToTime(GameLobby game, Duration duration, long startTime, long endTime) {
|
||||||
|
long transitionDuration = duration.toMillis();
|
||||||
|
long startMillis = System.currentTimeMillis();
|
||||||
|
|
||||||
|
timeTask = MinecraftServer.getSchedulerManager().buildTask(() -> {
|
||||||
|
long currentMillis = System.currentTimeMillis();
|
||||||
|
long elapsedMillis = currentMillis - startMillis;
|
||||||
|
double progress = Math.min(1.0, (double) elapsedMillis / transitionDuration);
|
||||||
|
|
||||||
|
long newTime = startTime + (long) (progress * (endTime - startTime));
|
||||||
|
game.getInstance().setTime(newTime);
|
||||||
|
|
||||||
|
if (progress >= 1.0) {
|
||||||
|
game.getInstance().setTime(endTime);
|
||||||
|
timeTask.cancel();
|
||||||
|
}
|
||||||
|
}).repeat(Duration.ofMillis(50)).schedule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Block getBlockAtPlayerPosition(Player player) {
|
||||||
|
Pos playerPosition = player.getPosition();
|
||||||
|
Instance instance = player.getInstance();
|
||||||
|
return instance.getBlock(playerPosition);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.cfox.gamejam.utils.classes;
|
package dev.celestialfox.spectrumsurvival.utils.classes;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.entity.*;
|
import net.minestom.server.entity.*;
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.cfox.gamejam.utils.classes;
|
package dev.celestialfox.spectrumsurvival.utils.classes;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.minestom.server.entity.Player;
|
import net.minestom.server.entity.Player;
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.cfox.gamejam.utils.config;
|
package dev.celestialfox.spectrumsurvival.utils.config;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.cfox.gamejam.utils.config;
|
package dev.celestialfox.spectrumsurvival.utils.config;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.cfox.gamejam.utils.config;
|
package dev.celestialfox.spectrumsurvival.utils.config;
|
||||||
|
|
||||||
public class Settings {
|
public class Settings {
|
||||||
public static String getIP() {
|
public static String getIP() {
|
|
@ -0,0 +1,177 @@
|
||||||
|
package dev.celestialfox.spectrumsurvival.utils.events;
|
||||||
|
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.classes.GameLobby;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.classes.SnowballProjectile;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.classes.ZombieCreature;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.managers.GameManager;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.managers.QueueManager;
|
||||||
|
import dev.celestialfox.spectrumsurvival.game.phases.Phase;
|
||||||
|
import dev.celestialfox.spectrumsurvival.utils.Misc;
|
||||||
|
import dev.celestialfox.spectrumsurvival.utils.classes.NPC;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.minestom.server.MinecraftServer;
|
||||||
|
import net.minestom.server.coordinate.Pos;
|
||||||
|
import net.minestom.server.coordinate.Vec;
|
||||||
|
import net.minestom.server.entity.Entity;
|
||||||
|
import net.minestom.server.entity.EntityType;
|
||||||
|
import net.minestom.server.entity.GameMode;
|
||||||
|
import net.minestom.server.entity.Player;
|
||||||
|
import net.minestom.server.entity.damage.Damage;
|
||||||
|
import net.minestom.server.entity.damage.DamageType;
|
||||||
|
import net.minestom.server.event.GlobalEventHandler;
|
||||||
|
import net.minestom.server.event.entity.EntityAttackEvent;
|
||||||
|
import net.minestom.server.event.entity.EntityDamageEvent;
|
||||||
|
import net.minestom.server.event.entity.projectile.ProjectileCollideWithBlockEvent;
|
||||||
|
import net.minestom.server.event.entity.projectile.ProjectileCollideWithEntityEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerDeathEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerMoveEvent;
|
||||||
|
import net.minestom.server.event.player.PlayerUseItemEvent;
|
||||||
|
import net.minestom.server.instance.block.Block;
|
||||||
|
import net.minestom.server.item.ItemStack;
|
||||||
|
import net.minestom.server.item.Material;
|
||||||
|
import net.minestom.server.timer.TaskSchedule;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.swing.text.Position;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class MiscEvents {
|
||||||
|
private static final double KNOCKBACK_STRENGTH = 15.0;
|
||||||
|
static GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(MiscEvents.class);
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
logger.debug("Registering Misc Listeners");
|
||||||
|
globalEventHandler.addListener(PlayerMoveEvent.class, event -> {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
if (GameManager.isPlayerInGame(player)) {
|
||||||
|
if (GameManager.getPlayerGame(player).getPhase() == Phase.GREEN) {
|
||||||
|
if (Misc.getBlockAtPlayerPosition(player) == Block.WITHER_ROSE && player.getGameMode() == GameMode.ADVENTURE) {
|
||||||
|
player.damage(Damage.fromPlayer(player, 1));
|
||||||
|
}
|
||||||
|
} else if (GameManager.getPlayerGame(player).getPhase() == Phase.RED) {
|
||||||
|
if (Misc.getBlockAtPlayerPosition(player) == Block.FIRE && player.getGameMode() == GameMode.ADVENTURE) {
|
||||||
|
player.damage(Damage.fromPosition(DamageType.IN_FIRE, player.getPosition(), 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalEventHandler.addListener(EntityAttackEvent.class, event -> {
|
||||||
|
Entity targeter = event.getEntity();
|
||||||
|
Entity targeted = event.getTarget();
|
||||||
|
|
||||||
|
if (targeter instanceof Player player) {
|
||||||
|
if (targeted instanceof NPC npc && npc.getCustomName().equals(Component.text("Join the Queue"))) {
|
||||||
|
QueueManager.joinPlayer(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targeted instanceof Player player2) {
|
||||||
|
if (player.getGameMode() == GameMode.ADVENTURE) {
|
||||||
|
applyKnockback(player, player2);
|
||||||
|
if (GameManager.isPlayerInGame(player)) {
|
||||||
|
if (GameManager.getPlayerGame(player).getPhase() == Phase.GRAY) {
|
||||||
|
player2.damage(Damage.fromPlayer(player, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targeted instanceof Player player) {
|
||||||
|
if (GameManager.isPlayerInGame(player)) {
|
||||||
|
if (GameManager.getPlayerGame(player).getPhase() == Phase.GREEN) {
|
||||||
|
if (targeter instanceof ZombieCreature) {
|
||||||
|
ZombieCreature zombie = new ZombieCreature();
|
||||||
|
zombie.setInstance(player.getInstance(), player.getPosition());
|
||||||
|
GameManager.getPlayerGame(player).eliminate(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalEventHandler.addListener(EntityDamageEvent.class, event -> {
|
||||||
|
Entity damaged = event.getEntity();
|
||||||
|
if (damaged instanceof Player player) {
|
||||||
|
if (player.getHealth() == 1 && GameManager.isPlayerInGame(player)) {
|
||||||
|
GameManager.getPlayerGame(player).eliminate(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalEventHandler.addListener(PlayerDisconnectEvent.class, event -> {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
GameLobby playerGame = GameManager.getPlayerGame(player);
|
||||||
|
UUID uuid = player.getUuid();
|
||||||
|
if (GameManager.isPlayerInGame(player)) {
|
||||||
|
playerGame.getPlayers().remove(uuid);
|
||||||
|
playerGame.getEliminated().remove(uuid);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalEventHandler.addListener(PlayerUseItemEvent.class, event -> {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
ItemStack item = event.getItemStack();
|
||||||
|
|
||||||
|
if (item.material() == Material.SNOWBALL) {
|
||||||
|
Pos playerPosition = player.getPosition().add(0, 1.5, 0);
|
||||||
|
Vec direction = player.getPosition().direction().normalize().mul(20);
|
||||||
|
SnowballProjectile snowball = new SnowballProjectile(player);
|
||||||
|
|
||||||
|
snowball.setInstance(player.getInstance(), playerPosition);
|
||||||
|
snowball.setVelocity(direction);
|
||||||
|
snowball.setNoGravity(false);
|
||||||
|
snowball.spawn();
|
||||||
|
|
||||||
|
MinecraftServer.getSchedulerManager().buildTask(() -> {
|
||||||
|
if (snowball.isActive()) {
|
||||||
|
snowball.remove();
|
||||||
|
}
|
||||||
|
}).delay(TaskSchedule.seconds(10)).schedule();
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalEventHandler.addListener(ProjectileCollideWithBlockEvent.class, event -> {
|
||||||
|
if (event.getEntity() instanceof SnowballProjectile snowball) {
|
||||||
|
if (snowball.isActive()) {
|
||||||
|
snowball.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalEventHandler.addListener(ProjectileCollideWithEntityEvent.class, event -> {
|
||||||
|
if (event.getEntity() instanceof SnowballProjectile snowball) {
|
||||||
|
if (event.getTarget() instanceof Player target) {
|
||||||
|
if (snowball.isActive()) {
|
||||||
|
snowball.remove();
|
||||||
|
}
|
||||||
|
target.damage(Damage.fromProjectile(snowball, snowball, 0.75F));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
globalEventHandler.addListener(PlayerDeathEvent.class, event -> {
|
||||||
|
// Cancel the default death message
|
||||||
|
event.setDeathText(Component.text("You were eliminated!"));
|
||||||
|
event.setChatMessage(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyKnockback(Player attacker, Player target) {
|
||||||
|
Pos targetPos = target.getPosition();
|
||||||
|
Pos attackerPos = attacker.getPosition();
|
||||||
|
double dx = targetPos.x() - attackerPos.x();
|
||||||
|
double dz = targetPos.z() - attackerPos.z();
|
||||||
|
double length = Math.sqrt(dx * dx + dz * dz);
|
||||||
|
|
||||||
|
if (length > 0) {
|
||||||
|
dx /= length;
|
||||||
|
dz /= length;
|
||||||
|
target.setVelocity(target.getVelocity().add(dx * KNOCKBACK_STRENGTH, 0, dz * KNOCKBACK_STRENGTH));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,12 +1,10 @@
|
||||||
package dev.cfox.gamejam.utils.events;
|
package dev.celestialfox.spectrumsurvival.utils.events;
|
||||||
|
|
||||||
import dev.cfox.gamejam.utils.Misc;
|
import dev.celestialfox.spectrumsurvival.game.managers.QueueManager;
|
||||||
import dev.cfox.gamejam.utils.classes.NPC;
|
import dev.celestialfox.spectrumsurvival.utils.classes.NPC;
|
||||||
import dev.cfox.gamejam.utils.classes.Randomized;
|
|
||||||
import net.hollowcube.polar.PolarLoader;
|
import net.hollowcube.polar.PolarLoader;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.entity.GameMode;
|
import net.minestom.server.entity.GameMode;
|
||||||
|
@ -16,13 +14,11 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
|
||||||
import net.minestom.server.event.player.PlayerChatEvent;
|
import net.minestom.server.event.player.PlayerChatEvent;
|
||||||
import net.minestom.server.event.player.PlayerSpawnEvent;
|
import net.minestom.server.event.player.PlayerSpawnEvent;
|
||||||
import net.minestom.server.instance.*;
|
import net.minestom.server.instance.*;
|
||||||
import net.minestom.server.instance.block.Block;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.time.Duration;
|
|
||||||
|
|
||||||
public class StartEvents {
|
public class StartEvents {
|
||||||
static GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
static GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
||||||
|
@ -50,14 +46,15 @@ public class StartEvents {
|
||||||
final Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
player.setGameMode(GameMode.ADVENTURE);
|
player.setGameMode(GameMode.ADVENTURE);
|
||||||
event.setSpawningInstance(instanceContainer);
|
event.setSpawningInstance(instanceContainer);
|
||||||
player.setRespawnPoint(new Pos(0.5, 66, 0.5, 180, 0));
|
player.setRespawnPoint(new Pos(0, 66, 0, 180, 0));
|
||||||
});
|
});
|
||||||
globalEventHandler.addListener(PlayerSpawnEvent.class, event -> {
|
globalEventHandler.addListener(PlayerSpawnEvent.class, event -> {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
if (event.isFirstSpawn()) {
|
if (event.isFirstSpawn()) {
|
||||||
player.sendMessage(Component.text(
|
player.sendMessage(
|
||||||
"§ePunch §rthe Minestom NPC to §ajoin the queue!", NamedTextColor.GRAY));
|
Component.text("Use §e/about game §rto read the rules.", NamedTextColor.GRAY)
|
||||||
|
.append(Component.text("§ePunch §rthe Minestom NPC to §ajoin the queue!", NamedTextColor.GRAY)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -77,6 +74,8 @@ public class StartEvents {
|
||||||
"yWIH6gVDRhgd/HwVYpRT87NBHf+q9EgYs/CYqIwnz5xXR22k29c7MTnaYFvWukbwF1FhWNilAyYzagSn/7ScvOpYn0RtyTWk656cwjzFSbTsSFzRwUl5f4mu1EeunYh8v5cZH27KTfAI7a9Q7ylXz7NoAbvaw056thXa7jHhLhFdPECnziRTnv9jDRwpoN/4jblmdOz5NCLtynubf8hwIwm9od18tXy4+gsV3aXS5+1MirpWDizqdozb9mtwzML9NYwVNpO2bRB9KYJ91VUWqxjfTy/q0xFQ1paolq4pp3tgvLXw0y+rdwCsCgh39JA4MKvIIJShww5xbqo4oFBRDj+/BI3+Y154Ess1004vE+iTRdt+az0v4y+evnOQLgryEr/36QzZOndpSFqYfKPl1MeUeZe1u4VDQJcgyJImg2TZJbG2WOmmTySWSEPrHcYC6c3Y9rVnQ6Zi4NxTe4e6/ZuDQVm14fuSUPd4Ll7/aIDyumHupBMMbBEa9qCmuZJPT5iWVlIGfzA2Dg/kea4Jw9WudUmiCYngB56HZEivDPniIxeGSTRFHMR2FfTKnLkxb2LDOvD+CgDWyr8cGy4xnB2hwdY2n28cCAYI5axj0qzCpHMl8Y90e2rKfX7NsUvyivbAVRwAsd/bWkkJoZ4/QStFEjV//81iNbuUz/4lFQA=");
|
"yWIH6gVDRhgd/HwVYpRT87NBHf+q9EgYs/CYqIwnz5xXR22k29c7MTnaYFvWukbwF1FhWNilAyYzagSn/7ScvOpYn0RtyTWk656cwjzFSbTsSFzRwUl5f4mu1EeunYh8v5cZH27KTfAI7a9Q7ylXz7NoAbvaw056thXa7jHhLhFdPECnziRTnv9jDRwpoN/4jblmdOz5NCLtynubf8hwIwm9od18tXy4+gsV3aXS5+1MirpWDizqdozb9mtwzML9NYwVNpO2bRB9KYJ91VUWqxjfTy/q0xFQ1paolq4pp3tgvLXw0y+rdwCsCgh39JA4MKvIIJShww5xbqo4oFBRDj+/BI3+Y154Ess1004vE+iTRdt+az0v4y+evnOQLgryEr/36QzZOndpSFqYfKPl1MeUeZe1u4VDQJcgyJImg2TZJbG2WOmmTySWSEPrHcYC6c3Y9rVnQ6Zi4NxTe4e6/ZuDQVm14fuSUPd4Ll7/aIDyumHupBMMbBEa9qCmuZJPT5iWVlIGfzA2Dg/kea4Jw9WudUmiCYngB56HZEivDPniIxeGSTRFHMR2FfTKnLkxb2LDOvD+CgDWyr8cGy4xnB2hwdY2n28cCAYI5axj0qzCpHMl8Y90e2rKfX7NsUvyivbAVRwAsd/bWkkJoZ4/QStFEjV//81iNbuUz/4lFQA=");
|
||||||
joinNPC.setInstance(instanceContainer, new Pos(0.5, 66.5, -16.5));
|
joinNPC.setInstance(instanceContainer, new Pos(0.5, 66.5, -16.5));
|
||||||
|
|
||||||
|
QueueManager.lobbyInstance = instanceContainer;
|
||||||
|
|
||||||
return instanceContainer;
|
return instanceContainer;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
package dev.cfox.gamejam.game.commands;
|
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.managers.GameManager;
|
|
||||||
import dev.cfox.gamejam.game.managers.QueueManager;
|
|
||||||
import net.kyori.adventure.sound.Sound;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.command.builder.Command;
|
|
||||||
import net.minestom.server.command.builder.arguments.ArgumentType;
|
|
||||||
import net.minestom.server.entity.Entity;
|
|
||||||
import net.minestom.server.entity.EntityType;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.sound.SoundEvent;
|
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
|
||||||
import net.minestom.server.utils.NamespaceID;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class QueueCommand extends Command {
|
|
||||||
public QueueCommand() {
|
|
||||||
super("queue", "q");
|
|
||||||
addSyntax(((sender, context) -> {
|
|
||||||
final String arg1 = context.get("arg1");
|
|
||||||
if (sender instanceof Player player) {
|
|
||||||
if (arg1.equals("join")) {
|
|
||||||
QueueManager.joinPlayer(player);
|
|
||||||
} else if (arg1.equals("leave")) {
|
|
||||||
QueueManager.removePlayer(player);
|
|
||||||
} else if (arg1.equals("force")) {
|
|
||||||
GameManager.startGame(QueueManager.getPlayerQueue(player));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}), ArgumentType.String("arg1"));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,108 +0,0 @@
|
||||||
package dev.cfox.gamejam.game.phases;
|
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.classes.GameLobby;
|
|
||||||
import dev.cfox.gamejam.game.managers.ConversionManager;
|
|
||||||
import dev.cfox.gamejam.utils.Misc;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.entity.Entity;
|
|
||||||
import net.minestom.server.entity.EntityType;
|
|
||||||
import net.minestom.server.entity.GameMode;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.timer.SchedulerManager;
|
|
||||||
import net.minestom.server.timer.Task;
|
|
||||||
import net.minestom.server.timer.TaskSchedule;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class PhaseLogic {
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(PhaseLogic.class);
|
|
||||||
private static final SchedulerManager scheduler = MinecraftServer.getSchedulerManager();
|
|
||||||
private static int phaseDuration = 30; // in seconds
|
|
||||||
private static int gameTime = 300; // 5 minutes in seconds
|
|
||||||
|
|
||||||
public static void random(GameLobby game) {
|
|
||||||
Task task = scheduler.buildTask(() -> {
|
|
||||||
Phase[] phases = Phase.values();
|
|
||||||
int randomIndex = new Random().nextInt(phases.length);
|
|
||||||
Phase selectedPhase = phases[randomIndex];
|
|
||||||
if (game.getTask() != null) {
|
|
||||||
game.getTask().cancel();
|
|
||||||
}
|
|
||||||
switch (selectedPhase) {
|
|
||||||
case RED -> red(game);
|
|
||||||
case BLUE -> blue(game);
|
|
||||||
case GREEN -> green(game);
|
|
||||||
case YELLOW -> yellow(game);
|
|
||||||
case PURPLE -> purple(game);
|
|
||||||
}
|
|
||||||
}).repeat(TaskSchedule.seconds(phaseDuration)).schedule();
|
|
||||||
scheduler.buildTask(() -> {
|
|
||||||
ConversionManager.fromGame(game);
|
|
||||||
task.cancel();
|
|
||||||
}).delay(TaskSchedule.seconds(gameTime)).schedule();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void red(GameLobby game) {
|
|
||||||
logger.debug("Picked red phase for GameLobby: " + game.getName());
|
|
||||||
game.setPhase(Phase.RED);
|
|
||||||
game.sendMessage(Component.text("New color picked! §cRED", NamedTextColor.GRAY));
|
|
||||||
game.sendMessage(Component.text("BLAH BLAH BLAH BLAH", NamedTextColor.RED));
|
|
||||||
Misc.showTitle(game.getInstance(), Component.text("■", NamedTextColor.RED), Component.text("Red", NamedTextColor.RED));
|
|
||||||
// Handle red phase logic
|
|
||||||
}
|
|
||||||
public static void blue(GameLobby game) {
|
|
||||||
logger.debug("Picked blue phase for GameLobby: " + game.getName());
|
|
||||||
game.setPhase(Phase.BLUE);
|
|
||||||
game.sendMessage(Component.text("New color picked! §9BLUE", NamedTextColor.GRAY));
|
|
||||||
game.sendMessage(Component.text("BLAH BLAH BLAH BLAH", NamedTextColor.BLUE));
|
|
||||||
Misc.showTitle(game.getInstance(), Component.text("■", NamedTextColor.BLUE), Component.text("Blue", NamedTextColor.BLUE));
|
|
||||||
// Handle blue phase logic
|
|
||||||
}
|
|
||||||
public static void green(GameLobby game) {
|
|
||||||
logger.debug("Picked green phase for GameLobby: " + game.getName());
|
|
||||||
game.setPhase(Phase.GREEN);
|
|
||||||
game.sendMessage(Component.text("New color picked! §aGREEN", NamedTextColor.GRAY));
|
|
||||||
game.sendMessage(Component.text("BLAH BLAH BLAH BLAH", NamedTextColor.GREEN));
|
|
||||||
Misc.showTitle(game.getInstance(), Component.text("■", NamedTextColor.GREEN), Component.text("Green", NamedTextColor.GREEN));
|
|
||||||
// Handle green phase logic
|
|
||||||
}
|
|
||||||
public static void yellow(GameLobby game) {
|
|
||||||
logger.debug("Picked yellow phase for GameLobby: " + game.getName());
|
|
||||||
game.setPhase(Phase.YELLOW);
|
|
||||||
game.sendMessage(Component.text("New color picked! §eYELLOW", NamedTextColor.GRAY));
|
|
||||||
game.sendMessage(Component.text("Thunder is coming! Find a place to hide!", NamedTextColor.YELLOW));
|
|
||||||
Misc.showTitle(game.getInstance(), Component.text("■", NamedTextColor.YELLOW), Component.text("Yellow", NamedTextColor.YELLOW));
|
|
||||||
scheduler.buildTask(() -> {
|
|
||||||
Task task = scheduler.buildTask(() -> {
|
|
||||||
List<UUID> uuids = game.getPlayers();
|
|
||||||
Random random = new Random();
|
|
||||||
Player randomPlayer = null;
|
|
||||||
|
|
||||||
while (randomPlayer == null || randomPlayer.getGameMode() != GameMode.ADVENTURE) {
|
|
||||||
randomPlayer = Misc.getPlayer(uuids.get(random.nextInt(uuids.size())));
|
|
||||||
}
|
|
||||||
|
|
||||||
Entity lightning = new Entity(EntityType.LIGHTNING_BOLT);
|
|
||||||
lightning.setInstance(randomPlayer.getInstance(), randomPlayer.getPosition());
|
|
||||||
lightning.spawn();
|
|
||||||
game.eliminate(randomPlayer);
|
|
||||||
}).repeat(Duration.ofSeconds(5)).schedule();
|
|
||||||
game.setTask(task);
|
|
||||||
}).delay(Duration.ofSeconds(5)).schedule();
|
|
||||||
}
|
|
||||||
public static void purple(GameLobby game) {
|
|
||||||
logger.debug("Picked purple phase for GameLobby: " + game.getName());
|
|
||||||
game.setPhase(Phase.PURPLE);
|
|
||||||
game.sendMessage(Component.text("New color picked! §dPURPLE", NamedTextColor.GRAY));
|
|
||||||
game.sendMessage(Component.text("BLAH BLAH BLAH BLAH", NamedTextColor.LIGHT_PURPLE));
|
|
||||||
Misc.showTitle(game.getInstance(), Component.text("■", NamedTextColor.LIGHT_PURPLE), Component.text("Purple", NamedTextColor.LIGHT_PURPLE));
|
|
||||||
// Handle purple phase logic
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
package dev.cfox.gamejam.utils;
|
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.title.Title;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.coordinate.Pos;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.instance.Instance;
|
|
||||||
import net.minestom.server.instance.block.Block;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class Misc {
|
|
||||||
public static Player getPlayer(UUID uuid) {
|
|
||||||
return MinecraftServer.getConnectionManager().getOnlinePlayerByUuid(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showTitle(Instance instance, Component title, Component subtitle) {
|
|
||||||
for (Player player : instance.getPlayers()) { // Get all players in the instance
|
|
||||||
player.showTitle(Title.title(title, subtitle)); // Send the title to each player
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void replaceAirInRegion(Instance instance, Pos start, Pos end, Block newBlockType) {
|
|
||||||
int startX = (int) Math.min(start.x(), end.x());
|
|
||||||
int startY = (int) Math.min(start.y(), end.y());
|
|
||||||
int startZ = (int) Math.min(start.z(), end.z());
|
|
||||||
|
|
||||||
int endX = (int) Math.max(start.x(), end.x());
|
|
||||||
int endY = (int) Math.max(start.y(), end.y());
|
|
||||||
int endZ = (int) Math.max(start.z(), end.z());
|
|
||||||
|
|
||||||
for (int x = startX; x <= endX; x++) {
|
|
||||||
for (int y = startY; y <= endY; y++) {
|
|
||||||
for (int z = startZ; z <= endZ; z++) {
|
|
||||||
Pos pos = new Pos(x, y, z);
|
|
||||||
if (instance.getBlock(pos).compare(Block.AIR)) {
|
|
||||||
instance.setBlock(pos, newBlockType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
package dev.cfox.gamejam.utils.events;
|
|
||||||
|
|
||||||
import dev.cfox.gamejam.game.managers.GameManager;
|
|
||||||
import dev.cfox.gamejam.game.managers.QueueManager;
|
|
||||||
import dev.cfox.gamejam.game.phases.Phase;
|
|
||||||
import dev.cfox.gamejam.utils.classes.NPC;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.minestom.server.MinecraftServer;
|
|
||||||
import net.minestom.server.entity.Entity;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.event.GlobalEventHandler;
|
|
||||||
import net.minestom.server.event.entity.EntityAttackEvent;
|
|
||||||
import net.minestom.server.event.player.PlayerMoveEvent;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class MiscEvents {
|
|
||||||
static GlobalEventHandler globalEventHandler = MinecraftServer.getGlobalEventHandler();
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(MiscEvents.class);
|
|
||||||
|
|
||||||
public static void register() {
|
|
||||||
logger.debug("Registering Misc Listeners");
|
|
||||||
globalEventHandler.addListener(PlayerMoveEvent.class, event -> {
|
|
||||||
Player player = event.getPlayer();
|
|
||||||
if (GameManager.isPlayerInGame(player)) {
|
|
||||||
Phase phase = GameManager.getPlayerGame(player).getPhase();
|
|
||||||
|
|
||||||
if (phase == Phase.YELLOW) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
globalEventHandler.addListener(EntityAttackEvent.class, event -> {
|
|
||||||
Entity targeter = event.getEntity();
|
|
||||||
Entity targeted = event.getTarget();
|
|
||||||
|
|
||||||
if (targeter instanceof Player player) {
|
|
||||||
if (targeted instanceof NPC npc && npc.getCustomName().equals(Component.text("Join the Queue"))) {
|
|
||||||
QueueManager.joinPlayer(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue