upload progress
This commit is contained in:
parent
c80f2c2eff
commit
93c7cb4a31
@ -154,7 +154,7 @@ public final class VillagerOptimizer extends JavaPlugin {
|
|||||||
File langDirectory = new File(getDataFolder() + File.separator + "lang");
|
File langDirectory = new File(getDataFolder() + File.separator + "lang");
|
||||||
Files.createDirectories(langDirectory.toPath());
|
Files.createDirectories(langDirectory.toPath());
|
||||||
for (String fileName : getDefaultLanguageFiles()) {
|
for (String fileName : getDefaultLanguageFiles()) {
|
||||||
final String localeString = fileName.substring(fileName.lastIndexOf(File.separator) + 1, fileName.lastIndexOf('.'));
|
final String localeString = fileName.substring(fileName.lastIndexOf('/') + 1, fileName.lastIndexOf('.'));
|
||||||
if (startup) logger.info(
|
if (startup) logger.info(
|
||||||
Component.text("│ ").style(STYLE)
|
Component.text("│ ").style(STYLE)
|
||||||
.append(Component.text(" "+localeString).color(NamedTextColor.WHITE).decorate(TextDecoration.BOLD))
|
.append(Component.text(" "+localeString).color(NamedTextColor.WHITE).decorate(TextDecoration.BOLD))
|
||||||
@ -190,7 +190,7 @@ public final class VillagerOptimizer extends JavaPlugin {
|
|||||||
try (final JarFile pluginJarFile = new JarFile(this.getFile())) {
|
try (final JarFile pluginJarFile = new JarFile(this.getFile())) {
|
||||||
return pluginJarFile.stream()
|
return pluginJarFile.stream()
|
||||||
.map(ZipEntry::getName)
|
.map(ZipEntry::getName)
|
||||||
.filter(name -> name.startsWith("lang" + File.separator) && name.endsWith(".yml"))
|
.filter(name -> name.startsWith("lang/") && name.endsWith(".yml"))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
} catch (IOException ioException) {
|
} catch (IOException ioException) {
|
||||||
logger.error("Failed getting default lang files!", ioException);
|
logger.error("Failed getting default lang files!", ioException);
|
||||||
|
@ -2,9 +2,8 @@ package me.xginko.villageroptimizer;
|
|||||||
|
|
||||||
import me.xginko.villageroptimizer.enums.Keyring;
|
import me.xginko.villageroptimizer.enums.Keyring;
|
||||||
import me.xginko.villageroptimizer.enums.OptimizationType;
|
import me.xginko.villageroptimizer.enums.OptimizationType;
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Villager;
|
import org.bukkit.entity.Villager;
|
||||||
import org.bukkit.entity.memory.MemoryKey;
|
import org.bukkit.entity.memory.MemoryKey;
|
||||||
import org.bukkit.inventory.MerchantRecipe;
|
import org.bukkit.inventory.MerchantRecipe;
|
||||||
@ -262,6 +261,14 @@ public final class WrappedVillager {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the villager can loose his acquired profession by having their workstation destroyed.
|
||||||
|
*/
|
||||||
|
public boolean canLooseProfession() {
|
||||||
|
// A villager with a level of 1 and no trading experience is liable to lose its profession.
|
||||||
|
return villager.getVillagerLevel() <= 1 && villager.getVillagerExperience() <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param cooldown_millis The configured cooldown in milliseconds you want to check against.
|
* @param cooldown_millis The configured cooldown in milliseconds you want to check against.
|
||||||
* @return Whether the villager can be leveled up or not with the checked milliseconds
|
* @return Whether the villager can be leveled up or not with the checked milliseconds
|
||||||
@ -304,28 +311,23 @@ public final class WrappedVillager {
|
|||||||
return cooldown_millis;
|
return cooldown_millis;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void memorizeName(final Component customName) {
|
public void sayNo() {
|
||||||
dataContainer.set(Keyring.VillagerOptimizer.LAST_OPTIMIZE_NAME.getKey(), PersistentDataType.STRING, MiniMessage.miniMessage().serialize(customName));
|
try {
|
||||||
|
villager.shakeHead();
|
||||||
|
} catch (NoSuchMethodError e) {
|
||||||
|
villager.getWorld().playSound(villager.getLocation(), Sound.ENTITY_VILLAGER_NO, 1.0F, 1.0F);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Component getMemorizedName() {
|
|
||||||
if (dataContainer.has(Keyring.VillagerOptimizer.LAST_OPTIMIZE_NAME.getKey(), PersistentDataType.STRING))
|
|
||||||
return MiniMessage.miniMessage().deserialize(dataContainer.get(Keyring.VillagerOptimizer.LAST_OPTIMIZE_NAME.getKey(), PersistentDataType.STRING));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void forgetName() {
|
|
||||||
dataContainer.remove(Keyring.VillagerOptimizer.LAST_OPTIMIZE_NAME.getKey());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class CachedJobSite {
|
private static class CachedJobSite {
|
||||||
|
private final @NotNull Villager villager;
|
||||||
private @Nullable Location jobSite;
|
private @Nullable Location jobSite;
|
||||||
private long lastRefresh;
|
private long lastRefresh;
|
||||||
private CachedJobSite(Villager villager) {
|
private CachedJobSite(@NotNull Villager villager) {
|
||||||
this.jobSite = villager.getMemory(MemoryKey.JOB_SITE);
|
this.villager = villager;
|
||||||
this.lastRefresh = System.currentTimeMillis();
|
this.jobSite = getJobSite();
|
||||||
}
|
}
|
||||||
private @Nullable Location getJobSite(Villager villager) {
|
private @Nullable Location getJobSite() {
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
if (now - lastRefresh > 1000L) {
|
if (now - lastRefresh > 1000L) {
|
||||||
this.jobSite = villager.getMemory(MemoryKey.JOB_SITE);
|
this.jobSite = villager.getMemory(MemoryKey.JOB_SITE);
|
||||||
@ -338,11 +340,6 @@ public final class WrappedVillager {
|
|||||||
public @Nullable Location getJobSite() {
|
public @Nullable Location getJobSite() {
|
||||||
if (cachedJobSite == null)
|
if (cachedJobSite == null)
|
||||||
cachedJobSite = new CachedJobSite(villager);
|
cachedJobSite = new CachedJobSite(villager);
|
||||||
return cachedJobSite.getJobSite(villager);
|
return cachedJobSite.getJobSite();
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canLooseProfession() {
|
|
||||||
// A villager with a level of 1 and no trading experience is liable to lose its profession.
|
|
||||||
return villager.getVillagerLevel() <= 1 && villager.getVillagerExperience() <= 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -32,7 +32,7 @@ public class LanguageCache {
|
|||||||
VillagerOptimizer.getLog().error("Failed to create lang directory.");
|
VillagerOptimizer.getLog().error("Failed to create lang directory.");
|
||||||
// Check if the file already exists and save the one from the plugin's resources folder if it does not
|
// Check if the file already exists and save the one from the plugin's resources folder if it does not
|
||||||
if (!langYML.exists())
|
if (!langYML.exists())
|
||||||
plugin.saveResource("lang" + File.separator + locale + ".yml", false);
|
plugin.saveResource("lang/" + locale + ".yml", false);
|
||||||
// Finally, load the lang file with configmaster
|
// Finally, load the lang file with configmaster
|
||||||
this.lang = ConfigFile.loadConfig(langYML);
|
this.lang = ConfigFile.loadConfig(langYML);
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ public interface VillagerOptimizerModule {
|
|||||||
modules.add(new FixOptimisationAfterCure());
|
modules.add(new FixOptimisationAfterCure());
|
||||||
modules.add(new RestockOptimizedTrades());
|
modules.add(new RestockOptimizedTrades());
|
||||||
modules.add(new LevelOptimizedProfession());
|
modules.add(new LevelOptimizedProfession());
|
||||||
modules.add(new RenameOptimizedVillagers());
|
modules.add(new VisuallyHighlightOptimized());
|
||||||
modules.add(new MakeVillagersSpawnAdult());
|
modules.add(new MakeVillagersSpawnAdult());
|
||||||
modules.add(new PreventUnoptimizedTrading());
|
modules.add(new PreventUnoptimizedTrading());
|
||||||
modules.add(new PreventOptimizedTargeting());
|
modules.add(new PreventOptimizedTargeting());
|
||||||
|
@ -62,11 +62,12 @@ public class EnableLeashingVillagers implements VillagerOptimizerModule, Listene
|
|||||||
final ItemStack handItem = player.getInventory().getItem(event.getHand());
|
final ItemStack handItem = player.getInventory().getItem(event.getHand());
|
||||||
if (handItem == null || !handItem.getType().equals(Material.LEAD)) return;
|
if (handItem == null || !handItem.getType().equals(Material.LEAD)) return;
|
||||||
|
|
||||||
Villager villager = (Villager) event.getRightClicked();
|
final Villager villager = (Villager) event.getRightClicked();
|
||||||
if (villager.isLeashed()) return;
|
if (villager.isLeashed()) return;
|
||||||
event.setCancelled(true); // Cancel the event, so we don't interact with the villager
|
|
||||||
if (only_optimized && !villagerCache.getOrAdd(villager).isOptimized()) return;
|
if (only_optimized && !villagerCache.getOrAdd(villager).isOptimized()) return;
|
||||||
|
|
||||||
|
event.setCancelled(true); // Cancel the event, so we don't interact with the villager
|
||||||
|
|
||||||
// Call event for compatibility with other plugins, constructing non deprecated if available
|
// Call event for compatibility with other plugins, constructing non deprecated if available
|
||||||
PlayerLeashEntityEvent leashEvent;
|
PlayerLeashEntityEvent leashEvent;
|
||||||
try {
|
try {
|
||||||
@ -86,7 +87,7 @@ public class EnableLeashingVillagers implements VillagerOptimizerModule, Listene
|
|||||||
|
|
||||||
if (log_enabled) {
|
if (log_enabled) {
|
||||||
VillagerOptimizer.getLog().info(Component.text(player.getName() + " leashed a villager at " +
|
VillagerOptimizer.getLog().info(Component.text(player.getName() + " leashed a villager at " +
|
||||||
CommonUtil.formatLocation(villager.getLocation())).color(VillagerOptimizer.STYLE.color()));
|
CommonUtil.formatLocation(villager.getLocation())).color(VillagerOptimizer.COLOR));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -68,22 +68,21 @@ public class LevelOptimizedProfession implements VillagerOptimizerModule, Listen
|
|||||||
event.getInventory().getType().equals(InventoryType.MERCHANT)
|
event.getInventory().getType().equals(InventoryType.MERCHANT)
|
||||||
&& event.getInventory().getHolder() instanceof Villager
|
&& event.getInventory().getHolder() instanceof Villager
|
||||||
) {
|
) {
|
||||||
Villager villager = (Villager) event.getInventory().getHolder();
|
final Villager villager = (Villager) event.getInventory().getHolder();
|
||||||
WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
final WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||||
if (!wVillager.isOptimized()) return;
|
if (!wVillager.isOptimized()) return;
|
||||||
|
|
||||||
if (wVillager.canLevelUp(cooldown_millis)) {
|
if (wVillager.canLevelUp(cooldown_millis)) {
|
||||||
if (wVillager.calculateLevel() > villager.getVillagerLevel()) {
|
if (wVillager.calculateLevel() <= villager.getVillagerLevel()) return;
|
||||||
|
|
||||||
scheduler.runAtEntity(villager, enableAI -> {
|
scheduler.runAtEntity(villager, enableAI -> {
|
||||||
villager.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 120, 120, false, false));
|
villager.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 120, 120, false, false));
|
||||||
villager.setAware(true);
|
villager.setAware(true);
|
||||||
|
|
||||||
scheduler.runAtEntityLater(villager, disableAI -> {
|
scheduler.runAtEntityLater(villager, disableAI -> {
|
||||||
villager.setAware(false);
|
villager.setAware(false);
|
||||||
wVillager.saveLastLevelUp();
|
wVillager.saveLastLevelUp();
|
||||||
}, 5, TimeUnit.SECONDS);
|
}, 5, TimeUnit.SECONDS);
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (notify_player) {
|
if (notify_player) {
|
||||||
Player player = (Player) event.getPlayer();
|
Player player = (Player) event.getPlayer();
|
||||||
|
@ -37,7 +37,7 @@ public class MakeVillagersSpawnAdult implements VillagerOptimizerModule, Listene
|
|||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onVillagerSpawn(CreatureSpawnEvent event) {
|
private void onVillagerSpawn(CreatureSpawnEvent event) {
|
||||||
if (event.getEntityType().equals(EntityType.VILLAGER)) {
|
if (event.getEntityType().equals(EntityType.VILLAGER)) {
|
||||||
Villager villager = (Villager) event.getEntity();
|
final Villager villager = (Villager) event.getEntity();
|
||||||
if (!villager.isAdult()) villager.setAdult();
|
if (!villager.isAdult()) villager.setAdult();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onTarget(EntityTargetEvent event) {
|
private void onTarget(EntityTargetEvent event) {
|
||||||
Entity target = event.getTarget();
|
final Entity target = event.getTarget();
|
||||||
if (
|
if (
|
||||||
target != null
|
target != null
|
||||||
&& target.getType().equals(EntityType.VILLAGER)
|
&& target.getType().equals(EntityType.VILLAGER)
|
||||||
@ -55,7 +55,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onEntityTargetVillager(EntityPathfindEvent event) {
|
private void onEntityTargetVillager(EntityPathfindEvent event) {
|
||||||
Entity target = event.getTargetEntity();
|
final Entity target = event.getTargetEntity();
|
||||||
if (
|
if (
|
||||||
target != null
|
target != null
|
||||||
&& target.getType().equals(EntityType.VILLAGER)
|
&& target.getType().equals(EntityType.VILLAGER)
|
||||||
|
@ -54,29 +54,26 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste
|
|||||||
if (!event.getInventory().getType().equals(InventoryType.MERCHANT)) return;
|
if (!event.getInventory().getType().equals(InventoryType.MERCHANT)) return;
|
||||||
if (event.getWhoClicked().hasPermission(Bypass.TRADE_PREVENTION.get())) return;
|
if (event.getWhoClicked().hasPermission(Bypass.TRADE_PREVENTION.get())) return;
|
||||||
if (!(event.getInventory().getHolder() instanceof Villager)) return;
|
if (!(event.getInventory().getHolder() instanceof Villager)) return;
|
||||||
|
if (villagerCache.getOrAdd((Villager) event.getInventory().getHolder()).isOptimized()) return;
|
||||||
|
|
||||||
Villager villager = (Villager) event.getInventory().getHolder();
|
|
||||||
|
|
||||||
if (!villagerCache.getOrAdd(villager).isOptimized()) {
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
||||||
if (notify_player) {
|
if (notify_player) {
|
||||||
Player player = (Player) event.getWhoClicked();
|
Player player = (Player) event.getWhoClicked();
|
||||||
VillagerOptimizer.getLang(player.locale()).optimize_for_trading
|
VillagerOptimizer.getLang(player.locale()).optimize_for_trading
|
||||||
.forEach(line -> KyoriUtil.sendMessage(player, line));
|
.forEach(line -> KyoriUtil.sendMessage(player, line));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onInventoryClick(InventoryClickEvent event) {
|
private void onInventoryClick(InventoryClickEvent event) {
|
||||||
if (!event.getInventory().getType().equals(InventoryType.MERCHANT)) return;
|
if (!event.getInventory().getType().equals(InventoryType.MERCHANT)) return;
|
||||||
if (event.getWhoClicked().hasPermission(Bypass.TRADE_PREVENTION.get())) return;
|
if (event.getWhoClicked().hasPermission(Bypass.TRADE_PREVENTION.get())) return;
|
||||||
if (!(event.getInventory().getHolder() instanceof Villager)) return;
|
if (!(event.getInventory().getHolder() instanceof Villager)) return;
|
||||||
|
if (villagerCache.getOrAdd((Villager) event.getInventory().getHolder()).isOptimized()) return;
|
||||||
|
|
||||||
Villager villager = (Villager) event.getInventory().getHolder();
|
|
||||||
|
|
||||||
if (!villagerCache.getOrAdd(villager).isOptimized()) {
|
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
|
|
||||||
if (notify_player) {
|
if (notify_player) {
|
||||||
Player player = (Player) event.getWhoClicked();
|
Player player = (Player) event.getWhoClicked();
|
||||||
VillagerOptimizer.getLang(player.locale()).optimize_for_trading
|
VillagerOptimizer.getLang(player.locale()).optimize_for_trading
|
||||||
@ -84,4 +81,3 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
package me.xginko.villageroptimizer.modules.gameplay;
|
|
||||||
|
|
||||||
import com.tcoded.folialib.impl.ServerImplementation;
|
|
||||||
import me.xginko.villageroptimizer.VillagerOptimizer;
|
|
||||||
import me.xginko.villageroptimizer.WrappedVillager;
|
|
||||||
import me.xginko.villageroptimizer.config.Config;
|
|
||||||
import me.xginko.villageroptimizer.events.VillagerOptimizeEvent;
|
|
||||||
import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent;
|
|
||||||
import me.xginko.villageroptimizer.modules.VillagerOptimizerModule;
|
|
||||||
import net.kyori.adventure.text.Component;
|
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import org.bukkit.entity.Villager;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.HandlerList;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
|
|
||||||
public class RenameOptimizedVillagers implements VillagerOptimizerModule, Listener {
|
|
||||||
|
|
||||||
private final ServerImplementation scheduler;
|
|
||||||
private final Component optimized_name;
|
|
||||||
private final boolean overwrite_previous_name;
|
|
||||||
|
|
||||||
public RenameOptimizedVillagers() {
|
|
||||||
shouldEnable();
|
|
||||||
this.scheduler = VillagerOptimizer.getFoliaLib().getImpl();
|
|
||||||
Config config = VillagerOptimizer.getConfiguration();
|
|
||||||
config.master().addComment("gameplay.rename-optimized-villagers.enable",
|
|
||||||
"Will change a villager's name to the name configured below when they are optimized.\n" +
|
|
||||||
"These names will be removed when unoptimized again if they were not changed in the meantime.");
|
|
||||||
this.optimized_name = MiniMessage.miniMessage().deserialize(
|
|
||||||
config.getString("gameplay.rename-optimized-villagers.optimized-name", "<green>Optimized",
|
|
||||||
"The name that will be used to mark optimized villagers. Uses MiniMessage format."));
|
|
||||||
this.overwrite_previous_name = config.getBoolean("gameplay.rename-optimized-villagers.overwrite-existing-name", false,
|
|
||||||
"If set to true, will rename even if the villager has already been named.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void enable() {
|
|
||||||
VillagerOptimizer plugin = VillagerOptimizer.getInstance();
|
|
||||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disable() {
|
|
||||||
HandlerList.unregisterAll(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldEnable() {
|
|
||||||
return VillagerOptimizer.getConfiguration().getBoolean("gameplay.rename-optimized-villagers.enable", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
private void onOptimize(VillagerOptimizeEvent event) {
|
|
||||||
WrappedVillager wVillager = event.getWrappedVillager();
|
|
||||||
Villager villager = wVillager.villager();
|
|
||||||
|
|
||||||
if (overwrite_previous_name || villager.customName() == null) {
|
|
||||||
scheduler.runAtEntityLater(villager, () -> {
|
|
||||||
villager.customName(optimized_name);
|
|
||||||
wVillager.memorizeName(optimized_name);
|
|
||||||
}, 10L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
|
||||||
private void onUnOptimize(VillagerUnoptimizeEvent event) {
|
|
||||||
WrappedVillager wVillager = event.getWrappedVillager();
|
|
||||||
Villager villager = wVillager.villager();
|
|
||||||
|
|
||||||
scheduler.runAtEntityLater(villager, () -> {
|
|
||||||
final Component currentName = villager.customName();
|
|
||||||
final Component memorizedName = wVillager.getMemorizedName();
|
|
||||||
if (currentName != null && currentName.equals(memorizedName))
|
|
||||||
villager.customName(null);
|
|
||||||
if (memorizedName != null)
|
|
||||||
wVillager.forgetName();
|
|
||||||
}, 10L);
|
|
||||||
}
|
|
||||||
}
|
|
@ -61,10 +61,10 @@ public class RestockOptimizedTrades implements VillagerOptimizerModule, Listener
|
|||||||
private void onInteract(PlayerInteractEntityEvent event) {
|
private void onInteract(PlayerInteractEntityEvent event) {
|
||||||
if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return;
|
if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return;
|
||||||
|
|
||||||
WrappedVillager wVillager = villagerCache.getOrAdd((Villager) event.getRightClicked());
|
final WrappedVillager wVillager = villagerCache.getOrAdd((Villager) event.getRightClicked());
|
||||||
if (!wVillager.isOptimized()) return;
|
if (!wVillager.isOptimized()) return;
|
||||||
Player player = event.getPlayer();
|
|
||||||
|
|
||||||
|
final Player player = event.getPlayer();
|
||||||
final boolean player_bypassing = player.hasPermission(Bypass.RESTOCK_COOLDOWN.get());
|
final boolean player_bypassing = player.hasPermission(Bypass.RESTOCK_COOLDOWN.get());
|
||||||
|
|
||||||
if (wVillager.canRestock(restock_delay_millis) || player_bypassing) {
|
if (wVillager.canRestock(restock_delay_millis) || player_bypassing) {
|
||||||
|
@ -39,9 +39,7 @@ public class UnoptimizeOnJobLoose implements VillagerOptimizerModule, Listener {
|
|||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onJobReset(VillagerCareerChangeEvent event) {
|
private void onJobReset(VillagerCareerChangeEvent event) {
|
||||||
if (!event.getReason().equals(VillagerCareerChangeEvent.ChangeReason.LOSING_JOB)) return;
|
if (!event.getReason().equals(VillagerCareerChangeEvent.ChangeReason.LOSING_JOB)) return;
|
||||||
|
final WrappedVillager wrappedVillager = villagerCache.getOrAdd(event.getEntity());
|
||||||
WrappedVillager wrappedVillager = villagerCache.getOrAdd(event.getEntity());
|
|
||||||
|
|
||||||
if (wrappedVillager.isOptimized()) {
|
if (wrappedVillager.isOptimized()) {
|
||||||
wrappedVillager.setOptimizationType(OptimizationType.NONE);
|
wrappedVillager.setOptimizationType(OptimizationType.NONE);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package me.xginko.villageroptimizer.modules.gameplay;
|
||||||
|
|
||||||
|
import com.tcoded.folialib.impl.ServerImplementation;
|
||||||
|
import me.xginko.villageroptimizer.VillagerOptimizer;
|
||||||
|
import me.xginko.villageroptimizer.config.Config;
|
||||||
|
import me.xginko.villageroptimizer.events.VillagerOptimizeEvent;
|
||||||
|
import me.xginko.villageroptimizer.events.VillagerUnoptimizeEvent;
|
||||||
|
import me.xginko.villageroptimizer.modules.VillagerOptimizerModule;
|
||||||
|
import org.bukkit.entity.Villager;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
public class VisuallyHighlightOptimized implements VillagerOptimizerModule, Listener {
|
||||||
|
|
||||||
|
private final ServerImplementation scheduler;
|
||||||
|
|
||||||
|
public VisuallyHighlightOptimized() {
|
||||||
|
shouldEnable();
|
||||||
|
this.scheduler = VillagerOptimizer.getFoliaLib().getImpl();
|
||||||
|
Config config = VillagerOptimizer.getConfiguration();
|
||||||
|
config.master().addComment("gameplay.outline-optimized-villagers.enable",
|
||||||
|
"Will make optimized villagers glow.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
VillagerOptimizer plugin = VillagerOptimizer.getInstance();
|
||||||
|
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
HandlerList.unregisterAll(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldEnable() {
|
||||||
|
return VillagerOptimizer.getConfiguration().getBoolean("gameplay.outline-optimized-villagers.enable", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onOptimize(VillagerOptimizeEvent event) {
|
||||||
|
Villager villager = event.getWrappedVillager().villager();
|
||||||
|
scheduler.runAtEntity(villager, glow -> {
|
||||||
|
if (!villager.isGlowing()) villager.setGlowing(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onUnOptimize(VillagerUnoptimizeEvent event) {
|
||||||
|
Villager villager = event.getWrappedVillager().villager();
|
||||||
|
scheduler.runAtEntity(villager, unGlow -> {
|
||||||
|
if (villager.isGlowing()) villager.setGlowing(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -17,8 +17,6 @@ import net.kyori.adventure.text.TextReplacementConfig;
|
|||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.Villager;
|
import org.bukkit.entity.Villager;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -96,9 +94,9 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onBlockPlace(BlockPlaceEvent event) {
|
private void onBlockPlace(BlockPlaceEvent event) {
|
||||||
Block placed = event.getBlock();
|
final Block placed = event.getBlock();
|
||||||
if (!blocks_that_disable.contains(placed.getType())) return;
|
if (!blocks_that_disable.contains(placed.getType())) return;
|
||||||
Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
if (!player.hasPermission(Optimize.BLOCK.get())) return;
|
if (!player.hasPermission(Optimize.BLOCK.get())) return;
|
||||||
if (only_while_sneaking && !player.isSneaking()) return;
|
if (only_while_sneaking && !player.isSneaking()) return;
|
||||||
|
|
||||||
@ -106,16 +104,14 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
|||||||
WrappedVillager closestOptimizableVillager = null;
|
WrappedVillager closestOptimizableVillager = null;
|
||||||
double closestDistance = Double.MAX_VALUE;
|
double closestDistance = Double.MAX_VALUE;
|
||||||
|
|
||||||
for (Entity entity : blockLoc.getNearbyEntities(search_radius, search_radius, search_radius)) {
|
for (Villager villager : blockLoc.getNearbyEntitiesByType(Villager.class, search_radius)) {
|
||||||
if (!entity.getType().equals(EntityType.VILLAGER)) continue;
|
|
||||||
Villager villager = (Villager) entity;
|
|
||||||
final Villager.Profession profession = villager.getProfession();
|
final Villager.Profession profession = villager.getProfession();
|
||||||
if (profession.equals(Villager.Profession.NONE) || profession.equals(Villager.Profession.NITWIT)) continue;
|
if (profession.equals(Villager.Profession.NONE) || profession.equals(Villager.Profession.NITWIT)) continue;
|
||||||
|
final double distance = villager.getLocation().distanceSquared(blockLoc);
|
||||||
|
if (distance >= closestDistance) continue;
|
||||||
|
|
||||||
WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
final WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||||
final double distance = entity.getLocation().distanceSquared(blockLoc);
|
if (wVillager.canOptimize(cooldown_millis)) {
|
||||||
|
|
||||||
if (distance < closestDistance && wVillager.canOptimize(cooldown_millis)) {
|
|
||||||
closestOptimizableVillager = wVillager;
|
closestOptimizableVillager = wVillager;
|
||||||
closestDistance = distance;
|
closestDistance = distance;
|
||||||
}
|
}
|
||||||
@ -132,7 +128,6 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!optimizeEvent.callEvent()) return;
|
if (!optimizeEvent.callEvent()) return;
|
||||||
|
|
||||||
closestOptimizableVillager.setOptimizationType(optimizeEvent.getOptimizationType());
|
closestOptimizableVillager.setOptimizationType(optimizeEvent.getOptimizationType());
|
||||||
closestOptimizableVillager.saveOptimizeTime();
|
closestOptimizableVillager.saveOptimizeTime();
|
||||||
|
|
||||||
@ -154,7 +149,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
|||||||
CommonUtil.formatLocation(closestOptimizableVillager.villager().getLocation())).color(VillagerOptimizer.COLOR));
|
CommonUtil.formatLocation(closestOptimizableVillager.villager().getLocation())).color(VillagerOptimizer.COLOR));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CommonUtil.shakeHead(closestOptimizableVillager.villager());
|
closestOptimizableVillager.sayNo();
|
||||||
if (notify_player) {
|
if (notify_player) {
|
||||||
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
||||||
.matchLiteral("%time%")
|
.matchLiteral("%time%")
|
||||||
@ -168,9 +163,9 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
|||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onBlockBreak(BlockBreakEvent event) {
|
private void onBlockBreak(BlockBreakEvent event) {
|
||||||
Block broken = event.getBlock();
|
final Block broken = event.getBlock();
|
||||||
if (!blocks_that_disable.contains(broken.getType())) return;
|
if (!blocks_that_disable.contains(broken.getType())) return;
|
||||||
Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
if (!player.hasPermission(Optimize.BLOCK.get())) return;
|
if (!player.hasPermission(Optimize.BLOCK.get())) return;
|
||||||
if (only_while_sneaking && !player.isSneaking()) return;
|
if (only_while_sneaking && !player.isSneaking()) return;
|
||||||
|
|
||||||
@ -178,14 +173,12 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
|||||||
WrappedVillager closestOptimizedVillager = null;
|
WrappedVillager closestOptimizedVillager = null;
|
||||||
double closestDistance = Double.MAX_VALUE;
|
double closestDistance = Double.MAX_VALUE;
|
||||||
|
|
||||||
for (Entity entity : blockLoc.getNearbyEntities(search_radius, search_radius, search_radius)) {
|
for (Villager villager : blockLoc.getNearbyEntitiesByType(Villager.class, search_radius)) {
|
||||||
if (!entity.getType().equals(EntityType.VILLAGER)) continue;
|
final double distance = villager.getLocation().distanceSquared(blockLoc);
|
||||||
Villager villager = (Villager) entity;
|
if (distance >= closestDistance) continue;
|
||||||
|
|
||||||
WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
final WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||||
final double distance = entity.getLocation().distanceSquared(blockLoc);
|
if (wVillager.isOptimized()) {
|
||||||
|
|
||||||
if (distance < closestDistance && wVillager.isOptimized()) {
|
|
||||||
closestOptimizedVillager = wVillager;
|
closestOptimizedVillager = wVillager;
|
||||||
closestDistance = distance;
|
closestDistance = distance;
|
||||||
}
|
}
|
||||||
@ -201,7 +194,6 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!unOptimizeEvent.callEvent()) return;
|
if (!unOptimizeEvent.callEvent()) return;
|
||||||
|
|
||||||
closestOptimizedVillager.setOptimizationType(OptimizationType.NONE);
|
closestOptimizedVillager.setOptimizationType(OptimizationType.NONE);
|
||||||
|
|
||||||
if (notify_player) {
|
if (notify_player) {
|
||||||
|
@ -14,7 +14,6 @@ import me.xginko.villageroptimizer.utils.CommonUtil;
|
|||||||
import me.xginko.villageroptimizer.utils.KyoriUtil;
|
import me.xginko.villageroptimizer.utils.KyoriUtil;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.TextReplacementConfig;
|
import net.kyori.adventure.text.TextReplacementConfig;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -36,7 +35,6 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
||||||
|
|
||||||
private final PlainTextComponentSerializer plainTextSerializer;
|
|
||||||
private final VillagerCache villagerCache;
|
private final VillagerCache villagerCache;
|
||||||
private final Set<String> nametags;
|
private final Set<String> nametags;
|
||||||
private final long cooldown;
|
private final long cooldown;
|
||||||
@ -44,7 +42,6 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
|||||||
|
|
||||||
public OptimizeByNametag() {
|
public OptimizeByNametag() {
|
||||||
shouldEnable();
|
shouldEnable();
|
||||||
this.plainTextSerializer = PlainTextComponentSerializer.plainText();
|
|
||||||
this.villagerCache = VillagerOptimizer.getCache();
|
this.villagerCache = VillagerOptimizer.getCache();
|
||||||
Config config = VillagerOptimizer.getConfiguration();
|
Config config = VillagerOptimizer.getConfiguration();
|
||||||
config.master().addComment("optimization-methods.nametag-optimization.enable",
|
config.master().addComment("optimization-methods.nametag-optimization.enable",
|
||||||
@ -83,23 +80,23 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
|||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
private void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||||
if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return;
|
if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return;
|
||||||
Player player = event.getPlayer();
|
final Player player = event.getPlayer();
|
||||||
if (!player.hasPermission(Optimize.NAMETAG.get())) return;
|
if (!player.hasPermission(Optimize.NAMETAG.get())) return;
|
||||||
|
|
||||||
ItemStack usedItem = player.getInventory().getItem(event.getHand());
|
final ItemStack usedItem = player.getInventory().getItem(event.getHand());
|
||||||
if (usedItem != null && !usedItem.getType().equals(Material.NAME_TAG)) return;
|
if (usedItem != null && !usedItem.getType().equals(Material.NAME_TAG)) return;
|
||||||
if (!usedItem.hasItemMeta()) return;
|
if (!usedItem.hasItemMeta()) return;
|
||||||
ItemMeta meta = usedItem.getItemMeta();
|
final ItemMeta meta = usedItem.getItemMeta();
|
||||||
if (!meta.hasDisplayName()) return;
|
if (!meta.hasDisplayName()) return;
|
||||||
|
|
||||||
// Get component name first, so we can manually name the villager when canceling the event to avoid item consumption.
|
// Get component name first, so we can manually name the villager when canceling the event to avoid item consumption.
|
||||||
Component newVillagerName = meta.displayName();
|
final Component newVillagerName = meta.displayName();
|
||||||
assert newVillagerName != null; // Legitimate since we checked for hasDisplayName()
|
assert newVillagerName != null; // Legitimate since we checked for hasDisplayName()
|
||||||
final String name = plainTextSerializer.serialize(newVillagerName);
|
final String nameTagPlainText = CommonUtil.plainTextSerializer.serialize(newVillagerName);
|
||||||
Villager villager = (Villager) event.getRightClicked();
|
final Villager villager = (Villager) event.getRightClicked();
|
||||||
WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
final WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||||
|
|
||||||
if (nametags.contains(name.toLowerCase())) {
|
if (nametags.contains(nameTagPlainText.toLowerCase())) {
|
||||||
if (wVillager.canOptimize(cooldown) || player.hasPermission(Bypass.NAMETAG_COOLDOWN.get())) {
|
if (wVillager.canOptimize(cooldown) || player.hasPermission(Bypass.NAMETAG_COOLDOWN.get())) {
|
||||||
VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(
|
VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(
|
||||||
wVillager,
|
wVillager,
|
||||||
@ -125,12 +122,12 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
|||||||
|
|
||||||
if (log_enabled) {
|
if (log_enabled) {
|
||||||
VillagerOptimizer.getLog().info(Component.text(player.getName() +
|
VillagerOptimizer.getLog().info(Component.text(player.getName() +
|
||||||
" optimized villager by nametag '" + name + "' at " +
|
" optimized villager by nametag '" + nameTagPlainText + "' at " +
|
||||||
CommonUtil.formatLocation(wVillager.villager().getLocation())).color(VillagerOptimizer.COLOR));
|
CommonUtil.formatLocation(wVillager.villager().getLocation())).color(VillagerOptimizer.COLOR));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
event.setCancelled(true);
|
event.setCancelled(true);
|
||||||
CommonUtil.shakeHead(villager);
|
wVillager.sayNo();
|
||||||
if (notify_player) {
|
if (notify_player) {
|
||||||
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
||||||
.matchLiteral("%time%")
|
.matchLiteral("%time%")
|
||||||
@ -142,9 +139,14 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (wVillager.isOptimized()) {
|
if (wVillager.isOptimized()) {
|
||||||
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager, player, OptimizationType.NAMETAG, event.isAsynchronous());
|
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(
|
||||||
if (!unOptimizeEvent.callEvent()) return;
|
wVillager,
|
||||||
|
player,
|
||||||
|
OptimizationType.NAMETAG,
|
||||||
|
event.isAsynchronous()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!unOptimizeEvent.callEvent()) return;
|
||||||
wVillager.setOptimizationType(OptimizationType.NONE);
|
wVillager.setOptimizationType(OptimizationType.NONE);
|
||||||
|
|
||||||
if (notify_player) {
|
if (notify_player) {
|
||||||
@ -154,7 +156,7 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
|||||||
|
|
||||||
if (log_enabled) {
|
if (log_enabled) {
|
||||||
VillagerOptimizer.getLog().info(Component.text(player.getName() +
|
VillagerOptimizer.getLog().info(Component.text(player.getName() +
|
||||||
" unoptimized villager by nametag '" + name + "' at " +
|
" unoptimized villager by nametag '" + nameTagPlainText + "' at " +
|
||||||
CommonUtil.formatLocation(wVillager.villager().getLocation())).color(VillagerOptimizer.COLOR));
|
CommonUtil.formatLocation(wVillager.villager().getLocation())).color(VillagerOptimizer.COLOR));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import org.bukkit.event.HandlerList;
|
|||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
import org.bukkit.event.block.BlockPlaceEvent;
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
|
import org.bukkit.event.entity.VillagerCareerChangeEvent;
|
||||||
import org.bukkit.util.NumberConversions;
|
import org.bukkit.util.NumberConversions;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -93,6 +94,20 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener
|
|||||||
return VillagerOptimizer.getConfiguration().getBoolean("optimization-methods.workstation-optimization.enable", false);
|
return VillagerOptimizer.getConfiguration().getBoolean("optimization-methods.workstation-optimization.enable", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Place block -> Remember what and where
|
||||||
|
// Wait for villager to claim jobsite
|
||||||
|
// Do optimization on that villager
|
||||||
|
|
||||||
|
// Destroy workstation -> look for nearby villager that claimed it
|
||||||
|
// Do unoptimization immediately
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
private void onCareerChange(VillagerCareerChangeEvent event) {
|
||||||
|
if (!event.getReason().equals(VillagerCareerChangeEvent.ChangeReason.EMPLOYED)) return;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
private void onBlockPlace(BlockPlaceEvent event) {
|
private void onBlockPlace(BlockPlaceEvent event) {
|
||||||
final Block placed = event.getBlock();
|
final Block placed = event.getBlock();
|
||||||
@ -127,7 +142,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener
|
|||||||
|
|
||||||
pending_optimizations.put(placed.getLocation(), scheduler.runAtLocationLater(workstationLoc, () -> {
|
pending_optimizations.put(placed.getLocation(), scheduler.runAtLocationLater(workstationLoc, () -> {
|
||||||
if (!finalToOptimize.canOptimize(cooldown_millis) && !player.hasPermission(Bypass.WORKSTATION_COOLDOWN.get())) {
|
if (!finalToOptimize.canOptimize(cooldown_millis) && !player.hasPermission(Bypass.WORKSTATION_COOLDOWN.get())) {
|
||||||
CommonUtil.shakeHead(finalToOptimize.villager());
|
finalToOptimize.sayNo();
|
||||||
if (notify_player) {
|
if (notify_player) {
|
||||||
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
||||||
.matchLiteral("%time%")
|
.matchLiteral("%time%")
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package me.xginko.villageroptimizer.utils;
|
package me.xginko.villageroptimizer.utils;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
@ -9,6 +10,8 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
|
|
||||||
public class CommonUtil {
|
public class CommonUtil {
|
||||||
|
public static final PlainTextComponentSerializer plainTextSerializer = PlainTextComponentSerializer.plainText();
|
||||||
|
|
||||||
public static @NotNull String formatDuration(Duration duration) {
|
public static @NotNull String formatDuration(Duration duration) {
|
||||||
if (duration.isNegative()) duration = duration.negated();
|
if (duration.isNegative()) duration = duration.negated();
|
||||||
|
|
||||||
@ -42,12 +45,6 @@ public class CommonUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void shakeHead(@NotNull Villager villager) {
|
|
||||||
try {
|
|
||||||
villager.shakeHead();
|
|
||||||
} catch (NoSuchMethodError ignored) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Villager.Profession getWorkstationProfession(@NotNull Material workstation) {
|
public static Villager.Profession getWorkstationProfession(@NotNull Material workstation) {
|
||||||
switch (workstation) {
|
switch (workstation) {
|
||||||
case BARREL:
|
case BARREL:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package me.xginko.villageroptimizer.logging;
|
package me.xginko.villageroptimizer.utils;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||||
@ -22,4 +22,3 @@ public final class ComponentLoggerProviderImpl implements ComponentLoggerProvide
|
|||||||
return helper.delegating(LoggerFactory.getLogger(name), SERIALIZER::serialize);
|
return helper.delegating(LoggerFactory.getLogger(name), SERIALIZER::serialize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package me.xginko.villageroptimizer.logging;
|
package me.xginko.villageroptimizer.utils;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.TranslatableComponent;
|
import net.kyori.adventure.text.TranslatableComponent;
|
@ -1 +1 @@
|
|||||||
me.xginko.villageroptimizer.logging.ComponentLoggerProviderImpl
|
me.xginko.villageroptimizer.utils.ComponentLoggerProviderImpl
|
Loading…
x
Reference in New Issue
Block a user