From 3c82544c4e00d58e0164e9da4b2177657e2799ef Mon Sep 17 00:00:00 2001 From: Martin Sulikowski Date: Mon, 6 Apr 2026 19:01:45 +0200 Subject: [PATCH] feat: Add WeatherCommand for flexible weather control and persistence * Introduced WeatherCommand to allow setting weather conditions with optional persistence. * Implemented WeatherService to manage weather changes and persistence logic. * Replaced SunCommand, RainCommand, and ThunderCommand logic with WeatherService integration. * Enhanced weather-related notices to include persistence messages. --- .../messages/ENTimeAndWeatherMessages.java | 4 + .../messages/PLTimeAndWeatherMessages.java | 4 + .../time/messages/TimeAndWeatherMessages.java | 2 + .../core/feature/weather/RainCommand.java | 12 +-- .../core/feature/weather/SunCommand.java | 13 +-- .../core/feature/weather/ThunderCommand.java | 12 +-- .../core/feature/weather/WeatherCommand.java | 94 +++++++++++++++++++ .../core/feature/weather/WeatherService.java | 51 ++++++++++ .../core/feature/weather/WeatherType.java | 7 ++ 9 files changed, 174 insertions(+), 25 deletions(-) create mode 100644 eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherCommand.java create mode 100644 eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherService.java create mode 100644 eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherType.java diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/ENTimeAndWeatherMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/ENTimeAndWeatherMessages.java index d40e6315a..f72a96d55 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/ENTimeAndWeatherMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/ENTimeAndWeatherMessages.java @@ -22,4 +22,8 @@ public class ENTimeAndWeatherMessages extends OkaeriConfig implements TimeAndWea Notice weatherSetSun = Notice.chat("Weather set to sun in the {WORLD}!"); Notice weatherSetThunder = Notice.chat("Weather set to thunder in the {WORLD}!"); + Notice weatherPersistenceEnabled = + Notice.chat("Locked {WEATHER} weather in the {WORLD} world."); + Notice weatherPersistenceDisabled = + Notice.chat("Natural weather cycle enabled again in the {WORLD} world."); } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/PLTimeAndWeatherMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/PLTimeAndWeatherMessages.java index b424abc69..2ecac437d 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/PLTimeAndWeatherMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/PLTimeAndWeatherMessages.java @@ -22,4 +22,8 @@ public class PLTimeAndWeatherMessages extends OkaeriConfig implements TimeAndWea Notice weatherSetSun = Notice.chat("Ustawiono słoneczną pogodę w świecie {WORLD}!"); Notice weatherSetThunder = Notice.chat("Ustawiono burze w świecie {WORLD}!"); + Notice weatherPersistenceEnabled = + Notice.chat("Zablokowano pogodę {WEATHER} w świecie {WORLD}."); + Notice weatherPersistenceDisabled = + Notice.chat("Przywrócono naturalny cykl pogody w świecie {WORLD}!"); } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/TimeAndWeatherMessages.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/TimeAndWeatherMessages.java index 70ca483b4..365d41eca 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/TimeAndWeatherMessages.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/time/messages/TimeAndWeatherMessages.java @@ -12,4 +12,6 @@ public interface TimeAndWeatherMessages { Notice weatherSetRain(); Notice weatherSetSun(); Notice weatherSetThunder(); + Notice weatherPersistenceEnabled(); + Notice weatherPersistenceDisabled(); } diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/RainCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/RainCommand.java index 288a7ac47..4ac9f5b8a 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/RainCommand.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/RainCommand.java @@ -1,7 +1,6 @@ package com.eternalcode.core.feature.weather; import com.eternalcode.annotations.scan.command.DescriptionDocs; -import com.eternalcode.commons.bukkit.scheduler.MinecraftScheduler; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.notice.NoticeService; import com.eternalcode.core.viewer.Viewer; @@ -18,12 +17,12 @@ class RainCommand { private final NoticeService noticeService; - private final MinecraftScheduler scheduler; + private final WeatherService weatherService; @Inject - RainCommand(NoticeService noticeService, MinecraftScheduler scheduler) { + RainCommand(NoticeService noticeService, WeatherService weatherService) { this.noticeService = noticeService; - this.scheduler = scheduler; + this.weatherService = weatherService; } @Execute @@ -39,10 +38,7 @@ void rainWorld(@Sender Viewer viewer, @Arg World world) { } private void setRain(Viewer viewer, World world) { - this.scheduler.run(() -> { - world.setStorm(true); - world.setThundering(false); - }); + this.weatherService.setWeather(world, WeatherType.RAIN, false); this.noticeService.create() .viewer(viewer) diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/SunCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/SunCommand.java index a49205367..9200554a5 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/SunCommand.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/SunCommand.java @@ -1,7 +1,6 @@ package com.eternalcode.core.feature.weather; import com.eternalcode.annotations.scan.command.DescriptionDocs; -import com.eternalcode.commons.bukkit.scheduler.MinecraftScheduler; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.notice.NoticeService; import com.eternalcode.core.viewer.Viewer; @@ -18,12 +17,12 @@ class SunCommand { private final NoticeService noticeService; - private final MinecraftScheduler scheduler; + private final WeatherService weatherService; @Inject - SunCommand(NoticeService noticeService, MinecraftScheduler scheduler) { + SunCommand(NoticeService noticeService, WeatherService weatherService) { this.noticeService = noticeService; - this.scheduler = scheduler; + this.weatherService = weatherService; } @Execute @@ -39,11 +38,7 @@ void sunWorld(@Sender Viewer viewer, @Arg World world) { } private void setSun(Viewer viewer, World world) { - this.scheduler.run(() -> { - world.setClearWeatherDuration(20 * 60 * 10); - world.setStorm(false); - world.setThundering(false); - }); + this.weatherService.setWeather(world, WeatherType.SUN, false); this.noticeService.create() .viewer(viewer) diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/ThunderCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/ThunderCommand.java index 31fc40c0c..fe5fdb448 100644 --- a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/ThunderCommand.java +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/ThunderCommand.java @@ -1,7 +1,6 @@ package com.eternalcode.core.feature.weather; import com.eternalcode.annotations.scan.command.DescriptionDocs; -import com.eternalcode.commons.bukkit.scheduler.MinecraftScheduler; import com.eternalcode.core.injector.annotations.Inject; import com.eternalcode.core.notice.NoticeService; import com.eternalcode.core.viewer.Viewer; @@ -18,12 +17,12 @@ class ThunderCommand { private final NoticeService noticeService; - private final MinecraftScheduler scheduler; + private final WeatherService weatherService; @Inject - ThunderCommand(NoticeService noticeService, MinecraftScheduler scheduler) { + ThunderCommand(NoticeService noticeService, WeatherService weatherService) { this.noticeService = noticeService; - this.scheduler = scheduler; + this.weatherService = weatherService; } @Execute @@ -39,10 +38,7 @@ void thunderWorld(@Sender Viewer viewer, @Arg World world) { } private void setThunder(Viewer viewer, World world) { - this.scheduler.run(() -> { - world.setStorm(true); - world.setThundering(true); - }); + this.weatherService.setWeather(world, WeatherType.THUNDER, false); this.noticeService.create() .viewer(viewer) diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherCommand.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherCommand.java new file mode 100644 index 000000000..032010979 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherCommand.java @@ -0,0 +1,94 @@ +package com.eternalcode.core.feature.weather; + +import com.eternalcode.annotations.scan.command.DescriptionDocs; +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.notice.NoticeService; +import com.eternalcode.core.viewer.Viewer; +import dev.rollczi.litecommands.annotations.argument.Arg; +import dev.rollczi.litecommands.annotations.command.Command; +import dev.rollczi.litecommands.annotations.context.Context; +import dev.rollczi.litecommands.annotations.context.Sender; +import dev.rollczi.litecommands.annotations.execute.Execute; +import dev.rollczi.litecommands.annotations.flag.Flag; +import dev.rollczi.litecommands.annotations.permission.Permission; +import java.util.Locale; +import org.bukkit.World; + +@Command(name = "weather") +@Permission("eternalcore.weather") +class WeatherCommand { + + private final NoticeService noticeService; + private final WeatherService weatherService; + + @Inject + WeatherCommand(NoticeService noticeService, WeatherService weatherService) { + this.noticeService = noticeService; + this.weatherService = weatherService; + } + + @Execute + @DescriptionDocs(description = "Sets weather in current world", arguments = " [-p]") + void execute(@Sender Viewer viewer, @Context World world, @Arg WeatherType weatherType, @Flag("-p") boolean persistent) { + this.setWeather(viewer, world, weatherType, persistent); + } + + @Execute + @DescriptionDocs(description = "Sets weather in specified world", arguments = " [-p]") + void execute( + @Sender Viewer viewer, + @Arg WeatherType weatherType, + @Arg World world, + @Flag("-p") boolean persistent + ) { + this.setWeather(viewer, world, weatherType, persistent); + } + + @Execute(name = "clear") + @DescriptionDocs(description = "Enables natural weather cycle in current world") + void clearCurrentWorld(@Sender Viewer viewer, @Context World world) { + this.clearWeather(viewer, world); + } + + @Execute(name = "clear") + @DescriptionDocs(description = "Enables natural weather cycle in specified world", arguments = "") + void clearSelectedWorld(@Sender Viewer viewer, @Arg World world) { + this.clearWeather(viewer, world); + } + + private void setWeather(Viewer viewer, World world, WeatherType weatherType, boolean persistent) { + this.weatherService.setWeather(world, weatherType, persistent); + + this.noticeService.create() + .viewer(viewer) + .placeholder("{WORLD}", world.getName()) + .notice(translation -> switch (weatherType) { + case SUN -> translation.timeAndWeather().weatherSetSun(); + case RAIN -> translation.timeAndWeather().weatherSetRain(); + case THUNDER -> translation.timeAndWeather().weatherSetThunder(); + }) + .send(); + + if (!persistent) { + return; + } + + this.noticeService.create() + .viewer(viewer) + .placeholder("{WORLD}", world.getName()) + .placeholder("{WEATHER}", weatherType.name().toLowerCase(Locale.ROOT)) + .notice(translation -> translation.timeAndWeather().weatherPersistenceEnabled()) + .send(); + } + + private void clearWeather(Viewer viewer, World world) { + this.weatherService.clearPersistentWeather(world); + + this.noticeService.create() + .viewer(viewer) + .placeholder("{WORLD}", world.getName()) + .notice(translation -> translation.timeAndWeather().weatherPersistenceDisabled()) + .send(); + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherService.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherService.java new file mode 100644 index 000000000..3ca8f486d --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherService.java @@ -0,0 +1,51 @@ +package com.eternalcode.core.feature.weather; + +import com.eternalcode.commons.bukkit.scheduler.MinecraftScheduler; +import com.eternalcode.core.injector.annotations.Inject; +import com.eternalcode.core.injector.annotations.component.Service; +import org.bukkit.GameRule; +import org.bukkit.World; + +@Service +class WeatherService { + + private static final int DEFAULT_CLEAR_WEATHER_DURATION = 20 * 60 * 10; + + private final MinecraftScheduler scheduler; + + @Inject + WeatherService(MinecraftScheduler scheduler) { + this.scheduler = scheduler; + } + + void setWeather(World world, WeatherType weatherType, boolean persistent) { + this.scheduler.run(() -> { + this.applyWeather(world, weatherType); + world.setGameRule(GameRule.DO_WEATHER_CYCLE, !persistent); + }); + } + + void clearPersistentWeather(World world) { + this.scheduler.run(() -> world.setGameRule(GameRule.DO_WEATHER_CYCLE, true)); + } + + private void applyWeather(World world, WeatherType weatherType) { + switch (weatherType) { + case SUN -> { + world.setClearWeatherDuration(DEFAULT_CLEAR_WEATHER_DURATION); + world.setStorm(false); + world.setThundering(false); + } + case RAIN -> { + world.setStorm(true); + world.setThundering(false); + } + case THUNDER -> { + world.setStorm(true); + world.setThundering(true); + } + default -> throw new IllegalStateException("Unsupported weather type: " + weatherType); + } + } + +} diff --git a/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherType.java b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherType.java new file mode 100644 index 000000000..5cad81871 --- /dev/null +++ b/eternalcore-core/src/main/java/com/eternalcode/core/feature/weather/WeatherType.java @@ -0,0 +1,7 @@ +package com.eternalcode.core.feature.weather; + +public enum WeatherType { + SUN, + RAIN, + THUNDER +}