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 6bc857f..653416d 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 @@ -17,6 +17,7 @@ import org.jetbrains.annotations.NotNull; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; import java.util.stream.Collectors; public class Settings extends Appliance { @@ -34,7 +35,8 @@ public class Settings extends Appliance { ChatMentions, DoubleDoors, KnockDoors, - BorderWarning + BorderWarning, + LocatorBarConfig } public static Settings instance() { @@ -58,6 +60,16 @@ public class Settings extends Appliance { private final WeakHashMap openSettingsInventories = new WeakHashMap<>(); private final WeakHashMap>> settingsCache = new WeakHashMap<>(); + protected final Map>, Consumer> changeListeners = new WeakHashMap<>(); + + public > void addChangeListener(Class setting, Consumer listener) { + this.changeListeners.merge(setting, listener, Consumer::andThen); + } + + public > void invokeChangeListener(Player player, Class setting) { + Optional.ofNullable(this.changeListeners.get(setting)) + .ifPresent(listener -> listener.accept(player)); + } private List> getSettings(Player player) { if(this.settingsCache.containsKey(player)) return this.settingsCache.get(player); diff --git a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/datatypes/Setting.java b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/datatypes/Setting.java index 296a46b..31cd596 100644 --- a/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/datatypes/Setting.java +++ b/common/src/main/java/eu/mhsl/craftattack/spawn/common/appliances/metaGameplay/settings/datatypes/Setting.java @@ -34,7 +34,24 @@ public abstract class Setting { } public void initializeFromPlayer(Player p) { - this.fromStorage(p.getPersistentDataContainer()); + PersistentDataContainer dataContainer = p.getPersistentDataContainer(); + try { + this.fromStorage(dataContainer); + } catch(IllegalArgumentException e) { + Main.logger().warning(String.format( + "Could not load state of setting %s from player %s: '%s'\n Did the datatype of the setting change?", + this.getNamespacedKey(), + e.getMessage(), + p.getName() + )); + dataContainer.remove(this.getNamespacedKey()); + this.fromStorage(dataContainer); + Main.logger().info(String.format( + "Restoring defaults of setting %s of player %s", + this.getNamespacedKey(), + p.getName() + )); + } } public void triggerChange(Player p, ClickType clickType) { @@ -42,6 +59,7 @@ public abstract class Setting { this.change(p, clickType); InteractSounds.of(p).click(); this.toStorage(p.getPersistentDataContainer(), this.state()); + Settings.instance().invokeChangeListener(p, this.getClass()); } public ItemStack buildItem() { diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBar.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBar.java new file mode 100644 index 0000000..bc0d1f8 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBar.java @@ -0,0 +1,50 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.locatorBar; + +import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.settings.Settings; +import eu.mhsl.craftattack.spawn.core.appliance.Appliance; +import org.bukkit.attribute.Attribute; +import org.bukkit.attribute.AttributeInstance; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Objects; + +public class LocatorBar extends Appliance { + private enum Distance { + MAX(6.0e7), + ZERO(0.0); + + final double distance; + Distance(double distance) { + this.distance = distance; + } + } + + @Override + public void onEnable() { + Settings.instance().declareSetting(LocatorBarSettings.class); + Settings.instance().addChangeListener(LocatorBarSettings.class, this::updateLocatorBar); + } + + public void updateLocatorBar(Player player) { + boolean enabled = Settings.instance().getSetting(player, Settings.Key.LocatorBarConfig, Boolean.class); + + AttributeInstance receive = player.getAttribute(Attribute.WAYPOINT_RECEIVE_RANGE); + AttributeInstance transmit = player.getAttribute(Attribute.WAYPOINT_TRANSMIT_RANGE); + + Objects.requireNonNull(receive); + Objects.requireNonNull(transmit); + + receive.setBaseValue(enabled ? Distance.MAX.distance : Distance.ZERO.distance); + transmit.setBaseValue(enabled ? Distance.MAX.distance : Distance.ZERO.distance); + } + + @Override + protected @NotNull List listeners() { + return List.of( + new LocatorBarUpdateListener() + ); + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBarSettings.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBarSettings.java new file mode 100644 index 0000000..bf54025 --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBarSettings.java @@ -0,0 +1,38 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.locatorBar; + +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.BoolSetting; +import org.bukkit.Material; + +public class LocatorBarSettings extends BoolSetting implements CategorizedSetting { + @Override + public SettingCategory category() { + return SettingCategory.Gameplay; + } + + public LocatorBarSettings() { + super(Settings.Key.LocatorBarConfig); + } + + @Override + protected String title() { + return "Ortungsleiste / Locator Bar"; + } + + @Override + protected String description() { + return "Konfiguriere, ob andere Spieler deine Position und du die Position anderer sehen möchtest"; + } + + @Override + protected Material icon() { + return Material.COMPASS; + } + + @Override + protected Boolean defaultValue() { + return true; + } +} diff --git a/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBarUpdateListener.java b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBarUpdateListener.java new file mode 100644 index 0000000..6feb17b --- /dev/null +++ b/craftattack/src/main/java/eu/mhsl/craftattack/spawn/craftattack/appliances/gameplay/locatorBar/LocatorBarUpdateListener.java @@ -0,0 +1,12 @@ +package eu.mhsl.craftattack.spawn.craftattack.appliances.gameplay.locatorBar; + +import eu.mhsl.craftattack.spawn.core.appliance.ApplianceListener; +import org.bukkit.event.EventHandler; +import org.bukkit.event.player.PlayerJoinEvent; + +class LocatorBarUpdateListener extends ApplianceListener { + @EventHandler + public void onJoin(PlayerJoinEvent event) { + this.getAppliance().updateLocatorBar(event.getPlayer()); + } +}