1
0
Fork 0

Additional changes for second Playtest

This commit is contained in:
Andus 2024-08-31 12:14:55 +02:00
parent cdc73cc230
commit 70e69cc76f
12 changed files with 180 additions and 160 deletions

Binary file not shown.

View file

@ -3,7 +3,7 @@ package dev.celestialfox.spectrumsurvival;
import dev.celestialfox.spectrumsurvival.game.commands.*;
import dev.celestialfox.spectrumsurvival.game.managers.GameManager;
import dev.celestialfox.spectrumsurvival.game.managers.QueueManager;
import dev.celestialfox.spectrumsurvival.utils.classes.SignHandler;
import dev.celestialfox.spectrumsurvival.utils.classes.Randomized;
import dev.celestialfox.spectrumsurvival.utils.config.Checks;
import dev.celestialfox.spectrumsurvival.utils.config.Settings;
import dev.celestialfox.spectrumsurvival.utils.events.MiscEvents;
@ -44,7 +44,6 @@ public class Server {
Terminal.start();
tablist();
MinecraftServer.getBlockManager().registerHandler("minecraft:spruce_wall_sign", SignHandler::new);
// Server Start
BungeeCordProxy.enable();
@ -67,31 +66,9 @@ public class Server {
.append(Component.text("\nᴘʟᴀʏᴇʀѕ ɪɴ-ɢᴀᴍᴇ: " + GameManager.getPlayersInGame() + "\n", NamedTextColor.BLUE)));
Component footer = Component.newline()
.append(Component.text("ᴍᴀᴅᴇ ʙʏ: CelestialFox Studio", randomMadeByColor()));
.append(Component.text("ᴍᴀᴅᴇ ʙʏ: CelestialFox Studio", Randomized.madeByColor()));
Audiences.players().sendPlayerListHeaderAndFooter(header, footer);
}, TaskSchedule.tick(10), TaskSchedule.tick(10));
}
public static NamedTextColor randomMadeByColor() {
Random random = new Random();
int num = random.nextInt(4);
switch (num) {
case 0 -> {
return NamedTextColor.BLUE;
}
case 1 -> {
return NamedTextColor.GRAY;
}
case 2 -> {
return NamedTextColor.GOLD;
}
case 3 -> {
return NamedTextColor.GREEN;
}
default -> {
return NamedTextColor.RED;
}
}
}
}

View file

