added CoordinateDisplay with settings preferences, directional updates, and time display

This commit is contained in:
2025-10-03 17:06:20 +02:00
parent 040cae6cd1
commit 5ca4c70a41
8 changed files with 250 additions and 1 deletions

View File

@@ -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<CoordinateDisplay> {
@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());
}
}

View File

@@ -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<Player, CoordinateDisplaySetting.CoordinateDisplayConfiguration> 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<Component> 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<Listener> listeners() {
return List.of(
new CoordinateChangedListener()
);
}
}

View File

@@ -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<CoordinateDisplaySetting.CoordinateDisplayConfiguration> {
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;
}
}

View File

@@ -37,7 +37,8 @@ public class Settings extends Appliance {
KnockDoors, KnockDoors,
BorderWarning, BorderWarning,
LocatorBar, LocatorBar,
InfoBars InfoBars,
CoordinateDisplay
} }
public static Settings instance() { public static Settings instance() {

View File

@@ -1,5 +1,7 @@
package eu.mhsl.craftattack.spawn.core.util.text; package eu.mhsl.craftattack.spawn.core.util.text;
import org.bukkit.Location;
public class DataSizeConverter { public class DataSizeConverter {
public static String convertBytesPerSecond(long bytes) { public static String convertBytesPerSecond(long bytes) {
double kbits = bytes * 8.0 / 1000.0; 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); 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";
}
}
} }

View File

@@ -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);
}
}

View File

@@ -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<EndermanBlockGriefReducer> {
@EventHandler
public void onBlockPickup(EntityChangeBlockEvent event) {
if(!(event.getEntity() instanceof Enderman)) return;
if(ThreadLocalRandom.current().nextDouble() > 0.7) event.setCancelled(true);
}
}

View File

@@ -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<Listener> listeners() {
return List.of(
new EndermanBlockChangeListener()
);
}
}