ExcellentEnchants-spigot/Core/src/main/java/su/nightexpress/excellentenchants/enchantment/impl/tool/DivineTouchEnchant.java

169 lines
6.5 KiB
Java

package su.nightexpress.excellentenchants.enchantment.impl.tool;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.enchantments.EnchantmentTarget;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockDropItemEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BlockStateMeta;
import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.api.config.JOption;
import su.nexmedia.engine.api.manager.EventListener;
import su.nexmedia.engine.lang.LangManager;
import su.nexmedia.engine.utils.Colorizer;
import su.nexmedia.engine.utils.Colors;
import su.nexmedia.engine.utils.LocationUtil;
import su.nexmedia.engine.utils.PDCUtil;
import su.nexmedia.engine.utils.values.UniParticle;
import su.nightexpress.excellentenchants.ExcellentEnchants;
import su.nightexpress.excellentenchants.Placeholders;
import su.nightexpress.excellentenchants.api.enchantment.meta.Chanced;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockBreakEnchant;
import su.nightexpress.excellentenchants.api.enchantment.type.BlockDropEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.ExcellentEnchant;
import su.nightexpress.excellentenchants.enchantment.impl.meta.ChanceImplementation;
import su.nightexpress.excellentenchants.api.enchantment.ItemCategory;
import su.nightexpress.excellentenchants.enchantment.util.EnchantUtils;
public class DivineTouchEnchant extends ExcellentEnchant implements Chanced, BlockBreakEnchant, BlockDropEnchant, EventListener {
public static final String ID = "divine_touch";
private final NamespacedKey key;
private String spawnerName;
private ChanceImplementation chanceImplementation;
private Location handleSpawner;
public DivineTouchEnchant(@NotNull ExcellentEnchants plugin) {
super(plugin, ID);
this.key = new NamespacedKey(plugin, "divine_spawner");
this.getDefaults().setDescription(Placeholders.ENCHANTMENT_CHANCE + "% chance to mine spawner.");
this.getDefaults().setLevelMax(5);
this.getDefaults().setTier(1.0);
this.getDefaults().setConflicts(SmelterEnchant.ID);
}
@Override
public void loadSettings() {
super.loadSettings();
this.chanceImplementation = ChanceImplementation.create(this,
"15.0 * " + Placeholders.ENCHANTMENT_LEVEL);
this.spawnerName = JOption.create("Settings.Spawner_Item.Name",
Colors.GREEN + "Mob Spawner " + Colors.GRAY + "(" + Placeholders.GENERIC_TYPE + ")",
"Spawner item display name.",
"Placeholder '" + Placeholders.GENERIC_TYPE + "' for the mob type."
).mapReader(Colorizer::apply).read(cfg);
}
@NotNull
@Override
public ChanceImplementation getChanceImplementation() {
return chanceImplementation;
}
@Override
@NotNull
public ItemCategory[] getFitItemTypes() {
return new ItemCategory[]{ItemCategory.PICKAXE};
}
@Override
@NotNull
public EnchantmentTarget getCategory() {
return EnchantmentTarget.TOOL;
}
@NotNull
@Override
public EventPriority getDropPriority() {
return EventPriority.NORMAL;
}
@NotNull
@Override
public EventPriority getBreakPriority() {
return EventPriority.HIGH;
}
@NotNull
public ItemStack getSpawner(@NotNull CreatureSpawner spawnerBlock) {
ItemStack itemSpawner = new ItemStack(Material.SPAWNER);
BlockStateMeta stateItem = (BlockStateMeta) itemSpawner.getItemMeta();
if (stateItem == null || spawnerBlock.getSpawnedType() == null) return itemSpawner;
CreatureSpawner spawnerItem = (CreatureSpawner) stateItem.getBlockState();
spawnerItem.setSpawnedType(spawnerBlock.getSpawnedType());
spawnerItem.update(true);
stateItem.setBlockState(spawnerItem);
stateItem.setDisplayName(this.spawnerName.replace(Placeholders.GENERIC_TYPE, LangManager.getEntityType(spawnerBlock.getSpawnedType())));
itemSpawner.setItemMeta(stateItem);
PDCUtil.set(itemSpawner, this.key, true);
return itemSpawner;
}
@Override
public boolean onDrop(@NotNull BlockDropItemEvent event, @NotNull LivingEntity player, @NotNull ItemStack item, int level) {
BlockState state = event.getBlockState();
Block block = state.getBlock();
if (this.handleSpawner == null || !this.handleSpawner.equals(block.getLocation())) return false;
this.handleSpawner = null;
if (!(state instanceof CreatureSpawner spawnerBlock)) return false;
EnchantUtils.popResource(event, this.getSpawner(spawnerBlock));
if (this.hasVisualEffects()) {
Location location = LocationUtil.getCenter(block.getLocation());
UniParticle.of(Particle.VILLAGER_HAPPY).play(location, 0.3, 0.15, 30);
}
return true;
}
@Override
public boolean onBreak(@NotNull BlockBreakEvent event, @NotNull LivingEntity player, @NotNull ItemStack item, int level) {
Block block = event.getBlock();
if (!(block.getState() instanceof CreatureSpawner spawnerBlock)) return false;
if (!this.checkTriggerChance(level)) return false;
event.setExpToDrop(0);
event.setDropItems(true);
this.handleSpawner = block.getLocation();
return false; // Do not consume charges
}
// Update spawner type of the placed spawner mined by Divine Touch.
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onSpawnerPlace(BlockPlaceEvent e) {
Block block = e.getBlock();
if (block.getType() != Material.SPAWNER) return;
Player player = e.getPlayer();
ItemStack spawner = player.getInventory().getItem(e.getHand());
if (spawner == null || spawner.getType() != Material.SPAWNER || !(spawner.getItemMeta() instanceof BlockStateMeta meta)) return;
if (PDCUtil.getBoolean(spawner, this.key).isEmpty()) return;
CreatureSpawner spawnerItem = (CreatureSpawner) meta.getBlockState();
CreatureSpawner spawnerBlock = (CreatureSpawner) block.getState();
spawnerBlock.setSpawnedType(spawnerItem.getSpawnedType());
spawnerBlock.update();
}
}