From 62a42e561edd605aec1113e249a655826f2c2842 Mon Sep 17 00:00:00 2001 From: jannis Date: Tue, 6 Oct 2026 20:48:33 +0200 Subject: [PATCH 1/4] added New Year Firework --- .../newYearFirework/NewYearFirework.java | 43 +++++++++++++++++++ .../NewYearFireworkListener.java | 23 ++++++++++ 2 files changed, 66 insertions(+) create mode 100644 craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFirework.java create mode 100644 craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFireworkListener.java diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFirework.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFirework.java new file mode 100644 index 0000000..00298a7 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFirework.java @@ -0,0 +1,43 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.newYearFirework; + +import eu.mhsl.craftattack.spawn.core.appliance.Appliance; +import org.bukkit.Color; +import org.bukkit.FireworkEffect; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Firework; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.inventory.meta.FireworkMeta; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Locale; + +public class NewYearFirework extends Appliance { + private static final String namespace = NewYearFirework.class.getSimpleName().toLowerCase(Locale.ROOT); + public static NamespacedKey fireworkKey = new NamespacedKey(namespace, "newyear_firework".toLowerCase()); + + public void spawnFirework(Player player) { + for (int i = 0; i < 5; i++) { + Firework firework = player.getWorld().spawn(player.getLocation(), Firework.class); + firework.getPersistentDataContainer().set(fireworkKey, PersistentDataType.BOOLEAN, true); + FireworkMeta fireworkMeta = firework.getFireworkMeta(); + fireworkMeta.addEffect(FireworkEffect.builder() + .with(FireworkEffect.Type.BALL) + .withColor(Color.AQUA, Color.RED, Color.LIME, Color.ORANGE, Color.YELLOW) + .withFade(Color.FUCHSIA, Color.WHITE) + .trail(true) + .flicker(true) + .build() + ); + fireworkMeta.setPower((int) (i % 3 + 0.25)); + firework.setFireworkMeta(fireworkMeta); + } + } + + @Override + protected @NotNull List listeners() { + return List.of(new NewYearFireworkListener()); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFireworkListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFireworkListener.java new file mode 100644 index 0000000..120b8f9 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFireworkListener.java @@ -0,0 +1,23 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.newYearFirework; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import org.bukkit.entity.Firework; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.event.player.PlayerJoinEvent; + +import java.time.LocalDate; + +public class NewYearFireworkListener extends ApplianceListener { + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if(LocalDate.now().getDayOfYear() != 1) return; + this.getAppliance().spawnFirework(event.getPlayer()); + } + @EventHandler + public void onDamage(EntityDamageByEntityEvent event) { + if(!(event.getDamager() instanceof Firework firework)) return; + if(!firework.getPersistentDataContainer().has(NewYearFirework.fireworkKey)) return; + event.setCancelled(true); + } +} From a1ab06a80daae9e4c7ad425501dbef8cf3e3beb1 Mon Sep 17 00:00:00 2001 From: jannis Date: Tue, 13 Oct 2026 22:29:33 +0200 Subject: [PATCH 2/4] fixed game rules --- .../eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java | 4 ++++ .../appliances/tooling/projectStart/ProjectStart.java | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java index 336724c..b8b974d 100644 --- a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java +++ b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java @@ -31,6 +31,10 @@ public class IteratorUtil { rules.forEach((gameRule, value) -> IteratorUtil.worlds(world -> world.setGameRule(gameRule, value ^ inverse))); } + public static void setIntGameRules(Map, Integer> rules) { + rules.forEach((gameRule, value) -> IteratorUtil.worlds(world -> world.setGameRule(gameRule, value))); + } + public static void times(int times, Runnable callback) { IntStream.range(0, times).forEach(value -> callback.run()); } diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/projectStart/ProjectStart.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/projectStart/ProjectStart.java index 74c8477..1f4d0a5 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/projectStart/ProjectStart.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/projectStart/ProjectStart.java @@ -68,6 +68,12 @@ public class ProjectStart extends Appliance { entry(GameRules.FALL_DAMAGE, true), entry(GameRules.FIRE_DAMAGE, true) ); + private final Map, Integer> intGameRulesAfterStart = Map.of( + GameRules.FIRE_SPREAD_RADIUS_AROUND_PLAYER, -1 + ); + private final Map, Integer> intGameRulesBeforeStart = Map.of( + GameRules.FIRE_SPREAD_RADIUS_AROUND_PLAYER, 0 + ); public ProjectStart() { super("countdown"); @@ -121,6 +127,7 @@ public class ProjectStart extends Appliance { IteratorUtil.worlds(World::getWorldBorder, worldBorder -> worldBorder.setSize(worldBorder.getMaxSize())); IteratorUtil.worlds(world -> IteratorUtil.setGameRules(this.gameRulesAfterStart, false)); + IteratorUtil.worlds(world -> IteratorUtil.setIntGameRules(this.intGameRulesAfterStart)); Bukkit.getWorlds().getFirst().setFullTime(0); this.netherFireLocations.forEach(location -> Objects.requireNonNull(this.startWorld).getBlockAt(location).setType(Material.FIRE)); @@ -168,6 +175,7 @@ public class ProjectStart extends Appliance { }); IteratorUtil.worlds(world -> world, world -> IteratorUtil.setGameRules(this.gameRulesAfterStart, true)); + IteratorUtil.worlds(world -> world, world -> IteratorUtil.setIntGameRules(this.intGameRulesBeforeStart)); this.resetAdvancements(); this.blockCycle.reset(); From 46ee734bbc8d86b3d278df7f70fa0d9576baa585 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elias=20M=C3=BCller?= Date: Tue, 13 Oct 2026 22:41:14 +0200 Subject: [PATCH 3/4] Refactored game rule handling in `ProjectStart` to use a unified `GameRuleSetting` record, eliminating redundant methods and improving code clarity. --- .../spawn/core/util/IteratorUtil.java | 6 +-- .../tooling/projectStart/ProjectStart.java | 43 +++++++++---------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java index b8b974d..54478e2 100644 --- a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java +++ b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/IteratorUtil.java @@ -31,12 +31,8 @@ public class IteratorUtil { rules.forEach((gameRule, value) -> IteratorUtil.worlds(world -> world.setGameRule(gameRule, value ^ inverse))); } - public static void setIntGameRules(Map, Integer> rules) { - rules.forEach((gameRule, value) -> IteratorUtil.worlds(world -> world.setGameRule(gameRule, value))); - } - public static void times(int times, Runnable callback) { - IntStream.range(0, times).forEach(value -> callback.run()); + IntStream.range(0, times).forEach(_ -> callback.run()); } public static void iterateListInGlobal(int sectionStart, List list, BiConsumer callback) { diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/projectStart/ProjectStart.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/projectStart/ProjectStart.java index 1f4d0a5..2484b8d 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/projectStart/ProjectStart.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tooling/projectStart/ProjectStart.java @@ -26,10 +26,8 @@ import org.bukkit.inventory.ItemStack; 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_LAVA_CHICKEN; public class ProjectStart extends Appliance { @@ -57,22 +55,23 @@ public class ProjectStart extends Appliance { ) ); - private final Map, Boolean> gameRulesAfterStart = Map.ofEntries( - entry(GameRules.ADVANCE_TIME, true), - entry(GameRules.SPAWN_PHANTOMS, true), - entry(GameRules.RAIDS, true), - entry(GameRules.ENTITY_DROPS, true), - entry(GameRules.SPAWN_PATROLS, true), - entry(GameRules.SPAWN_WANDERING_TRADERS, true), - entry(GameRules.ADVANCE_WEATHER, true), - entry(GameRules.FALL_DAMAGE, true), - entry(GameRules.FIRE_DAMAGE, true) - ); - private final Map, Integer> intGameRulesAfterStart = Map.of( - GameRules.FIRE_SPREAD_RADIUS_AROUND_PLAYER, -1 - ); - private final Map, Integer> intGameRulesBeforeStart = Map.of( - GameRules.FIRE_SPREAD_RADIUS_AROUND_PLAYER, 0 + private record GameRuleSetting(GameRule rule, T before, T after) { + void apply(boolean afterStart) { + IteratorUtil.worlds(world -> world.setGameRule(this.rule, afterStart ? this.after : this.before)); + } + } + + private final List> gameRules = List.of( + new GameRuleSetting<>(GameRules.ADVANCE_TIME, false, true), + new GameRuleSetting<>(GameRules.SPAWN_PHANTOMS, false, true), + new GameRuleSetting<>(GameRules.RAIDS, false, true), + new GameRuleSetting<>(GameRules.ENTITY_DROPS, false, true), + new GameRuleSetting<>(GameRules.SPAWN_PATROLS, false, true), + new GameRuleSetting<>(GameRules.SPAWN_WANDERING_TRADERS, false, true), + new GameRuleSetting<>(GameRules.ADVANCE_WEATHER, false, true), + new GameRuleSetting<>(GameRules.FALL_DAMAGE, false, true), + new GameRuleSetting<>(GameRules.FIRE_DAMAGE, false, true), + new GameRuleSetting<>(GameRules.FIRE_SPREAD_RADIUS_AROUND_PLAYER, 0, -1) ); public ProjectStart() { @@ -81,7 +80,7 @@ public class ProjectStart extends Appliance { this.countdown.addCustomAnnouncement( new Countdown.CustomAnnouncements( counter -> counter == this.startMusicAt, - counter -> this.glassLocation + _ -> this.glassLocation .getWorld() .playSound(this.glassLocation, MUSIC_DISC_LAVA_CHICKEN, SoundCategory.RECORDS, 500f, 1f) ) @@ -126,8 +125,7 @@ public class ProjectStart extends Appliance { this.setEnabled(false); IteratorUtil.worlds(World::getWorldBorder, worldBorder -> worldBorder.setSize(worldBorder.getMaxSize())); - IteratorUtil.worlds(world -> IteratorUtil.setGameRules(this.gameRulesAfterStart, false)); - IteratorUtil.worlds(world -> IteratorUtil.setIntGameRules(this.intGameRulesAfterStart)); + this.gameRules.forEach(setting -> setting.apply(true)); Bukkit.getWorlds().getFirst().setFullTime(0); this.netherFireLocations.forEach(location -> Objects.requireNonNull(this.startWorld).getBlockAt(location).setType(Material.FIRE)); @@ -174,8 +172,7 @@ public class ProjectStart extends Appliance { worldBorder.setDamageAmount(0); }); - IteratorUtil.worlds(world -> world, world -> IteratorUtil.setGameRules(this.gameRulesAfterStart, true)); - IteratorUtil.worlds(world -> world, world -> IteratorUtil.setIntGameRules(this.intGameRulesBeforeStart)); + this.gameRules.forEach(setting -> setting.apply(false)); this.resetAdvancements(); this.blockCycle.reset(); From 252758797dbe5626b794d53eff2c2aa84e4802e3 Mon Sep 17 00:00:00 2001 From: jannis Date: Tue, 13 Oct 2026 22:52:42 +0200 Subject: [PATCH 4/4] fixed issues in NewYearFirework and QuarzRecipe --- .../gameplay/newYearFirework/NewYearFirework.java | 5 +++++ .../gameplay/newYearFirework/NewYearFireworkListener.java | 6 ++---- .../gameplay/quarzRecipe/QuarzRecipeListener.java | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFirework.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFirework.java index 00298a7..c02e1b4 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFirework.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFirework.java @@ -11,6 +11,7 @@ import org.bukkit.inventory.meta.FireworkMeta; import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; +import java.time.LocalDate; import java.util.List; import java.util.Locale; @@ -36,6 +37,10 @@ public class NewYearFirework extends Appliance { } } + public boolean shouldSpawnFirework() { + return LocalDate.now().getDayOfYear() == 1; + } + @Override protected @NotNull List listeners() { return List.of(new NewYearFireworkListener()); diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFireworkListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFireworkListener.java index 120b8f9..4a8f2ec 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFireworkListener.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/newYearFirework/NewYearFireworkListener.java @@ -6,12 +6,10 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.player.PlayerJoinEvent; -import java.time.LocalDate; - -public class NewYearFireworkListener extends ApplianceListener { +class NewYearFireworkListener extends ApplianceListener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { - if(LocalDate.now().getDayOfYear() != 1) return; + if(!this.getAppliance().shouldSpawnFirework()) return; this.getAppliance().spawnFirework(event.getPlayer()); } @EventHandler diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/quarzRecipe/QuarzRecipeListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/quarzRecipe/QuarzRecipeListener.java index a24181a..80d5c3b 100644 --- a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/quarzRecipe/QuarzRecipeListener.java +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/quarzRecipe/QuarzRecipeListener.java @@ -4,7 +4,7 @@ import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerJoinEvent; -public class QuarzRecipeListener extends ApplianceListener { +class QuarzRecipeListener extends ApplianceListener { @EventHandler public void onPlayerJoin(PlayerJoinEvent event) { this.getAppliance().unlock(event.getPlayer());