From b0414ae6ab06963f67f54fa9cc6cf0fbd0fab153 Mon Sep 17 00:00:00 2001
From: lars <larslukasneuhaus@gmx.de>
Date: Wed, 9 Apr 2025 00:08:01 +0200
Subject: [PATCH] added warning with corresponding setting

---
 .../metaGameplay/settings/Settings.java       |  1 +
 .../shrinkingBorder/ShrinkingBorder.java      | 12 ++++
 .../ShrinkingBorderListener.java              | 60 +++++++++++++++++++
 .../ShrinkingBorderSetting.java               | 51 ++++++++++++++++
 4 files changed, 124 insertions(+)
 create mode 100644 varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorderListener.java
 create mode 100644 varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorderSetting.java

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 bb31285..fc184ff 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
@@ -33,6 +33,7 @@ public class Settings extends Appliance {
         ChatMentions,
         DoubleDoors,
         KnockDoors,
+        BorderWarning
     }
 
     public static Settings instance() {
diff --git a/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorder.java b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorder.java
index b34abd4..33009a0 100644
--- a/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorder.java
+++ b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorder.java
@@ -4,9 +4,11 @@ import eu.mhsl.craftattack.core.Main;
 import eu.mhsl.craftattack.core.appliance.Appliance;
 import eu.mhsl.craftattack.core.appliance.ApplianceCommand;
 import eu.mhsl.craftattack.core.config.Configuration;
+import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings;
 import org.bukkit.Bukkit;
 import org.bukkit.World;
 import org.bukkit.WorldBorder;
+import org.bukkit.event.Listener;
 import org.jetbrains.annotations.NotNull;
 
 import java.time.LocalTime;
@@ -37,6 +39,11 @@ public class ShrinkingBorder extends Appliance {
         }
     }
 
+    @Override
+    public void onEnable() {
+        Settings.instance().declareSetting(ShrinkingBorderSetting.class);
+    }
+
     public ShrinkingBorder() {
         super("shrinkingBorder");
         this.shrinkPerDay = this.localConfig().getInt(this.shrinkPerDayKey, 10);
@@ -94,4 +101,9 @@ public class ShrinkingBorder extends Appliance {
     protected @NotNull List<ApplianceCommand<?>> commands() {
         return List.of(new ShrinkingBorderCommand());
     }
+
+    @Override
+    protected @NotNull List<Listener> listeners() {
+        return List.of(new ShrinkingBorderListener());
+    }
 }
diff --git a/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorderListener.java b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorderListener.java
new file mode 100644
index 0000000..cc78619
--- /dev/null
+++ b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorderListener.java
@@ -0,0 +1,60 @@
+package eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.shrinkingBorder;
+
+import eu.mhsl.craftattack.core.appliance.ApplianceListener;
+import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings;
+import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.datatypes.SelectSetting;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.TextColor;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.WorldBorder;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.player.PlayerMoveEvent;
+
+public class ShrinkingBorderListener extends ApplianceListener<ShrinkingBorder> {
+    @EventHandler
+    public void onPlayerMove(PlayerMoveEvent event) {
+        if(!event.hasChangedPosition()) return;
+        if(event.getTo().getWorld().getEnvironment().equals(World.Environment.THE_END)) return;
+        if(this.isSave(event.getTo())) return;
+        int remainingDays = this.daysUntilBorder(event.getTo());
+
+        SelectSetting.Options.Option setting = Settings.instance().getSetting(event.getPlayer(), Settings.Key.BorderWarning, SelectSetting.Options.Option.class);
+        int maxDaysShown = 0;
+        if(setting.is(ShrinkingBorderSetting.oneDay)) maxDaysShown = 1;
+        if(setting.is(ShrinkingBorderSetting.twoDays)) maxDaysShown = 2;
+        if(setting.is(ShrinkingBorderSetting.threeDays)) maxDaysShown = 3;
+
+        if(remainingDays > maxDaysShown) return;
+
+        String actionBarText;
+        if(remainingDays <= 0) {
+            actionBarText = "Du befindest dich in der Worldborder!";
+        } else {
+            actionBarText = String.format("In %d Tagen ist die Worldborder hier!", remainingDays);
+        }
+
+        event.getPlayer().sendActionBar(Component.text(
+            actionBarText,
+            TextColor.color(255, 0, 0)
+        ));
+    }
+
+    private int daysUntilBorder(Location playerLocation) {
+        WorldBorder worldBorder = playerLocation.getWorld().getWorldBorder();
+        Location relativeLocation = playerLocation.clone().subtract(worldBorder.getCenter());
+        double playerBorderDistanceX = worldBorder.getSize()/2 - Math.abs(relativeLocation.getX());
+        double playerBorderDistanceZ = worldBorder.getSize()/2 - Math.abs(relativeLocation.getZ());
+        int xSteps = (int) Math.ceil(playerBorderDistanceX / this.getAppliance().getOption(ShrinkingBorderCommand.Argument.SHRINK_PER_DAY));
+        int zSteps = (int) Math.ceil(playerBorderDistanceZ / this.getAppliance().getOption(ShrinkingBorderCommand.Argument.SHRINK_PER_DAY));
+        return Math.min(xSteps, zSteps);
+    }
+
+    private boolean isSave(Location playerLocation) {
+        WorldBorder worldBorder = playerLocation.getWorld().getWorldBorder();
+        Location relativeLocation = playerLocation.clone().subtract(worldBorder.getCenter());
+        if(relativeLocation.getX() > this.getAppliance().getOption(ShrinkingBorderCommand.Argument.MINIMUM_SIZE)) return false;
+        if(relativeLocation.getZ() > this.getAppliance().getOption(ShrinkingBorderCommand.Argument.MINIMUM_SIZE)) return false;
+        return true;
+    }
+}
diff --git a/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorderSetting.java b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorderSetting.java
new file mode 100644
index 0000000..0bbb2bf
--- /dev/null
+++ b/varo/src/main/java/eu/mhsl/craftattack/spawn/varo/appliances/metaGameplay/shrinkingBorder/ShrinkingBorderSetting.java
@@ -0,0 +1,51 @@
+package eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.shrinkingBorder;
+
+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.SelectSetting;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+
+import java.util.List;
+import java.util.Locale;
+
+public class ShrinkingBorderSetting extends SelectSetting implements CategorizedSetting {
+    private static final String namespace = ShrinkingBorderSetting.class.getSimpleName().toLowerCase(Locale.ROOT);
+    public static Options.Option noWarning = new Options.Option("Keine Warnung", new NamespacedKey(namespace, "disabled"));
+    public static Options.Option oneDay = new Options.Option("Ein Tag", new NamespacedKey(namespace, "one"));
+    public static Options.Option twoDays = new Options.Option("Zwei Tage", new NamespacedKey(namespace, "two"));
+    public static Options.Option threeDays = new Options.Option("Drei Tage", new NamespacedKey(namespace, "three"));
+
+    public ShrinkingBorderSetting() {
+        super(
+            Settings.Key.BorderWarning,
+            new Options(List.of(noWarning, oneDay, twoDays, threeDays))
+        );
+    }
+
+    @Override
+    public SettingCategory category() {
+        return SettingCategory.Gameplay;
+    }
+
+    @Override
+    protected String title() {
+        return "Warnung vor der Worldborder";
+    }
+
+    @Override
+    protected String description() {
+        return "Warnt vor der Worldborder";
+    }
+
+    @Override
+    protected Material icon() {
+        return Material.BARRIER;
+    }
+
+    @Override
+    protected Options.Option defaultValue() {
+        return oneDay;
+    }
+}