2019-05-23 22:15:04 +02:00
|
|
|
package com.songoda.ultimatestacker.listeners;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2019-09-03 23:08:30 +02:00
|
|
|
import com.songoda.core.compatibility.ServerProject;
|
|
|
|
import com.songoda.core.compatibility.ServerVersion;
|
2021-06-14 01:30:48 +02:00
|
|
|
import com.songoda.core.lootables.loot.Drop;
|
|
|
|
import com.songoda.core.lootables.loot.DropUtils;
|
2018-11-06 04:33:10 +01:00
|
|
|
import com.songoda.ultimatestacker.UltimateStacker;
|
2019-09-07 23:55:16 +02:00
|
|
|
import com.songoda.ultimatestacker.settings.Settings;
|
2020-09-01 20:13:53 +02:00
|
|
|
import com.songoda.ultimatestacker.stackable.entity.EntityStack;
|
2023-03-29 21:21:00 +02:00
|
|
|
import org.bukkit.Bukkit;
|
2022-09-19 19:45:08 +02:00
|
|
|
import org.bukkit.GameMode;
|
2019-12-16 23:23:53 +01:00
|
|
|
import org.bukkit.GameRule;
|
2019-08-30 03:10:13 +02:00
|
|
|
import org.bukkit.Material;
|
2019-08-30 21:40:34 +02:00
|
|
|
import org.bukkit.enchantments.Enchantment;
|
2019-08-30 03:10:13 +02:00
|
|
|
import org.bukkit.entity.ChestedHorse;
|
2019-09-22 14:25:39 +02:00
|
|
|
import org.bukkit.entity.EntityType;
|
2019-08-30 03:10:13 +02:00
|
|
|
import org.bukkit.entity.LivingEntity;
|
2019-07-26 03:40:13 +02:00
|
|
|
import org.bukkit.entity.Player;
|
2018-11-06 04:33:10 +01:00
|
|
|
import org.bukkit.event.EventHandler;
|
|
|
|
import org.bukkit.event.Listener;
|
2019-08-30 21:40:34 +02:00
|
|
|
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
2021-02-22 18:30:14 +01:00
|
|
|
import org.bukkit.event.entity.EntityDamageEvent;
|
2018-11-06 04:33:10 +01:00
|
|
|
import org.bukkit.event.entity.EntityDeathEvent;
|
2019-07-08 18:39:57 +02:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2019-07-08 21:42:19 +02:00
|
|
|
import java.util.ArrayList;
|
2019-08-30 03:10:13 +02:00
|
|
|
import java.util.Arrays;
|
2021-02-22 18:30:14 +01:00
|
|
|
import java.util.HashMap;
|
2019-07-08 18:39:57 +02:00
|
|
|
import java.util.List;
|
2021-02-22 18:30:14 +01:00
|
|
|
import java.util.Map;
|
2019-08-30 21:40:34 +02:00
|
|
|
import java.util.Random;
|
2021-02-22 18:30:14 +01:00
|
|
|
import java.util.UUID;
|
2019-10-16 16:39:50 +02:00
|
|
|
import java.util.stream.Collectors;
|
2019-02-25 15:23:41 +01:00
|
|
|
|
2018-11-06 04:33:10 +01:00
|
|
|
public class DeathListeners implements Listener {
|
|
|
|
|
2020-09-01 20:54:43 +02:00
|
|
|
private final UltimateStacker plugin;
|
|
|
|
private final Random random;
|
2018-11-06 04:33:10 +01:00
|
|
|
|
2020-09-01 20:54:43 +02:00
|
|
|
public DeathListeners(UltimateStacker plugin) {
|
|
|
|
this.plugin = plugin;
|
|
|
|
this.random = new Random();
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
|
|
|
|
2021-02-22 18:30:14 +01:00
|
|
|
|
|
|
|
private final Map<UUID, List<ItemStack>> finalItems = new HashMap<>();
|
|
|
|
|
2023-05-05 10:57:17 +02:00
|
|
|
@EventHandler
|
2021-02-22 18:30:14 +01:00
|
|
|
public void onEntityDamage(EntityDamageEvent event) {
|
|
|
|
if (!(event.getEntity() instanceof LivingEntity))
|
|
|
|
return;
|
|
|
|
LivingEntity entity = (LivingEntity) event.getEntity();
|
|
|
|
|
|
|
|
if (entity.getHealth() - event.getFinalDamage() < 0)
|
|
|
|
finalItems.put(entity.getUniqueId(), getItems(entity));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-05-05 10:57:17 +02:00
|
|
|
@EventHandler
|
2018-11-06 04:33:10 +01:00
|
|
|
public void onEntityDeath(EntityDeathEvent event) {
|
2021-02-22 18:30:14 +01:00
|
|
|
LivingEntity entity = event.getEntity();
|
2019-09-22 14:25:39 +02:00
|
|
|
if (event.getEntityType() == EntityType.PLAYER
|
|
|
|
|| event.getEntityType() == EntityType.ARMOR_STAND) return;
|
2019-07-26 03:40:13 +02:00
|
|
|
|
2023-01-16 21:32:17 +01:00
|
|
|
//Respect MythicMobs
|
|
|
|
if (plugin.getCustomEntityManager().isCustomEntity(entity)) return;
|
|
|
|
|
2019-09-07 23:55:16 +02:00
|
|
|
boolean custom = Settings.CUSTOM_DROPS.getBoolean();
|
2020-09-01 20:54:43 +02:00
|
|
|
List<Drop> drops = custom ? plugin.getLootablesManager().getDrops(event.getEntity())
|
2019-10-16 16:39:50 +02:00
|
|
|
: event.getDrops().stream().map(Drop::new).collect(Collectors.toList());
|
2019-07-08 18:39:57 +02:00
|
|
|
|
2019-10-16 16:39:50 +02:00
|
|
|
if (custom) {
|
|
|
|
for (ItemStack item : new ArrayList<>(event.getDrops())) {
|
|
|
|
if (shouldDrop(event.getEntity(), item.getType()))
|
|
|
|
drops.add(new Drop(item));
|
|
|
|
}
|
2019-08-30 03:10:13 +02:00
|
|
|
}
|
2019-07-08 18:39:57 +02:00
|
|
|
|
2019-12-27 13:56:38 +01:00
|
|
|
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_13)
|
2021-02-22 18:30:14 +01:00
|
|
|
&& !entity.getWorld().getGameRuleValue(GameRule.DO_MOB_LOOT))
|
2019-12-16 23:23:53 +01:00
|
|
|
drops.clear();
|
|
|
|
|
2023-01-02 13:38:58 +01:00
|
|
|
if (plugin.getCustomEntityManager().getCustomEntity(entity) == null) {
|
2023-03-29 21:21:00 +02:00
|
|
|
//replace %player% in drop commands with the last player to damage the entity
|
|
|
|
//Run commands here, or it will be buggy
|
|
|
|
runCommands(entity, drops);
|
|
|
|
|
2023-02-04 14:48:13 +01:00
|
|
|
if (plugin.getEntityStackManager().isStackedEntity(event.getEntity())) {
|
2023-01-02 13:38:58 +01:00
|
|
|
plugin.getEntityStackManager().getStack(event.getEntity()).onDeath(entity, drops, custom, event.getDroppedExp(), event);
|
|
|
|
} else {
|
|
|
|
DropUtils.processStackedDrop(event.getEntity(), drops, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-22 18:30:14 +01:00
|
|
|
finalItems.remove(entity.getUniqueId());
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|
2019-08-30 03:10:13 +02:00
|
|
|
|
2023-03-29 21:21:00 +02:00
|
|
|
private void runCommands(LivingEntity entity, List<Drop> drops) {
|
|
|
|
String lastDamage = plugin.getEntityStackManager().getLastPlayerDamage(entity);
|
|
|
|
if (lastDamage != null) {
|
|
|
|
List<String> commands = new ArrayList<>();
|
|
|
|
drops.forEach(drop -> {
|
|
|
|
if (drop.getCommand() != null) {
|
|
|
|
String command = drop.getCommand().replace("%player%", lastDamage);
|
|
|
|
drop.setCommand(null);
|
|
|
|
commands.add(command);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
Bukkit.getScheduler().runTask(plugin, () -> {
|
|
|
|
for (String command : commands) {
|
|
|
|
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-30 03:10:13 +02:00
|
|
|
private boolean shouldDrop(LivingEntity entity, Material material) {
|
|
|
|
if (entity.getEquipment() != null && entity.getEquipment().getArmorContents().length != 0) {
|
2021-05-27 16:37:51 +02:00
|
|
|
if (Settings.DONT_DROP_ARMOR.getBoolean())
|
|
|
|
return false;
|
2021-02-22 18:30:14 +01:00
|
|
|
if (finalItems.containsKey(entity.getUniqueId())) {
|
|
|
|
List<ItemStack> items = finalItems.get(entity.getUniqueId());
|
|
|
|
for (ItemStack item : items)
|
|
|
|
if (item.getType() == material)
|
|
|
|
return true;
|
|
|
|
}
|
2019-08-30 03:10:13 +02:00
|
|
|
}
|
2021-05-27 16:37:05 +02:00
|
|
|
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_12)
|
2020-09-01 20:54:43 +02:00
|
|
|
&& entity instanceof ChestedHorse
|
|
|
|
&& ((ChestedHorse) entity).getInventory().contains(material))
|
|
|
|
return true;
|
2019-08-30 03:10:13 +02:00
|
|
|
|
|
|
|
switch (material.name()) {
|
|
|
|
case "SADDLE":
|
|
|
|
return !entity.getType().name().equals("RAVAGER");
|
|
|
|
case "DIAMOND_HORSE_ARMOR":
|
|
|
|
case "GOLDEN_HORSE_ARMOR":
|
|
|
|
case "IRON_HORSE_ARMOR":
|
|
|
|
case "LEATHER_HORSE_ARMOR":
|
|
|
|
case "CYAN_CARPET":
|
|
|
|
case "BLACK_CARPET":
|
|
|
|
case "BLUE_CARPET":
|
|
|
|
case "BROWN_CARPET":
|
|
|
|
case "GRAY_CARPET":
|
|
|
|
case "GREEN_CARPET":
|
|
|
|
case "LIGHT_BLUE_CARPET":
|
|
|
|
case "LIGHT_GRAY_CARPET":
|
|
|
|
case "LIME_CARPET":
|
|
|
|
case "MAGENTA_CARPET":
|
|
|
|
case "ORANGE_CARPET":
|
|
|
|
case "PINK_CARPET":
|
|
|
|
case "PURPLE_CARPET":
|
|
|
|
case "RED_CARPET":
|
|
|
|
case "WHITE_CARPET":
|
|
|
|
case "YELLOW_CARPET":
|
|
|
|
case "CARPET":
|
|
|
|
case "CHEST":
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2019-08-30 21:40:34 +02:00
|
|
|
|
2021-02-22 18:30:14 +01:00
|
|
|
public List<ItemStack> getItems(LivingEntity entity) {
|
|
|
|
if (entity.getEquipment() != null && entity.getEquipment().getArmorContents().length != 0) {
|
|
|
|
List<ItemStack> items = new ArrayList<>(Arrays.asList(entity.getEquipment().getArmorContents()));
|
|
|
|
items.add(entity.getEquipment().getItemInHand());
|
|
|
|
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9))
|
|
|
|
items.add(entity.getEquipment().getItemInOffHand());
|
|
|
|
return items;
|
|
|
|
}
|
|
|
|
return new ArrayList<>();
|
|
|
|
}
|
|
|
|
|
2019-08-30 21:40:34 +02:00
|
|
|
@EventHandler
|
|
|
|
public void onEntityHit(EntityDamageByEntityEvent event) {
|
2020-06-03 15:44:12 +02:00
|
|
|
if (!(event.getDamager() instanceof Player) || ServerVersion.isServerVersionAtOrBelow(ServerVersion.V1_12))
|
|
|
|
return;
|
2020-08-25 01:01:11 +02:00
|
|
|
|
|
|
|
if (!(event.getEntity() instanceof LivingEntity)) return;
|
|
|
|
LivingEntity entity = (LivingEntity) event.getEntity();
|
2023-02-04 14:48:13 +01:00
|
|
|
if (!plugin.getEntityStackManager().isStackedEntity(entity)) return;
|
2020-09-01 20:54:43 +02:00
|
|
|
EntityStack stack = plugin.getEntityStackManager().getStack(entity);
|
2019-08-30 21:40:34 +02:00
|
|
|
|
2022-09-19 19:45:08 +02:00
|
|
|
Player player = (Player) event.getDamager();
|
|
|
|
|
|
|
|
if (Settings.KILL_WHOLE_STACK_ON_DEATH.getBoolean() && Settings.REALISTIC_DAMAGE.getBoolean() && !player.getGameMode().equals(GameMode.CREATIVE)) {
|
2019-09-12 17:36:58 +02:00
|
|
|
ItemStack tool = player.getInventory().getItemInHand();
|
2019-12-11 22:43:23 +01:00
|
|
|
if (tool.getType().getMaxDurability() < 1 || (tool.getItemMeta() != null && (tool.getItemMeta().isUnbreakable()
|
|
|
|
|| (ServerProject.isServer(ServerProject.SPIGOT, ServerProject.PAPER) && tool.getItemMeta().isUnbreakable()))))
|
2019-08-30 21:40:34 +02:00
|
|
|
return;
|
|
|
|
|
|
|
|
int unbreakingLevel = tool.getEnchantmentLevel(Enchantment.DURABILITY);
|
|
|
|
|
|
|
|
int actualDamage = 0;
|
|
|
|
for (int i = 0; i < stack.getAmount(); i++)
|
|
|
|
if (checkUnbreakingChance(unbreakingLevel))
|
|
|
|
actualDamage++;
|
|
|
|
|
2019-10-16 16:39:50 +02:00
|
|
|
tool.setDurability((short) (tool.getDurability() + actualDamage));
|
2019-08-30 21:40:34 +02:00
|
|
|
|
|
|
|
if (!this.hasEnoughDurability(tool, 1))
|
2019-09-12 17:36:58 +02:00
|
|
|
player.getInventory().setItemInHand(null);
|
2019-08-30 21:40:34 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasEnoughDurability(ItemStack tool, int requiredAmount) {
|
2019-09-13 23:45:03 +02:00
|
|
|
if (tool.getType().getMaxDurability() <= 1)
|
2019-08-30 21:40:34 +02:00
|
|
|
return true;
|
2019-09-13 23:45:03 +02:00
|
|
|
return tool.getDurability() + requiredAmount <= tool.getType().getMaxDurability();
|
2019-08-30 21:40:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean checkUnbreakingChance(int level) {
|
|
|
|
return (1.0 / (level + 1)) > random.nextDouble();
|
|
|
|
}
|
|
|
|
|
2018-11-06 04:33:10 +01:00
|
|
|
}
|