diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateChangedListener.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateChangedListener.java new file mode 100644 index 0000000..a7976be --- /dev/null +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateChangedListener.java @@ -0,0 +1,21 @@ +package eu.mhsl.craftattack.spawn.common.appliances.gameplay.cordinateDisplay; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerMoveEvent; + +public class CoordinateChangedListener extends ApplianceListener { + @EventHandler + public void onJoin(PlayerJoinEvent event) { + this.getAppliance().updateEnabled(event.getPlayer()); + } + + @EventHandler + public void onMove(PlayerMoveEvent event) { + if(!this.getAppliance().isEnabled(event.getPlayer())) return; + boolean hasChangedOrientation = this.getAppliance().hasChangedDirection(event.getFrom(), event.getTo()); + if(!event.hasChangedBlock() && !hasChangedOrientation) return; + this.getAppliance().sendCoordinates(event.getPlayer()); + } +} diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateDisplay.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateDisplay.java new file mode 100644 index 0000000..30d4af8 --- /dev/null +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateDisplay.java @@ -0,0 +1,110 @@ +package eu.mhsl.craftattack.spawn.common.appliances.gameplay.cordinateDisplay; + +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.util.text.DataSizeConverter; +import eu.mhsl.craftattack.spawn.core.util.world.WorldUtils; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.util.Ticks; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class CoordinateDisplay extends Appliance { + Map enabledPlayers = new WeakHashMap<>(); + + @Override + public void onEnable() { + Settings.instance().declareSetting(CoordinateDisplaySetting.class); + Settings.instance().addChangeListener(CoordinateDisplaySetting.class, this::updateEnabled); + + Bukkit.getScheduler().runTaskTimerAsynchronously( + Main.instance(), + () -> this.sendCoordinates(), + Ticks.TICKS_PER_SECOND * 2, + Ticks.TICKS_PER_SECOND * 2 + ); + } + + public void updateEnabled(Player player) { + CoordinateDisplaySetting.CoordinateDisplayConfiguration configuration = Settings.instance().getSetting( + player, + Settings.Key.CoordinateDisplay, + CoordinateDisplaySetting.CoordinateDisplayConfiguration.class + ); + this.enabledPlayers.put(player, configuration); + } + + public boolean isEnabled(Player player) { + return Optional.ofNullable(this.enabledPlayers.get(player)) + .map(CoordinateDisplaySetting.CoordinateDisplayConfiguration::anyEnabled) + .orElse(false); + } + + private void sendCoordinates() { + this.enabledPlayers.entrySet().stream() + .filter(config -> config.getValue().anyEnabled()) + .map(Map.Entry::getKey) + .forEach(this::sendCoordinates); + } + + public void sendCoordinates(Player player) { + CoordinateDisplaySetting.CoordinateDisplayConfiguration config = this.enabledPlayers.get(player); + List components = new ArrayList<>(); + + if (config.coordinates()) { + components.add(Component.text("XYZ: ", NamedTextColor.GOLD)); + components.add(Component.text(String.format( + "%d %d %d", + player.getLocation().getBlockX(), + player.getLocation().getBlockY(), + player.getLocation().getBlockZ() + ))); + } + + if (config.direction()) { + if (!components.isEmpty()) { + components.add(Component.text(" | ", NamedTextColor.DARK_GRAY)); + } + components.add(Component.text("Richtung: ", NamedTextColor.GOLD)); + components.add(Component.text(DataSizeConverter.getCardinalDirection(player.getLocation()))); + } + + if (config.time()) { + if (!components.isEmpty()) { + components.add(Component.text(" | ", NamedTextColor.DARK_GRAY)); + } + components.add(Component.text("Zeit: ", NamedTextColor.GOLD)); + components.add(Component.text(WorldUtils.getGameTime(player.getWorld()))); + } + + if (!components.isEmpty()) { + Component actionBar = Component.empty(); + for (Component component : components) { + actionBar = actionBar.append(component); + } + player.sendActionBar(actionBar); + } + } + + + public boolean hasChangedDirection(Location previous, Location next) { + return !Objects.equals( + DataSizeConverter.getCardinalDirection(previous), + DataSizeConverter.getCardinalDirection(next) + ); + } + + @Override + protected @NotNull List listeners() { + return List.of( + new CoordinateChangedListener() + ); + } +} diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateDisplaySetting.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateDisplaySetting.java new file mode 100644 index 0000000..3e461f9 --- /dev/null +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/gameplay/cordinateDisplay/CoordinateDisplaySetting.java @@ -0,0 +1,46 @@ +package eu.mhsl.craftattack.spawn.common.appliances.gameplay.cordinateDisplay; + +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings; +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.datatypes.MultiBoolSetting; +import org.bukkit.Material; + +public class CoordinateDisplaySetting extends MultiBoolSetting { + public CoordinateDisplaySetting() { + super(Settings.Key.CoordinateDisplay); + } + + public record CoordinateDisplayConfiguration( + @DisplayName("Koordinaten") boolean coordinates, + @DisplayName("Richtung") boolean direction, + @DisplayName("Zeit") boolean time + ) { + public boolean anyEnabled() { + return this.coordinates || this.direction || this.time; + } + } + + @Override + protected String title() { + return "Koordinatenanzeige"; + } + + @Override + protected String description() { + return "Zeige deine aktuelle Position über der Hotbar an"; + } + + @Override + protected Material icon() { + return Material.RECOVERY_COMPASS; + } + + @Override + protected CoordinateDisplayConfiguration defaultValue() { + return new CoordinateDisplayConfiguration(false, false, false); + } + + @Override + public Class dataType() { + return CoordinateDisplayConfiguration.class; + } +} 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 bf80564..aae45d2 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 @@ -37,7 +37,8 @@ public class Settings extends Appliance { KnockDoors, BorderWarning, LocatorBar, - InfoBars + InfoBars, + CoordinateDisplay } public static Settings instance() { diff --git a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/text/DataSizeConverter.java b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/text/DataSizeConverter.java index 9399b2f..94e50f2 100644 --- a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/text/DataSizeConverter.java +++ b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/text/DataSizeConverter.java @@ -1,5 +1,7 @@ package eu.mhsl.craftattack.spawn.core.util.text; +import org.bukkit.Location; + public class DataSizeConverter { public static String convertBytesPerSecond(long bytes) { double kbits = bytes * 8.0 / 1000.0; @@ -52,4 +54,27 @@ public class DataSizeConverter { return String.format("%dd %dh %dm %ds", days, hours, minutes, seconds); } + + public static String getCardinalDirection(Location location) { + float yaw = location.getYaw(); + yaw = (yaw % 360 + 360) % 360; + + if (yaw >= 337.5 || yaw < 22.5) { + return "S"; + } else if (yaw >= 22.5 && yaw < 67.5) { + return "SW"; + } else if (yaw >= 67.5 && yaw < 112.5) { + return "W"; + } else if (yaw >= 112.5 && yaw < 157.5) { + return "NW"; + } else if (yaw >= 157.5 && yaw < 202.5) { + return "N"; + } else if (yaw >= 202.5 && yaw < 247.5) { + return "NO"; + } else if (yaw >= 247.5 && yaw < 292.5) { + return "O"; + } else { + return "SO"; + } + } } \ No newline at end of file diff --git a/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/world/WorldUtils.java b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/world/WorldUtils.java new file mode 100644 index 0000000..c7803c3 --- /dev/null +++ b/core/src/main/java/eu/mhsl/craftattack/spawn/core/util/world/WorldUtils.java @@ -0,0 +1,14 @@ +package eu.mhsl.craftattack.spawn.core.util.world; + +import org.bukkit.World; + +public class WorldUtils { + public static String getGameTime(World world) { + long timeOfDay = world.getTime() % 24000; + + int hours = (int) ((timeOfDay / 1000 + 6) % 24); + int minutes = (int) ((timeOfDay % 1000) * 60 / 1000); + + return String.format("%02d:%02d", hours, minutes); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tweaks/endermanBlockGriefReducer/EndermanBlockChangeListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tweaks/endermanBlockGriefReducer/EndermanBlockChangeListener.java new file mode 100644 index 0000000..aac7340 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tweaks/endermanBlockGriefReducer/EndermanBlockChangeListener.java @@ -0,0 +1,16 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.tweaks.endermanBlockGriefReducer; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import org.bukkit.entity.Enderman; +import org.bukkit.event.EventHandler; +import org.bukkit.event.entity.EntityChangeBlockEvent; + +import java.util.concurrent.ThreadLocalRandom; + +class EndermanBlockChangeListener extends ApplianceListener { + @EventHandler + public void onBlockPickup(EntityChangeBlockEvent event) { + if(!(event.getEntity() instanceof Enderman)) return; + if(ThreadLocalRandom.current().nextDouble() > 0.7) event.setCancelled(true); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tweaks/endermanBlockGriefReducer/EndermanBlockGriefReducer.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tweaks/endermanBlockGriefReducer/EndermanBlockGriefReducer.java new file mode 100644 index 0000000..a90f28f --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/tweaks/endermanBlockGriefReducer/EndermanBlockGriefReducer.java @@ -0,0 +1,16 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.tweaks.endermanBlockGriefReducer; + +import eu.mhsl.craftattack.spawn.core.appliance.Appliance; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class EndermanBlockGriefReducer extends Appliance { + @Override + protected @NotNull List listeners() { + return List.of( + new EndermanBlockChangeListener() + ); + } +}