large chunk of progress
This commit is contained in:
parent
84e9542f19
commit
4d01238f4f
@ -15,7 +15,7 @@ public class LanguageCache {
|
||||
|
||||
public final Component no_permission;
|
||||
public final List<Component> nametag_optimize_success, nametag_on_optimize_cooldown, nametag_unoptimize_success,
|
||||
block_optimization_success, block_on_optimize_cooldown, block_unoptimize_success,
|
||||
block_optimize_success, block_on_optimize_cooldown, block_unoptimize_success,
|
||||
workstation_optimization_success, workstation_on_optimize_cooldown, workstation_unoptimize_success;
|
||||
|
||||
public LanguageCache(String lang) throws Exception {
|
||||
@ -26,7 +26,7 @@ public class LanguageCache {
|
||||
this.nametag_optimize_success = getListTranslation("messages.nametag.optimize-success", List.of("<green>Successfully optimized villager by using a nametag."));
|
||||
this.nametag_on_optimize_cooldown = getListTranslation("messages.nametag.optimize-on-cooldown", List.of("<gray>You need to wait %time% until you can optimize this villager again."));
|
||||
this.nametag_unoptimize_success = getListTranslation("messages.nametag.unoptimize-success", List.of("<green>Successfully unoptimized villager by using a nametag."));
|
||||
this.block_optimization_success = getListTranslation("messages.block.optimize-success", List.of("<green>%villagertype% villager successfully optimized using block %blocktype%."));
|
||||
this.block_optimize_success = getListTranslation("messages.block.optimize-success", List.of("<green>%villagertype% villager successfully optimized using block %blocktype%."));
|
||||
this.block_on_optimize_cooldown = getListTranslation("messages.block.optimize-on-cooldown", List.of("<gray>You need to wait %time% until you can optimize this villager again."));
|
||||
this.block_unoptimize_success = getListTranslation("messages.block.unoptimize-success", List.of("<green>Successfully unoptimized villager by moving it off a %blocktype% block."));
|
||||
this.workstation_optimization_success = getListTranslation("messages.workstation.optimize-success", List.of("<green>%villagertype% villager successfully optimized using workstation block %blocktype%."));
|
||||
|
@ -15,14 +15,14 @@ public final class WrappedVillager {
|
||||
|
||||
public WrappedVillager(@NotNull Villager villager) {
|
||||
this.villager = villager;
|
||||
this.villagerData = villager.getPersistentDataContainer();
|
||||
this.villagerData = this.villager.getPersistentDataContainer();
|
||||
}
|
||||
|
||||
public @NotNull Villager villager() {
|
||||
return villager;
|
||||
}
|
||||
|
||||
public static @NotNull WrappedVillager fromVillager(Villager villager) {
|
||||
public static @NotNull WrappedVillager fromCache(Villager villager) {
|
||||
return VillagerOptimizer.getVillagerCache().get(villager);
|
||||
}
|
||||
|
||||
|
@ -36,16 +36,16 @@ public class AntiVillagerDamage implements VillagerOptimizerModule, Listener {
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onDamage(EntityDamageEvent event) {
|
||||
if (!event.getEntity().getType().equals(EntityType.VILLAGER)) return;
|
||||
private void onDamageReceive(EntityDamageEvent event) {
|
||||
if (!event.getEntityType().equals(EntityType.VILLAGER)) return;
|
||||
if (cache.get((Villager) event.getEntity()).isOptimized()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onPathfind(EntityPushedByEntityAttackEvent event) {
|
||||
if (!event.getEntity().getType().equals(EntityType.VILLAGER)) return;
|
||||
private void onPushByEntityAttack(EntityPushedByEntityAttackEvent event) {
|
||||
if (!event.getEntityType().equals(EntityType.VILLAGER)) return;
|
||||
if (cache.get((Villager) event.getEntity()).isOptimized()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
@ -3,11 +3,14 @@ package me.xginko.villageroptimizer.modules;
|
||||
import com.destroystokyo.paper.event.entity.EntityPathfindEvent;
|
||||
import me.xginko.villageroptimizer.VillagerOptimizer;
|
||||
import me.xginko.villageroptimizer.models.VillagerCache;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Mob;
|
||||
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;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.EntityTargetLivingEntityEvent;
|
||||
|
||||
public class AntiVillagerTargetting implements VillagerOptimizerModule, Listener {
|
||||
@ -42,9 +45,20 @@ public class AntiVillagerTargetting implements VillagerOptimizerModule, Listener
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onTarget(EntityPathfindEvent event) {
|
||||
private void onEntityTargetVillager(EntityPathfindEvent event) {
|
||||
if (event.getTargetEntity() instanceof Villager villager && cache.get(villager).isOptimized()) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onEntityAttackVillager(EntityDamageByEntityEvent event) {
|
||||
if (
|
||||
event.getEntityType().equals(EntityType.VILLAGER)
|
||||
&& event.getDamager() instanceof Mob attacker
|
||||
&& cache.get((Villager) event.getEntity()).isOptimized()
|
||||
) {
|
||||
attacker.setTarget(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,43 @@
|
||||
package me.xginko.villageroptimizer.modules;
|
||||
|
||||
import io.papermc.paper.event.entity.EntityMoveEvent;
|
||||
import me.xginko.villageroptimizer.VillagerOptimizer;
|
||||
import me.xginko.villageroptimizer.config.Config;
|
||||
import me.xginko.villageroptimizer.enums.OptimizationType;
|
||||
import me.xginko.villageroptimizer.models.VillagerCache;
|
||||
import me.xginko.villageroptimizer.models.WrappedVillager;
|
||||
import me.xginko.villageroptimizer.utils.CommonUtils;
|
||||
import net.kyori.adventure.text.TextReplacementConfig;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
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;
|
||||
import org.bukkit.event.EventPriority;
|
||||
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.player.PlayerInteractEntityEvent;
|
||||
|
||||
public class BlockOptimization implements VillagerOptimizerModule, Listener {
|
||||
|
||||
private final VillagerCache cache;
|
||||
private final Config config;
|
||||
private final boolean shouldLog;
|
||||
private final boolean shouldLog, shouldNotifyPlayer;
|
||||
|
||||
protected BlockOptimization() {
|
||||
this.cache = VillagerOptimizer.getVillagerCache();
|
||||
this.config = VillagerOptimizer.getConfiguration();
|
||||
this.config.addComment("optimization.methods.by-specific-block.enable", """
|
||||
When enabled, villagers standing on the configured specific blocks will become optimized once a\s
|
||||
player interacts with them. If the block is broken or moved, the villager will become unoptimized\s
|
||||
again once a player interacts with the villager afterwards.
|
||||
""");
|
||||
this.shouldLog = config.getBoolean("optimization.methods.by-specific-block.log", false);
|
||||
this.shouldNotifyPlayer = config.getBoolean("optimization.methods.by-specific-block.notify-player", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -43,24 +57,91 @@ public class BlockOptimization implements VillagerOptimizerModule, Listener {
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
private void onEntityMove(EntityMoveEvent event) {
|
||||
if (!event.getEntityType().equals(EntityType.VILLAGER)) return;
|
||||
private void onBlockPlace(BlockPlaceEvent event) {
|
||||
Block placed = event.getBlock();
|
||||
if (!config.blocks_that_disable.contains(placed.getType())) return;
|
||||
|
||||
placed.getRelative(BlockFace.UP).getLocation().getNearbyEntities(0.5,0.5,0.5).forEach(entity -> {
|
||||
if (entity.getType().equals(EntityType.VILLAGER)) {
|
||||
WrappedVillager wVillager = cache.get((Villager) entity);
|
||||
if (!wVillager.isOptimized()) {
|
||||
if (wVillager.setOptimization(OptimizationType.BLOCK)) {
|
||||
if (shouldNotifyPlayer) {
|
||||
Player player = event.getPlayer();
|
||||
VillagerOptimizer.getLang(player.locale()).block_optimize_success.forEach(player::sendMessage);
|
||||
}
|
||||
if (shouldLog)
|
||||
VillagerOptimizer.getLog().info("Villager was optimized by block at "+wVillager.villager().getLocation());
|
||||
} else {
|
||||
if (shouldNotifyPlayer) {
|
||||
Player player = event.getPlayer();
|
||||
VillagerOptimizer.getLang(player.locale()).block_on_optimize_cooldown.forEach(line -> player.sendMessage(line
|
||||
.replaceText(TextReplacementConfig.builder().matchLiteral("%time%").replacement(CommonUtils.formatTime(wVillager.getOptimizeCooldown())).build())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
private void onBlockBreak(BlockBreakEvent event) {
|
||||
Block broken = event.getBlock();
|
||||
if (!config.blocks_that_disable.contains(broken.getType())) return;
|
||||
|
||||
broken.getRelative(BlockFace.UP).getLocation().getNearbyEntities(0.5,0.5,0.5).forEach(entity -> {
|
||||
if (entity.getType().equals(EntityType.VILLAGER)) {
|
||||
WrappedVillager wVillager = cache.get((Villager) entity);
|
||||
if (wVillager.getOptimizationType().equals(OptimizationType.BLOCK)) {
|
||||
wVillager.setOptimization(OptimizationType.OFF);
|
||||
if (shouldNotifyPlayer) {
|
||||
Player player = event.getPlayer();
|
||||
VillagerOptimizer.getLang(player.locale()).block_unoptimize_success.forEach(player::sendMessage);
|
||||
}
|
||||
if (shouldLog)
|
||||
VillagerOptimizer.getLog().info("Villager unoptimized because no longer standing on optimization block at "+wVillager.villager().getLocation());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
private void onPlayerInteract(PlayerInteractEntityEvent event) {
|
||||
Entity interacted = event.getRightClicked();
|
||||
if (!interacted.getType().equals(EntityType.VILLAGER)) return;
|
||||
|
||||
WrappedVillager wVillager = cache.get((Villager) interacted);
|
||||
final Location entityLegs = interacted.getLocation();
|
||||
|
||||
final Location entityLegs = event.getEntity().getLocation();
|
||||
if (
|
||||
config.blocks_that_disable.contains(entityLegs.getBlock().getType())
|
||||
config.blocks_that_disable.contains(entityLegs.getBlock().getType()) // for slabs and sink in blocks
|
||||
|| config.blocks_that_disable.contains(entityLegs.clone().subtract(0,1,0).getBlock().getType())
|
||||
) {
|
||||
WrappedVillager wVillager = cache.get((Villager) event.getEntity());
|
||||
if (!wVillager.isOptimized()) {
|
||||
wVillager.setOptimization(OptimizationType.BLOCK);
|
||||
if (shouldLog) VillagerOptimizer.getLog().info("Villager moved onto an optimization block at "+wVillager.villager().getLocation());
|
||||
if (wVillager.setOptimization(OptimizationType.BLOCK)) {
|
||||
if (shouldNotifyPlayer) {
|
||||
Player player = event.getPlayer();
|
||||
VillagerOptimizer.getLang(player.locale()).block_optimize_success.forEach(player::sendMessage);
|
||||
}
|
||||
if (shouldLog)
|
||||
VillagerOptimizer.getLog().info("Villager was optimized by block at "+wVillager.villager().getLocation());
|
||||
} else {
|
||||
if (shouldNotifyPlayer) {
|
||||
Player player = event.getPlayer();
|
||||
VillagerOptimizer.getLang(player.locale()).block_on_optimize_cooldown.forEach(line -> player.sendMessage(line
|
||||
.replaceText(TextReplacementConfig.builder().matchLiteral("%time%").replacement(CommonUtils.formatTime(wVillager.getOptimizeCooldown())).build())));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
WrappedVillager wVillager = cache.get((Villager) event.getEntity());
|
||||
if (wVillager.isOptimized()) {
|
||||
if (wVillager.getOptimizationType().equals(OptimizationType.BLOCK)) {
|
||||
wVillager.setOptimization(OptimizationType.OFF);
|
||||
if (shouldLog) VillagerOptimizer.getLog().info("Villager moved away from an optimization block at "+wVillager.villager().getLocation());
|
||||
if (shouldNotifyPlayer) {
|
||||
Player player = event.getPlayer();
|
||||
VillagerOptimizer.getLang(player.locale()).block_unoptimize_success.forEach(player::sendMessage);
|
||||
}
|
||||
if (shouldLog)
|
||||
VillagerOptimizer.getLog().info("Villager unoptimized because no longer standing on optimization block at "+wVillager.villager().getLocation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,6 @@ public class ChunkLimit implements VillagerOptimizerModule, Listener {
|
||||
|
||||
private int getProfessionPriority(Villager villager) {
|
||||
Villager.Profession profession = villager.getProfession();
|
||||
return removalPriority.contains(profession) && !WrappedVillager.fromVillager(villager).isOptimized() ? removalPriority.indexOf(profession) : Integer.MAX_VALUE;
|
||||
return removalPriority.contains(profession) && !WrappedVillager.fromCache(villager).isOptimized() ? removalPriority.indexOf(profession) : Integer.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,12 @@ public class NametagOptimization implements VillagerOptimizerModule, Listener {
|
||||
protected NametagOptimization() {
|
||||
this.cache = VillagerOptimizer.getVillagerCache();
|
||||
this.config = VillagerOptimizer.getConfiguration();
|
||||
this.config.addComment("optimization.methods.by-nametag.enable",
|
||||
"""
|
||||
Enable optimization by naming villagers to one of the names configured below.\s
|
||||
Nametag optimized villagers will be unoptimized again when they are renamed to something else.
|
||||
"""
|
||||
);
|
||||
this.shouldLog = config.getBoolean("optimization.methods.by-nametag.log", false);
|
||||
this.shouldNotifyPlayer = config.getBoolean("optimization.methods.by-nametag.notify-player", true);
|
||||
}
|
||||
@ -48,7 +54,7 @@ public class NametagOptimization implements VillagerOptimizerModule, Listener {
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
private void onNametag(PlayerNameEntityEvent event) {
|
||||
private void onPlayerNameEntity(PlayerNameEntityEvent event) {
|
||||
if (!event.getEntity().getType().equals(EntityType.VILLAGER)) return;
|
||||
Component name = event.getName();
|
||||
if (name == null) return;
|
||||
@ -68,14 +74,13 @@ public class NametagOptimization implements VillagerOptimizerModule, Listener {
|
||||
} else {
|
||||
if (shouldNotifyPlayer) {
|
||||
Player player = event.getPlayer();
|
||||
VillagerOptimizer.getLang(player.locale()).nametag_on_optimize_cooldown.forEach(line ->
|
||||
player.sendMessage(line.replaceText(TextReplacementConfig.builder().matchLiteral("%time").replacement(CommonUtils.formatTime(wVillager.getOptimizeCooldown())).build()))
|
||||
);
|
||||
VillagerOptimizer.getLang(player.locale()).nametag_on_optimize_cooldown.forEach(line -> player.sendMessage(line
|
||||
.replaceText(TextReplacementConfig.builder().matchLiteral("%time%").replacement(CommonUtils.formatTime(wVillager.getOptimizeCooldown())).build())));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (wVillager.isOptimized()) {
|
||||
if (wVillager.getOptimizationType().equals(OptimizationType.NAMETAG)) {
|
||||
wVillager.setOptimization(OptimizationType.OFF);
|
||||
if (shouldNotifyPlayer) {
|
||||
Player player = event.getPlayer();
|
||||
|
@ -2,6 +2,7 @@ package me.xginko.villageroptimizer.modules;
|
||||
|
||||
import me.xginko.villageroptimizer.VillagerOptimizer;
|
||||
import me.xginko.villageroptimizer.config.Config;
|
||||
import me.xginko.villageroptimizer.models.VillagerCache;
|
||||
import me.xginko.villageroptimizer.models.WrappedVillager;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Villager;
|
||||
@ -13,12 +14,19 @@ import org.bukkit.event.player.PlayerInteractEntityEvent;
|
||||
|
||||
public class RestockOptimized implements VillagerOptimizerModule, Listener {
|
||||
|
||||
private final VillagerCache cache;
|
||||
private final long restock_delay;
|
||||
private final boolean shouldLog;
|
||||
|
||||
public RestockOptimized() {
|
||||
this.cache = VillagerOptimizer.getVillagerCache();
|
||||
Config config = VillagerOptimizer.getConfiguration();
|
||||
this.restock_delay = config.getInt("")
|
||||
config.addComment("optimization.trade-restocking.enable", """
|
||||
This is for automatic restocking of trades for optimized villagers. Optimized Villagers\s
|
||||
Don't have enough AI to do trade restocks themselves, so this needs to always be enabled.
|
||||
""");
|
||||
this.restock_delay = config.getInt("optimization.trade-restocking.delay-in-ticks", 1200);
|
||||
this.shouldLog = config.getBoolean("optimization.trade-restocking.log", false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -34,15 +42,15 @@ public class RestockOptimized implements VillagerOptimizerModule, Listener {
|
||||
|
||||
@Override
|
||||
public boolean shouldEnable() {
|
||||
return true;
|
||||
return VillagerOptimizer.getConfiguration().getBoolean("optimization.trade-restocking.enable", true);
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
private void onInteract(PlayerInteractEntityEvent event) {
|
||||
if (!event.getRightClicked().getType().equals(EntityType.VILLAGER)) return;
|
||||
WrappedVillager wrappedVillager = new WrappedVillager((Villager) event.getRightClicked());
|
||||
if (!wrappedVillager.isOptimized()) return;
|
||||
WrappedVillager wVillager = cache.get((Villager) event.getRightClicked());
|
||||
if (!wVillager.isOptimized()) return;
|
||||
|
||||
|
||||
if (wrappedVillager.getSavedWorldTime() >)
|
||||
}
|
||||
}
|
||||
|
@ -14,12 +14,17 @@ public class WorkstationOptimization implements VillagerOptimizerModule, Listene
|
||||
|
||||
private final VillagerCache cache;
|
||||
private final Config config;
|
||||
private final boolean shouldLog;
|
||||
private final boolean shouldLog, shouldNotifyPlayer;
|
||||
|
||||
protected WorkstationOptimization() {
|
||||
this.cache = VillagerOptimizer.getVillagerCache();
|
||||
this.config = VillagerOptimizer.getConfiguration();
|
||||
this.config.addComment("optimization.methods.by-workstation.enable", """
|
||||
When enabled, villagers near a configured radius to a workstation specific to their profession\s
|
||||
will be optimized.
|
||||
""");
|
||||
this.shouldLog = config.getBoolean("optimization.methods.by-workstation.log", false);
|
||||
this.shouldNotifyPlayer = config.getBoolean("optimization.methods.by-workstation.notify-player", true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,4 +1,5 @@
|
||||
name: VillagerOptimizer
|
||||
version: '${project.version}'
|
||||
main: me.xginko.villageroptimizer.VillagerOptimizer
|
||||
api-version: '1.20'
|
||||
api-version: '1.19'
|
||||
folia-supported: true
|
Loading…
x
Reference in New Issue
Block a user