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");
|
||||
Files.createDirectories(langDirectory.toPath());
|
||||
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(
|
||||
Component.text("│ ").style(STYLE)
|
||||
.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())) {
|
||||
return pluginJarFile.stream()
|
||||
.map(ZipEntry::getName)
|
||||
.filter(name -> name.startsWith("lang" + File.separator) && name.endsWith(".yml"))
|
||||
.filter(name -> name.startsWith("lang/") && name.endsWith(".yml"))
|
||||
.collect(Collectors.toSet());
|
||||
} catch (IOException 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.OptimizationType;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.entity.memory.MemoryKey;
|
||||
import org.bukkit.inventory.MerchantRecipe;
|
||||
@ -262,6 +261,14 @@ public final class WrappedVillager {
|
||||
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.
|
||||
* @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;
|
||||
}
|
||||
|
||||
public void memorizeName(final Component customName) {
|
||||
dataContainer.set(Keyring.VillagerOptimizer.LAST_OPTIMIZE_NAME.getKey(), PersistentDataType.STRING, MiniMessage.miniMessage().serialize(customName));
|
||||
}
|
||||
|
||||
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());
|
||||
public void sayNo() {
|
||||
try {
|
||||
villager.shakeHead();
|
||||
} catch (NoSuchMethodError e) {
|
||||
villager.getWorld().playSound(villager.getLocation(), Sound.ENTITY_VILLAGER_NO, 1.0F, 1.0F);
|
||||
}
|
||||
}
|
||||
|
||||
private static class CachedJobSite {
|
||||
private final @NotNull Villager villager;
|
||||
private @Nullable Location jobSite;
|
||||
private long lastRefresh;
|
||||
private CachedJobSite(Villager villager) {
|
||||
this.jobSite = villager.getMemory(MemoryKey.JOB_SITE);
|
||||
this.lastRefresh = System.currentTimeMillis();
|
||||
private CachedJobSite(@NotNull Villager villager) {
|
||||
this.villager = villager;
|
||||
this.jobSite = getJobSite();
|
||||
}
|
||||
private @Nullable Location getJobSite(Villager villager) {
|
||||
private @Nullable Location getJobSite() {
|
||||
final long now = System.currentTimeMillis();
|
||||
if (now - lastRefresh > 1000L) {
|
||||
this.jobSite = villager.getMemory(MemoryKey.JOB_SITE);
|
||||
@ -338,11 +340,6 @@ public final class WrappedVillager {
|
||||
public @Nullable Location getJobSite() {
|
||||
if (cachedJobSite == null)
|
||||
cachedJobSite = new CachedJobSite(villager);
|
||||
return cachedJobSite.getJobSite(villager);
|
||||
}
|
||||
|
||||
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;
|
||||
return cachedJobSite.getJobSite();
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ public class LanguageCache {
|
||||
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
|
||||
if (!langYML.exists())
|
||||
plugin.saveResource("lang" + File.separator + locale + ".yml", false);
|
||||
plugin.saveResource("lang/" + locale + ".yml", false);
|
||||
// Finally, load the lang file with configmaster
|
||||
this.lang = ConfigFile.loadConfig(langYML);
|
||||
|
||||
|
@ -27,7 +27,7 @@ public interface VillagerOptimizerModule {
|
||||
modules.add(new FixOptimisationAfterCure());
|
||||
modules.add(new RestockOptimizedTrades());
|
||||
modules.add(new LevelOptimizedProfession());
|
||||
modules.add(new RenameOptimizedVillagers());
|
||||
modules.add(new VisuallyHighlightOptimized());
|
||||
modules.add(new MakeVillagersSpawnAdult());
|
||||
modules.add(new PreventUnoptimizedTrading());
|
||||
modules.add(new PreventOptimizedTargeting());
|
||||
|
@ -62,11 +62,12 @@ public class EnableLeashingVillagers implements VillagerOptimizerModule, Listene
|
||||
final ItemStack handItem = player.getInventory().getItem(event.getHand());
|
||||
if (handItem == null || !handItem.getType().equals(Material.LEAD)) return;
|
||||
|
||||
Villager villager = (Villager) event.getRightClicked();
|
||||
final Villager villager = (Villager) event.getRightClicked();
|
||||
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;
|
||||
|
||||
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
|
||||
PlayerLeashEntityEvent leashEvent;
|
||||
try {
|
||||
@ -86,7 +87,7 @@ public class EnableLeashingVillagers implements VillagerOptimizerModule, Listene
|
||||
|
||||
if (log_enabled) {
|
||||
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().getHolder() instanceof Villager
|
||||
) {
|
||||
Villager villager = (Villager) event.getInventory().getHolder();
|
||||
WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||
final Villager villager = (Villager) event.getInventory().getHolder();
|
||||
final WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||
if (!wVillager.isOptimized()) return;
|
||||
|
||||
if (wVillager.canLevelUp(cooldown_millis)) {
|
||||
if (wVillager.calculateLevel() > villager.getVillagerLevel()) {
|
||||
scheduler.runAtEntity(villager, enableAI -> {
|
||||
villager.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 120, 120, false, false));
|
||||
villager.setAware(true);
|
||||
if (wVillager.calculateLevel() <= villager.getVillagerLevel()) return;
|
||||
|
||||
scheduler.runAtEntityLater(villager, disableAI -> {
|
||||
villager.setAware(false);
|
||||
wVillager.saveLastLevelUp();
|
||||
}, 5, TimeUnit.SECONDS);
|
||||
});
|
||||
}
|
||||
scheduler.runAtEntity(villager, enableAI -> {
|
||||
villager.addPotionEffect(new PotionEffect(PotionEffectType.SLOW, 120, 120, false, false));
|
||||
villager.setAware(true);
|
||||
scheduler.runAtEntityLater(villager, disableAI -> {
|
||||
villager.setAware(false);
|
||||
wVillager.saveLastLevelUp();
|
||||
}, 5, TimeUnit.SECONDS);
|
||||
});
|
||||
} else {
|
||||
if (notify_player) {
|
||||
Player player = (Player) event.getPlayer();
|
||||
|
@ -37,7 +37,7 @@ public class MakeVillagersSpawnAdult implements VillagerOptimizerModule, Listene
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onVillagerSpawn(CreatureSpawnEvent event) {
|
||||
if (event.getEntityType().equals(EntityType.VILLAGER)) {
|
||||
Villager villager = (Villager) event.getEntity();
|
||||
final Villager villager = (Villager) event.getEntity();
|
||||
if (!villager.isAdult()) villager.setAdult();
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onTarget(EntityTargetEvent event) {
|
||||
Entity target = event.getTarget();
|
||||
final Entity target = event.getTarget();
|
||||
if (
|
||||
target != null
|
||||
&& target.getType().equals(EntityType.VILLAGER)
|
||||
@ -55,7 +55,7 @@ public class PreventOptimizedTargeting implements VillagerOptimizerModule, Liste
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onEntityTargetVillager(EntityPathfindEvent event) {
|
||||
Entity target = event.getTargetEntity();
|
||||
final Entity target = event.getTargetEntity();
|
||||
if (
|
||||
target != null
|
||||
&& target.getType().equals(EntityType.VILLAGER)
|
||||
|
@ -54,16 +54,14 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste
|
||||
if (!event.getInventory().getType().equals(InventoryType.MERCHANT)) return;
|
||||
if (event.getWhoClicked().hasPermission(Bypass.TRADE_PREVENTION.get())) return;
|
||||
if (!(event.getInventory().getHolder() instanceof Villager)) return;
|
||||
if (villagerCache.getOrAdd((Villager) event.getInventory().getHolder()).isOptimized()) return;
|
||||
|
||||
Villager villager = (Villager) event.getInventory().getHolder();
|
||||
event.setCancelled(true);
|
||||
|
||||
if (!villagerCache.getOrAdd(villager).isOptimized()) {
|
||||
event.setCancelled(true);
|
||||
if (notify_player) {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
VillagerOptimizer.getLang(player.locale()).optimize_for_trading
|
||||
.forEach(line -> KyoriUtil.sendMessage(player, line));
|
||||
}
|
||||
if (notify_player) {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
VillagerOptimizer.getLang(player.locale()).optimize_for_trading
|
||||
.forEach(line -> KyoriUtil.sendMessage(player, line));
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,16 +70,14 @@ public class PreventUnoptimizedTrading implements VillagerOptimizerModule, Liste
|
||||
if (!event.getInventory().getType().equals(InventoryType.MERCHANT)) return;
|
||||
if (event.getWhoClicked().hasPermission(Bypass.TRADE_PREVENTION.get())) return;
|
||||
if (!(event.getInventory().getHolder() instanceof Villager)) return;
|
||||
if (villagerCache.getOrAdd((Villager) event.getInventory().getHolder()).isOptimized()) return;
|
||||
|
||||
Villager villager = (Villager) event.getInventory().getHolder();
|
||||
event.setCancelled(true);
|
||||
|
||||
if (!villagerCache.getOrAdd(villager).isOptimized()) {
|
||||
event.setCancelled(true);
|
||||
if (notify_player) {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
VillagerOptimizer.getLang(player.locale()).optimize_for_trading
|
||||
.forEach(line -> KyoriUtil.sendMessage(player, line));
|
||||
}
|
||||
if (notify_player) {
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
VillagerOptimizer.getLang(player.locale()).optimize_for_trading
|
||||
.forEach(line -> KyoriUtil.sendMessage(player, line));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
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;
|
||||
Player player = event.getPlayer();
|
||||
|
||||
final Player player = event.getPlayer();
|
||||
final boolean player_bypassing = player.hasPermission(Bypass.RESTOCK_COOLDOWN.get());
|
||||
|
||||
if (wVillager.canRestock(restock_delay_millis) || player_bypassing) {
|
||||
|
@ -39,9 +39,7 @@ public class UnoptimizeOnJobLoose implements VillagerOptimizerModule, Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onJobReset(VillagerCareerChangeEvent event) {
|
||||
if (!event.getReason().equals(VillagerCareerChangeEvent.ChangeReason.LOSING_JOB)) return;
|
||||
|
||||
WrappedVillager wrappedVillager = villagerCache.getOrAdd(event.getEntity());
|
||||
|
||||
final WrappedVillager wrappedVillager = villagerCache.getOrAdd(event.getEntity());
|
||||
if (wrappedVillager.isOptimized()) {
|
||||
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.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Villager;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -58,7 +56,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
||||
try {
|
||||
return Material.valueOf(configuredMaterial);
|
||||
} catch (IllegalArgumentException e) {
|
||||
VillagerOptimizer.getLog().warn("(block-optimization) Material '"+configuredMaterial +
|
||||
VillagerOptimizer.getLog().warn("(block-optimization) Material '" + configuredMaterial +
|
||||
"' not recognized. Please use correct Material enums from: " +
|
||||
"https://jd.papermc.io/paper/1.20/org/bukkit/Material.html");
|
||||
return null;
|
||||
@ -96,9 +94,9 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onBlockPlace(BlockPlaceEvent event) {
|
||||
Block placed = event.getBlock();
|
||||
final Block placed = event.getBlock();
|
||||
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 (only_while_sneaking && !player.isSneaking()) return;
|
||||
|
||||
@ -106,16 +104,14 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
||||
WrappedVillager closestOptimizableVillager = null;
|
||||
double closestDistance = Double.MAX_VALUE;
|
||||
|
||||
for (Entity entity : blockLoc.getNearbyEntities(search_radius, search_radius, search_radius)) {
|
||||
if (!entity.getType().equals(EntityType.VILLAGER)) continue;
|
||||
Villager villager = (Villager) entity;
|
||||
for (Villager villager : blockLoc.getNearbyEntitiesByType(Villager.class, search_radius)) {
|
||||
final Villager.Profession profession = villager.getProfession();
|
||||
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 double distance = entity.getLocation().distanceSquared(blockLoc);
|
||||
|
||||
if (distance < closestDistance && wVillager.canOptimize(cooldown_millis)) {
|
||||
final WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||
if (wVillager.canOptimize(cooldown_millis)) {
|
||||
closestOptimizableVillager = wVillager;
|
||||
closestDistance = distance;
|
||||
}
|
||||
@ -132,7 +128,6 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
||||
);
|
||||
|
||||
if (!optimizeEvent.callEvent()) return;
|
||||
|
||||
closestOptimizableVillager.setOptimizationType(optimizeEvent.getOptimizationType());
|
||||
closestOptimizableVillager.saveOptimizeTime();
|
||||
|
||||
@ -154,7 +149,7 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
||||
CommonUtil.formatLocation(closestOptimizableVillager.villager().getLocation())).color(VillagerOptimizer.COLOR));
|
||||
}
|
||||
} else {
|
||||
CommonUtil.shakeHead(closestOptimizableVillager.villager());
|
||||
closestOptimizableVillager.sayNo();
|
||||
if (notify_player) {
|
||||
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
||||
.matchLiteral("%time%")
|
||||
@ -168,9 +163,9 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onBlockBreak(BlockBreakEvent event) {
|
||||
Block broken = event.getBlock();
|
||||
final Block broken = event.getBlock();
|
||||
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 (only_while_sneaking && !player.isSneaking()) return;
|
||||
|
||||
@ -178,14 +173,12 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
||||
WrappedVillager closestOptimizedVillager = null;
|
||||
double closestDistance = Double.MAX_VALUE;
|
||||
|
||||
for (Entity entity : blockLoc.getNearbyEntities(search_radius, search_radius, search_radius)) {
|
||||
if (!entity.getType().equals(EntityType.VILLAGER)) continue;
|
||||
Villager villager = (Villager) entity;
|
||||
for (Villager villager : blockLoc.getNearbyEntitiesByType(Villager.class, search_radius)) {
|
||||
final double distance = villager.getLocation().distanceSquared(blockLoc);
|
||||
if (distance >= closestDistance) continue;
|
||||
|
||||
WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||
final double distance = entity.getLocation().distanceSquared(blockLoc);
|
||||
|
||||
if (distance < closestDistance && wVillager.isOptimized()) {
|
||||
final WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||
if (wVillager.isOptimized()) {
|
||||
closestOptimizedVillager = wVillager;
|
||||
closestDistance = distance;
|
||||
}
|
||||
@ -201,7 +194,6 @@ public class OptimizeByBlock implements VillagerOptimizerModule, Listener {
|
||||
);
|
||||
|
||||
if (!unOptimizeEvent.callEvent()) return;
|
||||
|
||||
closestOptimizedVillager.setOptimizationType(OptimizationType.NONE);
|
||||
|
||||
if (notify_player) {
|
||||
|
@ -14,7 +14,6 @@ import me.xginko.villageroptimizer.utils.CommonUtil;
|
||||
import me.xginko.villageroptimizer.utils.KyoriUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextReplacementConfig;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -36,7 +35,6 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
||||
|
||||
private final PlainTextComponentSerializer plainTextSerializer;
|
||||
private final VillagerCache villagerCache;
|
||||
private final Set<String> nametags;
|
||||
private final long cooldown;
|
||||
@ -44,7 +42,6 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
||||
|
||||
public OptimizeByNametag() {
|
||||
shouldEnable();
|
||||
this.plainTextSerializer = PlainTextComponentSerializer.plainText();
|
||||
this.villagerCache = VillagerOptimizer.getCache();
|
||||
Config config = VillagerOptimizer.getConfiguration();
|
||||
config.master().addComment("optimization-methods.nametag-optimization.enable",
|
||||
@ -83,23 +80,23 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
|
||||
if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return;
|
||||
Player player = event.getPlayer();
|
||||
final Player player = event.getPlayer();
|
||||
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.hasItemMeta()) return;
|
||||
ItemMeta meta = usedItem.getItemMeta();
|
||||
final ItemMeta meta = usedItem.getItemMeta();
|
||||
if (!meta.hasDisplayName()) return;
|
||||
|
||||
// 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()
|
||||
final String name = plainTextSerializer.serialize(newVillagerName);
|
||||
Villager villager = (Villager) event.getRightClicked();
|
||||
WrappedVillager wVillager = villagerCache.getOrAdd(villager);
|
||||
final String nameTagPlainText = CommonUtil.plainTextSerializer.serialize(newVillagerName);
|
||||
final Villager villager = (Villager) event.getRightClicked();
|
||||
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())) {
|
||||
VillagerOptimizeEvent optimizeEvent = new VillagerOptimizeEvent(
|
||||
wVillager,
|
||||
@ -125,12 +122,12 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
||||
|
||||
if (log_enabled) {
|
||||
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));
|
||||
}
|
||||
} else {
|
||||
event.setCancelled(true);
|
||||
CommonUtil.shakeHead(villager);
|
||||
wVillager.sayNo();
|
||||
if (notify_player) {
|
||||
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
||||
.matchLiteral("%time%")
|
||||
@ -142,9 +139,14 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
||||
}
|
||||
} else {
|
||||
if (wVillager.isOptimized()) {
|
||||
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(wVillager, player, OptimizationType.NAMETAG, event.isAsynchronous());
|
||||
if (!unOptimizeEvent.callEvent()) return;
|
||||
VillagerUnoptimizeEvent unOptimizeEvent = new VillagerUnoptimizeEvent(
|
||||
wVillager,
|
||||
player,
|
||||
OptimizationType.NAMETAG,
|
||||
event.isAsynchronous()
|
||||
);
|
||||
|
||||
if (!unOptimizeEvent.callEvent()) return;
|
||||
wVillager.setOptimizationType(OptimizationType.NONE);
|
||||
|
||||
if (notify_player) {
|
||||
@ -154,7 +156,7 @@ public class OptimizeByNametag implements VillagerOptimizerModule, Listener {
|
||||
|
||||
if (log_enabled) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.VillagerCareerChangeEvent;
|
||||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
import java.time.Duration;
|
||||
@ -93,6 +94,20 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener
|
||||
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)
|
||||
private void onBlockPlace(BlockPlaceEvent event) {
|
||||
final Block placed = event.getBlock();
|
||||
@ -127,7 +142,7 @@ public class OptimizeByWorkstation implements VillagerOptimizerModule, Listener
|
||||
|
||||
pending_optimizations.put(placed.getLocation(), scheduler.runAtLocationLater(workstationLoc, () -> {
|
||||
if (!finalToOptimize.canOptimize(cooldown_millis) && !player.hasPermission(Bypass.WORKSTATION_COOLDOWN.get())) {
|
||||
CommonUtil.shakeHead(finalToOptimize.villager());
|
||||
finalToOptimize.sayNo();
|
||||
if (notify_player) {
|
||||
final TextReplacementConfig timeLeft = TextReplacementConfig.builder()
|
||||
.matchLiteral("%time%")
|
||||
|
@ -1,5 +1,6 @@
|
||||
package me.xginko.villageroptimizer.utils;
|
||||
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
@ -9,6 +10,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.time.Duration;
|
||||
|
||||
public class CommonUtil {
|
||||
public static final PlainTextComponentSerializer plainTextSerializer = PlainTextComponentSerializer.plainText();
|
||||
|
||||
public static @NotNull String formatDuration(Duration duration) {
|
||||
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) {
|
||||
switch (workstation) {
|
||||
case BARREL:
|
||||
|
@ -1,4 +1,4 @@
|
||||
package me.xginko.villageroptimizer.logging;
|
||||
package me.xginko.villageroptimizer.utils;
|
||||
|
||||
import com.google.auto.service.AutoService;
|
||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
@ -21,5 +21,4 @@ public final class ComponentLoggerProviderImpl implements ComponentLoggerProvide
|
||||
) {
|
||||
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.TranslatableComponent;
|
@ -1 +1 @@
|
||||
me.xginko.villageroptimizer.logging.ComponentLoggerProviderImpl
|
||||
me.xginko.villageroptimizer.utils.ComponentLoggerProviderImpl
|
Loading…
x
Reference in New Issue
Block a user