Updated Projectstart to use generic Countdown

This commit is contained in:
Elias Müller 2023-12-08 23:56:33 +01:00
parent bbaf4f394b
commit 848c3f02fe
9 changed files with 155 additions and 118 deletions

View File

@ -3,7 +3,7 @@ package eu.mhsl.craftattack.spawn;
import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliances.adminMarker.AdminMarker;
import eu.mhsl.craftattack.spawn.appliances.chatMessages.ChatMessages;
import eu.mhsl.craftattack.spawn.appliances.countdown.Countdown;
import eu.mhsl.craftattack.spawn.appliances.projectStart.ProjectStart;
import eu.mhsl.craftattack.spawn.appliances.debug.Debug;
import eu.mhsl.craftattack.spawn.appliances.event.Event;
import eu.mhsl.craftattack.spawn.appliances.help.Help;
@ -36,7 +36,7 @@ public final class Main extends JavaPlugin {
new AdminMarker(),
new WorldMuseum(),
new TitleClear(),
new Countdown(),
new ProjectStart(),
new Tablist(),
new ChatMessages(),
new Report(),

View File

@ -1,14 +1,14 @@
package eu.mhsl.craftattack.spawn.appliances.countdown;
package eu.mhsl.craftattack.spawn.appliances.projectStart;
import eu.mhsl.craftattack.spawn.Main;
import eu.mhsl.craftattack.spawn.appliance.Appliance;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.countdown.command.ProjectStartCancelCommand;
import eu.mhsl.craftattack.spawn.appliances.countdown.command.ProjectStartCommand;
import eu.mhsl.craftattack.spawn.appliances.countdown.command.ProjectStartResetCommand;
import eu.mhsl.craftattack.spawn.appliances.countdown.listener.PlayerInvincibleListener;
import eu.mhsl.craftattack.spawn.appliances.projectStart.command.ProjectStartCancelCommand;
import eu.mhsl.craftattack.spawn.appliances.projectStart.command.ProjectStartCommand;
import eu.mhsl.craftattack.spawn.appliances.projectStart.command.ProjectStartResetCommand;
import eu.mhsl.craftattack.spawn.appliances.projectStart.listener.PlayerInvincibleListener;
import eu.mhsl.craftattack.spawn.config.Configuration;
import eu.mhsl.craftattack.spawn.util.ComponentUtil;
import eu.mhsl.craftattack.spawn.util.Countdown;
import eu.mhsl.craftattack.spawn.util.IteratorUtil;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.Component;
@ -19,27 +19,28 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import static java.util.Map.entry;
import static org.bukkit.Sound.MUSIC_DISC_PIGSTEP;
public class Countdown extends Appliance {
public Countdown() {
super("countdown");
}
private int taskId = -1;
private boolean isRunning = false;
private final int countDownLength = localConfig().getInt("countdown");
private int countDown;
public class ProjectStart extends Appliance {
private final Countdown countdown = new Countdown(localConfig().getInt("countdown"), this::format, this::announce, this::projectStart);
private final int startMusicAt = 137;
private int cycleState = 0;
private World world = Bukkit.getWorld("world");
private List<Material> glassColors = List.of(Material.RED_STAINED_GLASS, Material.YELLOW_STAINED_GLASS, Material.GREEN_STAINED_GLASS, Material.BLUE_STAINED_GLASS);
private Material defaultGlassColor = Material.ORANGE_STAINED_GLASS;
private Location glassLocation = new Location(world, -224, 67, -368);
private final World world = Bukkit.getWorld("world");
private final List<Material> glassColors = List.of(
Material.RED_STAINED_GLASS,
Material.YELLOW_STAINED_GLASS,
Material.GREEN_STAINED_GLASS,
Material.BLUE_STAINED_GLASS
);
private final Material defaultGlassColor = Material.ORANGE_STAINED_GLASS;
private final Location glassLocation = new Location(world, -224, 67, -368);
//
private final Map<GameRule<Boolean>, Boolean> gamerulesAfterStart = Map.ofEntries(
private final Map<GameRule<Boolean>, Boolean> gameRulesAfterStart = Map.ofEntries(
entry(GameRule.DO_DAYLIGHT_CYCLE, true),
entry(GameRule.DO_INSOMNIA, true),
entry(GameRule.ANNOUNCE_ADVANCEMENTS, true),
@ -53,74 +54,49 @@ public class Countdown extends Appliance {
entry(GameRule.FIRE_DAMAGE, true)
);
public void startCountdown() {
if(!isEnabled()) return;
if(isRunning) return;
public ProjectStart() {
super("countdown");
this.countDown = countDownLength;
int startMusicAfter = 43;
this.isRunning = true;
this.taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(Main.instance(), () -> {
if(this.countDown <= 0) {
this.cancelCountdown();
this.projectStart();
return;
this.countdown.addCustomAnnouncement(
new Countdown.CustomAnnouncements(
counter -> counter == startMusicAt,
counter -> {
Objects.requireNonNull(world)
.playSound(glassLocation, MUSIC_DISC_PIGSTEP, SoundCategory.RECORDS, 500f, 1f);
}
)
);
}
if(countDown == countDownLength - startMusicAfter) {
world.playSound(glassLocation, org.bukkit.Sound.MUSIC_DISC_PIGSTEP, SoundCategory.RECORDS, 500f, 1f);
}
if(countDown > 60 && countDown % 60 == 0) {
sendStartMessage(countDown / 60, "Minuten");
}
if(countDown <= 60 && (countDown <= 10 || countDown % 10 == 0)) {
sendStartMessage(countDown, "Sekunden");
}
this.countDown--;
}, 20, 20);
}
private void sendStartMessage(int timeLeft, String unit) {
cycleBeacon();
Bukkit.getOnlinePlayers().forEach(player -> player.sendMessage(
Component.text()
private Component format(Countdown.AnnouncementData data) {
return Component.text()
.append(ComponentUtil.createRainbowText("CraftAttack", 10))
.append(Component.text(" startet in ", NamedTextColor.GOLD))
.append(Component.text(timeLeft, NamedTextColor.AQUA))
.append(Component.text(" " + unit + "!", NamedTextColor.GOLD))
));
.append(Component.text(data.count(), NamedTextColor.AQUA))
.append(Component.text(" " + data.unit() + "!", NamedTextColor.GOLD))
.build();
}
private void cycleBeacon() {
glassLocation.getBlock().setType(glassColors.get(cycleState));
cycleState++;
if(cycleState >= glassColors.size()) cycleState = 0;
private void announce(Component message) {
cycleBeacon();
IteratorUtil.onlinePlayers(player -> player.sendMessage(message));
}
public void startCountdown() {
if(!isEnabled()) return;
this.countdown.start();
}
public void cancelCountdown() {
if(taskId == -1) return;
Bukkit.getScheduler().cancelTask(this.taskId);
this.isRunning = false;
this.countdown.cancel();
this.restoreBeforeStart();
}
public boolean isEnabled() {
return localConfig().getBoolean("enabled");
}
public void setEnabled(boolean enabled) {
localConfig().set("enabled", enabled);
Configuration.saveChanges();
}
public void projectStart() {
setEnabled(false);
IteratorUtil.worlds(World::getWorldBorder, worldBorder -> worldBorder.setSize(worldBorder.getMaxSize()));
IteratorUtil.worlds(world -> setGamerules(gamerulesAfterStart, false));
IteratorUtil.worlds(world -> IteratorUtil.setGameRules(gameRulesAfterStart, false));
Bukkit.getOnlinePlayers().forEach(player -> {
player.setFoodLevel(20);
@ -155,17 +131,28 @@ public class Countdown extends Appliance {
worldBorder.setDamageAmount(0);
});
IteratorUtil.worlds(world -> world, world -> setGamerules(gamerulesAfterStart, true));
IteratorUtil.worlds(world -> world, world -> IteratorUtil.setGameRules(gameRulesAfterStart, true));
glassLocation.getBlock().setType(defaultGlassColor);
}
private void setGamerules(Map<GameRule<Boolean>, Boolean> rules, boolean inverse) {
rules.forEach((gameRule, value) -> IteratorUtil.worlds(world -> world.setGameRule(gameRule, value ^ inverse)));
private void cycleBeacon() {
glassLocation.getBlock().setType(glassColors.get(cycleState));
cycleState++;
if(cycleState >= glassColors.size()) cycleState = 0;
}
public boolean isRunning() {
return isRunning;
public boolean isEnabled() {
return localConfig().getBoolean("enabled");
}
public void setEnabled(boolean enabled) {
localConfig().set("enabled", enabled);
Configuration.saveChanges();
}
public Countdown getCountdown() {
return countdown;
}
@Override

View File

@ -1,21 +1,21 @@
package eu.mhsl.craftattack.spawn.appliances.countdown.command;
package eu.mhsl.craftattack.spawn.appliances.projectStart.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.countdown.Countdown;
import eu.mhsl.craftattack.spawn.appliances.projectStart.ProjectStart;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class ProjectStartCancelCommand extends ApplianceCommand<Countdown> {
public class ProjectStartCancelCommand extends ApplianceCommand<ProjectStart> {
public ProjectStartCancelCommand() {
super("projectStartCancel");
}
@Override
protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(getAppliance().isRunning()) {
if(getAppliance().getCountdown().isRunning()) {
getAppliance().cancelCountdown();
sender.sendMessage(Component.text("Countdown cancelled successfully!").color(NamedTextColor.GREEN));
} else {

View File

@ -1,14 +1,14 @@
package eu.mhsl.craftattack.spawn.appliances.countdown.command;
package eu.mhsl.craftattack.spawn.appliances.projectStart.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.countdown.Countdown;
import eu.mhsl.craftattack.spawn.appliances.projectStart.ProjectStart;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class ProjectStartCommand extends ApplianceCommand<Countdown> {
public class ProjectStartCommand extends ApplianceCommand<ProjectStart> {
public ProjectStartCommand() {
super("projectStart");
}
@ -20,7 +20,7 @@ public class ProjectStartCommand extends ApplianceCommand<Countdown> {
return;
}
if(getAppliance().isRunning()) {
if(getAppliance().getCountdown().isRunning()) {
sender.sendMessage(Component.text("Countdown already running!").color(NamedTextColor.RED));
return;
}

View File

@ -1,12 +1,12 @@
package eu.mhsl.craftattack.spawn.appliances.countdown.command;
package eu.mhsl.craftattack.spawn.appliances.projectStart.command;
import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.appliances.countdown.Countdown;
import eu.mhsl.craftattack.spawn.appliances.projectStart.ProjectStart;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class ProjectStartResetCommand extends ApplianceCommand<Countdown> {
public class ProjectStartResetCommand extends ApplianceCommand<ProjectStart> {
public ProjectStartResetCommand() {
super("projectStartReset");
}

View File

@ -1,14 +1,14 @@
package eu.mhsl.craftattack.spawn.appliances.countdown.listener;
package eu.mhsl.craftattack.spawn.appliances.projectStart.listener;
import eu.mhsl.craftattack.spawn.appliance.ApplianceListener;
import eu.mhsl.craftattack.spawn.appliances.countdown.Countdown;
import eu.mhsl.craftattack.spawn.appliances.projectStart.ProjectStart;
import io.papermc.paper.event.player.PrePlayerAttackEntityEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
public class PlayerInvincibleListener extends ApplianceListener<Countdown> {
public class PlayerInvincibleListener extends ApplianceListener<ProjectStart> {
@EventHandler
public void onDamage(EntityDamageEvent event) {
if(event.getEntity() instanceof Player) event.setCancelled(getAppliance().isEnabled());

View File

@ -14,10 +14,10 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
public class Restart extends Appliance {
private Countdown countdown;
private final Countdown countdown;
public Restart() {
this.countdown = new Countdown(60, this::announce, this::onDone);
this.countdown = new Countdown(60, this::format, this::announce, this::onDone);
}
public void scheduleRestart() {
@ -36,15 +36,16 @@ public class Restart extends Appliance {
}
}
private void announce(int secondsLeft) {
IteratorUtil.onlinePlayers(player -> {
player.sendMessage(
Component.text()
private Component format(Countdown.AnnouncementData data) {
return Component.text()
.append(Component.text("Serverneustart in ", NamedTextColor.DARK_RED))
.append(Component.text(secondsLeft, NamedTextColor.RED))
.append(Component.text(" Sekunden!", NamedTextColor.DARK_RED))
);
});
.append(Component.text(data.count(), NamedTextColor.RED))
.append(Component.text(" " + data.unit() + "!", NamedTextColor.DARK_RED))
.build();
}
private void announce(Component message) {
IteratorUtil.onlinePlayers(player -> player.sendMessage(message));
}
private void onDone() {

View File

@ -1,23 +1,55 @@
package eu.mhsl.craftattack.spawn.util;
import eu.mhsl.craftattack.spawn.Main;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
public class Countdown {
private final int countdownFrom;
private boolean running;
private int taskId;
private int current;
private final Consumer<Integer> announcement;
private final Consumer<Component> announcementConsumer;
private final Function<AnnouncementData, Component> announcementBuilder;
private Function<Integer, AnnouncementData> defaultAnnouncements;
private final List<CustomAnnouncements> customAnnouncements = new ArrayList<>();
private final Runnable onDone;
public Countdown(int countdownFrom, Consumer<Integer> announcement, Runnable onDone) {
public record AnnouncementData(int count, String unit) {}
public record CustomAnnouncements(Function<Integer, Boolean> test, Consumer<Integer> task) {}
public Countdown(int countdownFrom, Function<AnnouncementData, Component> announcementBuilder, Consumer<Component> announcementConsumer, Runnable onDone) {
this.countdownFrom = countdownFrom;
this.current = countdownFrom;
this.announcement = announcement;
this.announcementBuilder = announcementBuilder;
this.announcementConsumer = announcementConsumer;
this.onDone = onDone;
this.defaultAnnouncements = count -> {
if(current > 60 && current % 60 == 0) {
return new AnnouncementData(current / 60, "Minuten");
}
if(current <= 60 && (current <= 10 || current % 10 == 0)) {
return new AnnouncementData(current, "Sekunden");
}
return null;
};
}
public void addCustomAnnouncement(CustomAnnouncements announcement) {
this.customAnnouncements.add(announcement);
}
public void setDefaultAnnouncements(Function<Integer, AnnouncementData> defaultAnnouncement) {
this.defaultAnnouncements = defaultAnnouncement;
}
public void start() {
@ -34,14 +66,17 @@ public class Countdown {
this.current = countdownFrom;
}
public boolean isDone() {
return current <= 0;
private void tick() {
AnnouncementData defaultAnnouncementData = this.defaultAnnouncements.apply(current);
if(defaultAnnouncementData != null) {
this.announcementConsumer.accept(this.announcementBuilder.apply(defaultAnnouncementData));
}
private void tick() {
if(current <= 60 && (current <= 10 || current % 10 == 0)) {
this.announcement.accept(current);
}
customAnnouncements
.stream()
.filter(a -> a.test.apply(current))
.forEach(a -> a.task.accept(current));
this.current--;
if(isDone()) {
@ -49,4 +84,12 @@ public class Countdown {
this.cancel();
}
}
public boolean isDone() {
return current <= 0;
}
public boolean isRunning() {
return this.running;
}
}

View File

@ -1,9 +1,11 @@
package eu.mhsl.craftattack.spawn.util;
import org.bukkit.Bukkit;
import org.bukkit.GameRule;
import org.bukkit.World;
import org.bukkit.entity.Player;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
@ -19,4 +21,8 @@ public class IteratorUtil {
public static void onlinePlayers(Consumer<Player> player) {
Bukkit.getOnlinePlayers().forEach(player);
}
public static void setGameRules(Map<GameRule<Boolean>, Boolean> rules, boolean inverse) {
rules.forEach((gameRule, value) -> IteratorUtil.worlds(world -> world.setGameRule(gameRule, value ^ inverse)));
}
}