@ -33,8 +33,10 @@ public class GameLobby {
private Task latestTask;
private Task repeatTask;
private Task endTask;
private Task bossBarTask;
private Instance instance;
private String name = "";
private long phaseStartTime;
public void setPlayers(ArrayList<UUID> playerList) {
players.addAll(playerList);
@ -116,18 +118,28 @@ public class GameLobby {
public Task getTask() {
return latestTask;
}
public void setRepeatTask(Task task) {
repeatTask = task;
}
public Task getRepeatTask() {
return repeatTask;
}
public void setEndTask(Task task) {
endTask = task;
}
public Task getEndTask() {
return endTask;
}
public void setBossBarTask(Task task) {
bossBarTask = task;
}
public Task getBossBarTask() {
return bossBarTask;
}
public long getPhaseStartTime() {
return phaseStartTime;
}
public void setPhaseStartTime(long phaseStartTime) {
this.phaseStartTime = phaseStartTime;
}
}

View file

@ -5,6 +5,7 @@ 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.goal.RandomStrollGoal;
import net.minestom.server.entity.ai.target.ClosestEntityTarget;
import net.minestom.server.entity.attribute.Attribute;
import net.minestom.server.utils.time.TimeUnit;
@ -15,16 +16,15 @@ public class ZombieCreature extends EntityCreature {
public ZombieCreature() {
super(EntityType.ZOMBIE);
getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.15);
getAttribute(Attribute.GENERIC_MOVEMENT_SPEED).setBaseValue(0.2);
addAIGroup(
List.of(
new MeleeAttackGoal(this, 1.6, 20, TimeUnit.SERVER_TICK) // Attack the target
new MeleeAttackGoal(this, 1.6, 20, TimeUnit.SERVER_TICK), // Attack the target
new RandomStrollGoal(this, 20) // Walk around
),
List.of(
new ClosestEntityTarget(this, 50,
entity -> entity instanceof Player && ((Player) entity).getGameMode() != GameMode.SPECTATOR) // Target the nearest player
new ClosestEntityTarget(this, 64, entity -> entity instanceof Player player
&& player.getGameMode() != GameMode.SPECTATOR) // If there is none, target the nearest player
)
);
}

View file

@ -1,6 +1,5 @@
package dev.celestialfox.spectrumsurvival.game.managers;
import dev.celestialfox.spectrumsurvival.game.classes.GameLobby;
import dev.celestialfox.spectrumsurvival.utils.Misc;
import dev.celestialfox.spectrumsurvival.game.classes.GameQueue;
import net.kyori.adventure.key.Key;
@ -22,7 +21,7 @@ public class QueueManager {
public static List<GameQueue> queues = new ArrayList<>();
private static final HashMap<GameQueue, Task> countdownTasks = new HashMap<>();
private static int minPlayers = 6;
private static int maxPlayers = 10;
private static int maxPlayers = 12;
public static Instance lobbyInstance;
public static void joinPlayer(Player player) {
@ -46,8 +45,8 @@ public class QueueManager {
createQueue(player);
}
player.sendMessage(Component.text("The queue starts the countdown from §e6 players.", NamedTextColor.GRAY));
player.sendMessage(Component.text("One queue can hold up to §e10 players.", NamedTextColor.GRAY));
player.sendMessage(Component.text("The queue starts the countdown from §e" + minPlayers + " players.", NamedTextColor.GRAY));
player.sendMessage(Component.text("One queue can hold up to §e" + maxPlayers + " players.", NamedTextColor.GRAY));
player.sendMessage(Component.text("§e§lWaiting for too long? §rUse §a/queue force §rto start now.", NamedTextColor.GRAY));
}
}

View file

@ -0,0 +1,28 @@
package dev.celestialfox.spectrumsurvival.game.phases;
import dev.celestialfox.spectrumsurvival.game.classes.GameLobby;
import dev.celestialfox.spectrumsurvival.utils.Misc;
import net.kyori.adventure.bossbar.BossBar;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
public class PhaseBossBar {
public static void updateBossBar(GameLobby game, BossBar nextPhaseBossBar, int phaseDuration) {
long currentTime = System.currentTimeMillis();
long elapsedMillis = currentTime - game.getPhaseStartTime();
long elapsedSeconds = elapsedMillis / 1000;
float progress = 1.0f - (float) elapsedSeconds / phaseDuration;
nextPhaseBossBar.progress(Math.max(progress, 0.0f));
long remainingSeconds = phaseDuration - elapsedSeconds;
String remainingTime = String.format("%d seconds until next phase", Math.max(remainingSeconds, 0));
nextPhaseBossBar.name(Component.text(remainingTime, NamedTextColor.WHITE));
}
public static void resetBossBarProgress(BossBar nextPhaseBossBar) {
nextPhaseBossBar.progress(1.0f);
}
public static void removeBossBar(GameLobby game, BossBar nextPhaseBossBar) {
game.getPlayers().forEach(uuid -> Misc.getPlayer(uuid).hideBossBar(nextPhaseBossBar));
}
}

View file

@ -6,6 +6,7 @@ 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.bossbar.BossBar;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.MinecraftServer;
@ -42,6 +43,7 @@ public class PhaseLogic {
private static Task endTask;
private static final int zombiesSpawn = 5;
private static BossBar nextPhaseBossBar;
public static void random(GameLobby game) {
if (game.getRepeatTask() != null) {
@ -51,15 +53,26 @@ public class PhaseLogic {
game.getEndTask().cancel();
}
nextPhaseBossBar = BossBar.bossBar(
Component.text("Time until next phase", NamedTextColor.WHITE),
1.0f, // progress (between 0.0 and 1.0)
BossBar.Color.WHITE,
BossBar.Overlay.PROGRESS
);
game.getPlayers().forEach(uuid -> Misc.getPlayer(uuid).showBossBar(nextPhaseBossBar));
Task bossBarTask = scheduler.buildTask(() -> PhaseBossBar.updateBossBar(game, nextPhaseBossBar, phaseDuration))
.repeat(TaskSchedule.tick(1))
.schedule();
game.setBossBarTask(bossBarTask);
repeatTask = scheduler.buildTask(() -> {
// Check if all players are eliminated
if (game.getEliminated().size() == game.getPlayers().size()) {
ConversionManager.fromGame(game);
game.getRepeatTask().cancel();
endGame(game);
game.getEndTask().cancel();
if (game.getTask() != null) {
game.getTask().cancel();
}
} else {
logger.debug("Starting random phase selection for GameLobby: {}", game.getName());
if (game.getTask() != null) {
@ -68,9 +81,9 @@ public class PhaseLogic {
try {
Phase[] phases = Phase.values();
Phase selectedPhase;
Random random = new Random(System.nanoTime());
do {
int randomIndex = new Random().nextInt(phases.length);
selectedPhase = phases[randomIndex];
selectedPhase = phases[random.nextInt(phases.length)];
} while (
(selectedPhase == game.getPhase())
|| ((selectedPhase == Phase.GRAY || selectedPhase == Phase.BLUE) && (game.getPlayers().size() == game.getEliminated().size()+1)));
@ -92,17 +105,13 @@ public class PhaseLogic {
endTask = scheduler.buildTask(() -> {
try {
logger.debug("Ending game for GameLobby: {}", game.getName());
ConversionManager.fromGame(game);
game.getRepeatTask().cancel();
if (game.getTask() != null) {
game.getTask().cancel();
}
endGame(game);
} catch (Exception e) {
logger.error("Exception occurred during game ending: {}", e.getMessage());
}
}).delay(TaskSchedule.seconds(gameTime)).schedule();
game.setPhaseStartTime(System.currentTimeMillis());
game.setRepeatTask(repeatTask);
game.setEndTask(endTask);
}
@ -114,16 +123,16 @@ public class PhaseLogic {
// Logic
List<Pos> positions = new ArrayList<>();
int minX = -10;
int maxX = 10;
int minZ = -10;
int maxZ = 10;
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++) {
for (int y = 66; y < 70; y++) {
Pos pos = new Pos(x, y, z);
if (new Random().nextInt(10) < 2) {
if (isFlamableBlock(game.getInstance().getBlock(pos))) {
if (new Random().nextInt(5) < 2) {
if (Misc.isFlamableBlock(game.getInstance().getBlock(pos))) {
positions.add(pos);
}
}
@ -138,7 +147,7 @@ public class PhaseLogic {
Pos pos = iterator.next();
game.getInstance().setBlock(pos, Block.FIRE);
}
}).repeat(Duration.ofMillis(250)).schedule();
}).repeat(TaskSchedule.tick(1)).schedule();
scheduler.buildTask(() -> {
task.cancel();
@ -197,7 +206,7 @@ public class PhaseLogic {
}
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.",
"Wither roses harm, zombies kill instantly.",
"Green", NamedTextColor.GREEN, 18000, Weather.CLEAR);
// Logic
@ -253,13 +262,13 @@ public class PhaseLogic {
lightning.setInstance(randomPlayer.getInstance(), lightningPos);
lightning.spawn();
}
}).delay(Duration.ofSeconds(5)).repeat(Duration.ofSeconds(2)).schedule();
}).delay(Duration.ofSeconds(5)).repeat(Duration.ofSeconds(3)).schedule();
game.setTask(task);
}
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);
"Gray", NamedTextColor.GRAY, 18000, Weather.CLEAR);
// Logic
game.getPlayers().forEach(uuid -> {
@ -273,10 +282,14 @@ public class PhaseLogic {
public static void setupPhase(GameLobby game, Phase phase, String colorPicked, String desc,
String colorText, NamedTextColor color, int time, Weather weather) {
PhaseBossBar.resetBossBarProgress(nextPhaseBossBar);
game.setPhaseStartTime(System.currentTimeMillis());
PhaseBossBar.updateBossBar(game, nextPhaseBossBar, phaseDuration);
game.setPhase(phase);
game.sendMessage(Component.text(colorPicked, NamedTextColor.GRAY));
game.sendMessage(Component.text(colorPicked, NamedTextColor.WHITE));
game.sendMessage(Component.text(desc, color));
Misc.showTitle(game.getInstance(), Component.text("", color), Component.text(colorText, color));
Misc.showTitle(game.getInstance(), Component.text(" " + colorText + "", color), Component.text(desc, color));
long currentGameTime = game.getInstance().getTime();
if (time != currentGameTime) {
@ -286,6 +299,17 @@ public class PhaseLogic {
game.getInstance().setWeather(weather);
}
public static void endGame(GameLobby game) {
logger.debug("Ending game for GameLobby: {}", game.getName());
ConversionManager.fromGame(game);
game.getRepeatTask().cancel();
game.getBossBarTask().cancel();
if (game.getTask() != null) {
game.getTask().cancel();
}
PhaseBossBar.removeBossBar(game, nextPhaseBossBar);
}
private static boolean isUnderBlock(Player player) {
Pos playerPosition = player.getPosition();
for (int i = 1; i <= 5; i++) {
@ -346,45 +370,6 @@ public class PhaseLogic {
}
}
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();
@ -396,4 +381,6 @@ public class PhaseLogic {
game.setInstance(instanceContainer);
}
}

View file

@ -26,34 +26,6 @@ public class Misc {
}
}
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();
@ -78,4 +50,45 @@ public class Misc {
Instance instance = player.getInstance();
return instance.getBlock(playerPosition);
}
public 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.OAK_PLANKS)
&& !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.LILY_PAD)
&& !block.compare(Block.SEA_LANTERN)
&& !block.compare(Block.RED_CARPET)
&& !block.compare(Block.WHITE_CARPET)
&& !block.compare(Block.TRIPWIRE);
}
}

View file

@ -1,6 +1,7 @@
package dev.celestialfox.spectrumsurvival.utils.classes;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minestom.server.entity.Player;
import java.util.Random;
@ -19,4 +20,26 @@ public class Randomized {
default -> Component.text(elIcon + player.getUsername() + " §cgot eliminated.");
};
}
public static NamedTextColor madeByColor() {
Random random = new Random();
int num = random.nextInt(4);
switch (num) {
case 0 -> {
return NamedTextColor.BLUE;
}
case 1 -> {
return NamedTextColor.GRAY;
}
case 2 -> {
return NamedTextColor.GOLD;
}
case 3 -> {
return NamedTextColor.GREEN;
}
default -> {
return NamedTextColor.RED;
}
}
}
}

View file

@ -1,25 +0,0 @@
package dev.celestialfox.spectrumsurvival.utils.classes;
import net.minestom.server.instance.block.BlockHandler;
import net.minestom.server.tag.Tag;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.List;
public final class SignHandler implements BlockHandler {
@Override
public @NotNull Collection<Tag<?>> getBlockEntityTags() {
return List.of(
Tag.Boolean("is_waxed"),
Tag.NBT("front_text"),
Tag.NBT("back_text")
);
}
@Override
public @NotNull NamespaceID getNamespaceId() {
return NamespaceID.from("minecraft:sign");
}
}

View file

@ -8,20 +8,17 @@ 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.sound.Sound;
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;
@ -35,7 +32,6 @@ 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 {
@ -113,7 +109,7 @@ public class MiscEvents {
if (item.material() == Material.SNOWBALL) {
Pos playerPosition = player.getPosition().add(0, 1.5, 0);
Vec direction = player.getPosition().direction().normalize().mul(30);
Vec direction = player.getPosition().direction().normalize().mul(25);
SnowballProjectile snowball = new SnowballProjectile(player);
snowball.setInstance(player.getInstance(), playerPosition);

View file

@ -5,6 +5,8 @@ import dev.celestialfox.spectrumsurvival.utils.classes.NPC;
import net.hollowcube.polar.PolarLoader;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.title.Title;
import net.kyori.adventure.title.TitlePart;
import net.minestom.server.MinecraftServer;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
@ -14,6 +16,11 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent;
import net.minestom.server.event.player.PlayerChatEvent;
import net.minestom.server.event.player.PlayerSpawnEvent;
import net.minestom.server.instance.*;
import net.minestom.server.item.ItemStack;
import net.minestom.server.item.Material;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -52,6 +59,9 @@ public class StartEvents {
Player player = event.getPlayer();
if (event.isFirstSpawn()) {
player.showTitle(Title.title(
Component.text("Welcome!", NamedTextColor.DARK_AQUA),
Component.text("Use §e/about game §rto read the rules", NamedTextColor.AQUA)));
player.sendMessage(
Component.text("Use §e/about game §rto read the rules.\n", NamedTextColor.GRAY)
.append(Component.text("Use §e/credits and /about us §rto know who made the game.\n", NamedTextColor.GRAY))