diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/Settings.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/Settings.java index aae45d2..dfec693 100644 --- a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/Settings.java +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/Settings.java @@ -38,7 +38,8 @@ public class Settings extends Appliance { BorderWarning, LocatorBar, InfoBars, - CoordinateDisplay + CoordinateDisplay, + Bloodmoon } public static Settings instance() { diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/Bloodmoon.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/Bloodmoon.java new file mode 100644 index 0000000..b4de47f --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/Bloodmoon.java @@ -0,0 +1,282 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon; + +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings; +import eu.mhsl.craftattack.spawn.core.Main; +import eu.mhsl.craftattack.spawn.core.appliance.Appliance; +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.commands.BloodmoonCommand; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonEntityDamageListener; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonMonsterDeathListener; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonPlayerJoinListener; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener.BloodmoonTimeListener; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.util.Ticks; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffectType; +import org.bukkit.scheduler.BukkitTask; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; +import java.util.concurrent.ThreadLocalRandom; + +@SuppressWarnings("FieldCanBeLocal") +public class Bloodmoon extends Appliance { + public final Map> affectedMobEffectMap = Map.ofEntries( + Map.entry(EntityType.ZOMBIE, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.WITHER, 7, 1) + )), + Map.entry(EntityType.SKELETON, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.SLOWNESS, 3.5, 1) + )), + Map.entry(EntityType.SPIDER, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.POISON, 4, 1), + new MobEffect.PotionMobEffect(PotionEffectType.NAUSEA, 6, 10) + )), + Map.entry(EntityType.CREEPER, Set.of( + new MobEffect.LightningMobEffect() + )), + Map.entry(EntityType.HUSK, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.WITHER, 7, 1) + )), + Map.entry(EntityType.STRAY, Set.of()), + Map.entry(EntityType.DROWNED, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.WITHER, 7, 1) + )), + Map.entry(EntityType.WITCH, Set.of()), + Map.entry(EntityType.ZOMBIE_VILLAGER, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.WITHER, 7, 1) + )), + Map.entry(EntityType.PHANTOM, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.LEVITATION, 1.5, 3) + )), + Map.entry(EntityType.ENDERMAN, Set.of( + new MobEffect.PotionMobEffect(PotionEffectType.SLOWNESS, 2.5, 2) + )) + ); + public final int expMultiplier = 3; + public final double mobDamageMultiplier = 2; + public final double mobHealthMultiplier = 2; + + private final ThreadLocalRandom random = ThreadLocalRandom.current(); + private boolean isActive = false; + private final BossBar bossBar = BossBar.bossBar( + Component.text("Blutmond", NamedTextColor.DARK_RED), + 1f, + BossBar.Color.RED, + BossBar.Overlay.NOTCHED_12, + Set.of(BossBar.Flag.CREATE_WORLD_FOG, BossBar.Flag.DARKEN_SCREEN) + ); + private final boolean hordesEnabled = true; + private final int hordeSpawnRateTicks = 40 * Ticks.TICKS_PER_SECOND; + private final int hordeSpawnRateVariationTicks = 40 * Ticks.TICKS_PER_SECOND; + private final int hordeMinPopulation = 3; + private final int hordeMaxPopulation = 10; + private final int hordeSpawnDistance = 10; + private final List hordeMobList = List.of( + EntityType.ZOMBIE, + EntityType.SKELETON, + EntityType.SPIDER + ); + private final Map hordeSpawnTasks = new WeakHashMap<>(); + private long lastBloodmoonStartTick = 0; + public final int ticksPerDay = 24000; + public final int bloodmoonLength = ticksPerDay/2; + public final int preStartMessageTicks = Ticks.TICKS_PER_SECOND * 50; + private final int bloodmoonFreeDaysAtStart = 3; + private final int bloodmoonStartTime = ticksPerDay/2; + private final int bloodmoonDayInterval = 30; + private final int minBonusDrops = 1; + private final int maxBonusDrops = 4; + private final Map bonusDropWeightMap = Map.of( + new ItemStack(Material.IRON_INGOT, 5), 10, + new ItemStack(Material.GOLD_INGOT, 2), 5, + new ItemStack(Material.DIAMOND, 1), 1, + new ItemStack(Material.IRON_BLOCK, 1), 5, + new ItemStack(Material.GOLD_BLOCK, 1), 2 + ); + + @Override + public void onEnable() { + Settings.instance().declareSetting(BloodmoonSetting.class); + } + + public boolean bloodmoonIsActive() { + return this.isActive; + } + + public void startBloodmoon(long startTick) { + this.lastBloodmoonStartTick = startTick; + this.isActive = true; + Bukkit.getOnlinePlayers().forEach(this::addPlayerToBossBar); + this.startHordeSpawning(this.getRandomHordeSpawnDelay()); + this.sendStartMessages(); + } + + public void stopBloodmoon() { + this.isActive = false; + Bukkit.getOnlinePlayers().forEach(player -> player.hideBossBar(this.bossBar)); + this.sendStopMessages(); + } + + public void updateBossBar() { + long tick = Bukkit.getWorlds().getFirst().getFullTime(); + long sinceStart = tick - this.lastBloodmoonStartTick; + float progress = 1f - ((float) sinceStart / this.bloodmoonLength); + if(progress < 0) progress = 1f; + this.bossBar.progress(progress); + } + + public boolean isStartTick(long tick) { + long day = tick / this.ticksPerDay; + if(day % this.bloodmoonDayInterval != 0 || day - this.bloodmoonFreeDaysAtStart <= 0) return false; + long time = tick - (day * this.ticksPerDay); + return time == this.bloodmoonStartTime; + } + + private int getRandomHordeSpawnDelay() { + return this.hordeSpawnRateTicks + this.random.nextInt(this.hordeSpawnRateVariationTicks); + } + + private void startHordeSpawning(int delay) { + Bukkit.getOnlinePlayers().forEach(player -> this.startHordeSpawning(delay, player)); + } + + private void startHordeSpawning(int delay, Player player) { + @Nullable BukkitTask task = this.hordeSpawnTasks.get(player); + if(task != null) task.cancel(); + BukkitTask newTask = Bukkit.getScheduler().runTaskLater( + Main.instance(), + () -> { + if(!this.bloodmoonIsActive()) return; + this.spawnRandomHorde(player); + this.startHordeSpawning(this.getRandomHordeSpawnDelay(), player); + }, + delay + ); + this.hordeSpawnTasks.put(player, newTask); + } + + public void addPlayerToBossBar(Player player) { + if(!this.getBloodmoonSetting(player)) return; + player.showBossBar(this.bossBar); + } + + public boolean isAffectedMob(Entity entity) { + return this.affectedMobEffectMap.containsKey(entity.getType()); + } + + public boolean getBloodmoonSetting(Player player) { + return Settings.instance().getSetting( + player, + Settings.Key.Bloodmoon, + Boolean.class + ); + } + + public void spawnRandomHorde(Player player) { + if(!this.hordesEnabled) return; + if(!player.getGameMode().equals(GameMode.SURVIVAL)) return; + + EntityType hordeEntityType = this.hordeMobList.get(this.random.nextInt(this.hordeMobList.size())); + int hordeSize = this.random.nextInt(this.hordeMinPopulation, this.hordeMaxPopulation + 1); + this.spawnHorde(player, hordeSize, hordeEntityType); + } + + public void sendWarningMessage(Player p) { + p.sendMessage(Component.text("Der Blutmond waltet in diesem Augenblick!", NamedTextColor.RED)); + } + + public void sendAnnouncementMessages() { + this.sendMessage(Component.text("Der Blutmond naht; morgen wird er den Himmel beherrschen", NamedTextColor.GOLD)); + } + + public void sendPreStartMessages() { + this.sendMessage(Component.text("Der Himmel ist heute Nacht ungewöhnlich düster", NamedTextColor.DARK_PURPLE)); + } + + private void spawnHorde(Player player, int size, EntityType type) { + for(int i = 0; i < size; i++) { + double spawnRadiant = this.random.nextDouble(0, 2*Math.PI); + Location mobSpawnLocation = player.getLocation().add( + Math.sin(spawnRadiant)*this.hordeSpawnDistance, + 0, + Math.cos(spawnRadiant)*this.hordeSpawnDistance + ); + mobSpawnLocation.setY(player.getWorld().getHighestBlockYAt(mobSpawnLocation) + 1); + player.getWorld().spawnEntity(mobSpawnLocation, type); + player.getWorld().strikeLightningEffect(mobSpawnLocation); + } + } + + public List getRandomBonusDrops() { + int itemCount = this.random.nextInt(this.minBonusDrops, this.maxBonusDrops + 1); + List result = new ArrayList<>(); + for(int i = 0; i < itemCount; i++) { + result.add(this.getRandomBonusDrop()); + } + return result; + } + + private @Nullable ItemStack getRandomBonusDrop() { + int totalWeight = this.bonusDropWeightMap.values().stream().mapToInt(value -> value).sum(); + int randomInt = this.random.nextInt(0, totalWeight + 1); + int cumulativeWeight = 0; + for(Map.Entry entry : this.bonusDropWeightMap.entrySet()) { + cumulativeWeight += entry.getValue(); + if(randomInt <= cumulativeWeight) return entry.getKey(); + } + return null; + } + + private void sendMessage(Component message) { + if(Bukkit.getOnlinePlayers().isEmpty()) return; + List onlinePlayers = Bukkit.getOnlinePlayers().stream() + .filter(this::getBloodmoonSetting) + .toList(); + onlinePlayers.forEach(player -> player.sendMessage(message)); + } + + private void sendStartMessages() { + this.sendMessage( + Component.empty() + .append(Component.text("Der Blutmond ist über uns", NamedTextColor.DARK_RED, TextDecoration.BOLD)) + .appendNewline() + .append(Component.text("Erfahrung vervielfacht sich und Mobs lassen reichere Beute fallen", NamedTextColor.RED)) + .appendNewline() + .append(Component.text("Mobs sind erstarkt und belegen dich mit finsteren Debuffs", NamedTextColor.RED)) + ); + } + + private void sendStopMessages() { + this.sendMessage(Component.text("Der Blutmond weicht...", NamedTextColor.GREEN, TextDecoration.BOLD)); + } + + @Override + protected @NotNull List listeners() { + return List.of( + new BloodmoonMonsterDeathListener(), + new BloodmoonPlayerJoinListener(), + new BloodmoonEntityDamageListener(), + new BloodmoonTimeListener() + ); + } + + @Override + protected @NotNull List> commands() { + return List.of( + new BloodmoonCommand() + ); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/BloodmoonSetting.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/BloodmoonSetting.java new file mode 100644 index 0000000..3782205 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/BloodmoonSetting.java @@ -0,0 +1,56 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon; + +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.CategorizedSetting; +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.SettingCategory; +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings; +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.datatypes.BoolSetting; +import eu.mhsl.craftattack.spawn.core.Main; +import eu.mhsl.craftattack.spawn.core.util.world.InteractSounds; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; + +public class BloodmoonSetting extends BoolSetting implements CategorizedSetting { + public BloodmoonSetting() { + super(Settings.Key.Bloodmoon); + } + + @Override + public SettingCategory category() { + return SettingCategory.Misc; // TODO: mehr als 8 bug fixen + } + + @Override + protected String title() { + return "Blutmond"; + } + + @Override + protected String description() { + return "Kämpfe während dem Blutmond gegen stärkere Monster mit besseren Drops. Kann nicht während dem Blutmond geändert werden!"; + } + + @Override + protected Material icon() { + return Material.SKELETON_SKULL; + } + + @Override + protected Boolean defaultValue() { + return true; + } + + // TODO: Settings deaktivierbar machen + + @Override + protected void change(Player player, ClickType clickType) { + if(Main.instance().getAppliance(Bloodmoon.class).bloodmoonIsActive()) { + InteractSounds.of(player).delete(); + player.sendMessage(Component.text("Während dem Blutmond kann diese Einstellung nicht geändert werden!", NamedTextColor.RED)); + return; + } + super.change(player, clickType); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/MobEffect.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/MobEffect.java new file mode 100644 index 0000000..c84ce63 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/MobEffect.java @@ -0,0 +1,29 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon; + +import net.kyori.adventure.util.Ticks; +import org.bukkit.entity.Player; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +public abstract class MobEffect { + public abstract void apply(Player p); + + public static class PotionMobEffect extends MobEffect { + private final PotionEffect effect; + public PotionMobEffect(PotionEffectType type, double seconds, int amplifier) { + this.effect = new PotionEffect(type, (int) (seconds * Ticks.TICKS_PER_SECOND), amplifier); + } + + @Override + public void apply(Player p) { + p.addPotionEffect(this.effect); + } + } + + public static class LightningMobEffect extends MobEffect { + @Override + public void apply(Player p) { + p.getWorld().strikeLightning(p.getLocation()); + } + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/commands/BloodmoonCommand.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/commands/BloodmoonCommand.java new file mode 100644 index 0000000..42a788c --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/commands/BloodmoonCommand.java @@ -0,0 +1,44 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.commands; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class BloodmoonCommand extends ApplianceCommand { + public BloodmoonCommand() { + super("bloodmoon"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + if(args.length == 0) { + sender.sendMessage("Bloodmoon is currently %s.".formatted(this.getAppliance().bloodmoonIsActive() ? "active" : "inactive")); + return; + } + + switch(args[0]) { + case "start": { + this.getAppliance().startBloodmoon(0L); + sender.sendMessage("Started bloodmoon."); + break; + } + case "stop": { + this.getAppliance().stopBloodmoon(); + sender.sendMessage("Stopped bloodmoon."); + break; + } + default: throw new Error("No such option: '%s' !".formatted(args[0])); + } + } + + @Override + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if(args.length == 1) return List.of("start", "stop"); + return null; + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonEntityDamageListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonEntityDamageListener.java new file mode 100644 index 0000000..8f2b4f5 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonEntityDamageListener.java @@ -0,0 +1,35 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon; +import org.bukkit.entity.Entity; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; + +public class BloodmoonEntityDamageListener extends ApplianceListener { + @EventHandler + public void onEntityDamage(EntityDamageByEntityEvent event) { + if(!this.getAppliance().bloodmoonIsActive()) return; + Entity damagerEntity = event.getDamager(); + if(damagerEntity instanceof Projectile projectile) { + if(!(projectile.getShooter() instanceof Entity shooter)) return; + damagerEntity = shooter; + } + if(!(damagerEntity instanceof LivingEntity damager && event.getEntity() instanceof LivingEntity receiver)) return; + if(event.getFinalDamage() == 0) return; + + if(this.getAppliance().isAffectedMob(damager) && receiver instanceof Player player) { + if(!this.getAppliance().getBloodmoonSetting(player)) return; + event.setDamage(event.getDamage() * this.getAppliance().mobDamageMultiplier); + this.getAppliance().affectedMobEffectMap.get(damager.getType()).forEach(mobEffect -> mobEffect.apply(player)); + return; + } + if(this.getAppliance().isAffectedMob(receiver) && damager instanceof Player player) { + if(!this.getAppliance().getBloodmoonSetting(player)) return; + event.setDamage(event.getDamage() / this.getAppliance().mobHealthMultiplier); + } + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonMonsterDeathListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonMonsterDeathListener.java new file mode 100644 index 0000000..5ec9bb3 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonMonsterDeathListener.java @@ -0,0 +1,23 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDeathEvent; + +public class BloodmoonMonsterDeathListener extends ApplianceListener { + @EventHandler + public void onMonsterDeath(EntityDeathEvent event) { + if(!this.getAppliance().bloodmoonIsActive()) return; + if(!(event.getDamageSource().getCausingEntity() instanceof Player player)) return; + if(!this.getAppliance().getBloodmoonSetting(player)) return; + LivingEntity entity = event.getEntity(); + if(!this.getAppliance().isAffectedMob(entity)) return; + + event.setDroppedExp(event.getDroppedExp() * this.getAppliance().expMultiplier); + event.getDrops().addAll(this.getAppliance().getRandomBonusDrops()); + entity.getWorld().strikeLightningEffect(entity.getLocation()); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonPlayerJoinListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonPlayerJoinListener.java new file mode 100644 index 0000000..30c575e --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonPlayerJoinListener.java @@ -0,0 +1,15 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +public class BloodmoonPlayerJoinListener extends ApplianceListener { + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if(!this.getAppliance().bloodmoonIsActive()) return; + this.getAppliance().addPlayerToBossBar(event.getPlayer()); + this.getAppliance().sendWarningMessage(event.getPlayer()); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonTimeListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonTimeListener.java new file mode 100644 index 0000000..6b9923e --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/bloodmoon/listener/BloodmoonTimeListener.java @@ -0,0 +1,31 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.listener; + +import com.destroystokyo.paper.event.server.ServerTickStartEvent; +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.bloodmoon.Bloodmoon; +import net.kyori.adventure.util.Ticks; +import org.bukkit.Bukkit; +import org.bukkit.event.EventHandler; + +public class BloodmoonTimeListener extends ApplianceListener { + @EventHandler + public void onServerTick(ServerTickStartEvent event) { + long currentTime = Bukkit.getWorlds().getFirst().getFullTime(); + if(this.getAppliance().isStartTick(currentTime)) { + this.getAppliance().startBloodmoon(currentTime); + return; + } + if(this.getAppliance().isStartTick(currentTime - this.getAppliance().bloodmoonLength)) { + this.getAppliance().stopBloodmoon(); + return; + } + if(currentTime % Ticks.TICKS_PER_SECOND == 0) this.getAppliance().updateBossBar(); + if(this.getAppliance().isStartTick(currentTime + this.getAppliance().ticksPerDay)) { + this.getAppliance().sendAnnouncementMessages(); + return; + } + if(this.getAppliance().isStartTick(currentTime + this.getAppliance().preStartMessageTicks)) { + this.getAppliance().sendPreStartMessages(); + } + } +}