From 1e10276daeef47100245d250efb1f5d489d66ddf Mon Sep 17 00:00:00 2001 From: Carson Fleming Date: Mon, 20 Oct 2025 23:04:48 -0400 Subject: armor reinforcement + fix lightning fucketry --- .../mc/penguin_dust/exceptions/DustException.java | 7 -- .../penguin_dust/exceptions/MaterialException.java | 7 ++ .../mc/penguin_dust/listener/CraftingListener.java | 21 +++-- .../mc/penguin_dust/listener/DamageListener.java | 53 +++++++++++- .../mc/penguin_dust/listener/PlayerXPListener.java | 4 +- .../cflems/mc/penguin_dust/spells/Lightning.java | 2 + .../cflems/mc/penguin_dust/utils/DustUtils.java | 44 ---------- .../mc/penguin_dust/utils/MaterialUtils.java | 95 ++++++++++++++++++++++ .../cflems/mc/penguin_dust/utils/SpellUtils.java | 11 +-- 9 files changed, 176 insertions(+), 68 deletions(-) delete mode 100644 src/main/java/net/cflems/mc/penguin_dust/exceptions/DustException.java create mode 100644 src/main/java/net/cflems/mc/penguin_dust/exceptions/MaterialException.java delete mode 100644 src/main/java/net/cflems/mc/penguin_dust/utils/DustUtils.java create mode 100644 src/main/java/net/cflems/mc/penguin_dust/utils/MaterialUtils.java diff --git a/src/main/java/net/cflems/mc/penguin_dust/exceptions/DustException.java b/src/main/java/net/cflems/mc/penguin_dust/exceptions/DustException.java deleted file mode 100644 index 68907b6..0000000 --- a/src/main/java/net/cflems/mc/penguin_dust/exceptions/DustException.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.cflems.mc.penguin_dust.exceptions; - -public class DustException extends RuntimeException { - public DustException(String message) { - super(message); - } -} diff --git a/src/main/java/net/cflems/mc/penguin_dust/exceptions/MaterialException.java b/src/main/java/net/cflems/mc/penguin_dust/exceptions/MaterialException.java new file mode 100644 index 0000000..e11352c --- /dev/null +++ b/src/main/java/net/cflems/mc/penguin_dust/exceptions/MaterialException.java @@ -0,0 +1,7 @@ +package net.cflems.mc.penguin_dust.exceptions; + +public class MaterialException extends RuntimeException { + public MaterialException(String message) { + super(message); + } +} diff --git a/src/main/java/net/cflems/mc/penguin_dust/listener/CraftingListener.java b/src/main/java/net/cflems/mc/penguin_dust/listener/CraftingListener.java index cd6357d..2c04a12 100644 --- a/src/main/java/net/cflems/mc/penguin_dust/listener/CraftingListener.java +++ b/src/main/java/net/cflems/mc/penguin_dust/listener/CraftingListener.java @@ -1,7 +1,7 @@ package net.cflems.mc.penguin_dust.listener; import net.cflems.mc.penguin_dust.Spell; -import net.cflems.mc.penguin_dust.utils.DustUtils; +import net.cflems.mc.penguin_dust.utils.MaterialUtils; import net.cflems.mc.penguin_dust.utils.SpellUtils; import org.bukkit.Material; @@ -32,7 +32,7 @@ public final class CraftingListener implements Listener { copperIngotCount += item.getAmount(); break; case PUMPKIN_SEEDS: - if (DustUtils.isDust(item)) { + if (MaterialUtils.isDust(item)) { dustCount += item.getAmount(); break; } @@ -43,23 +43,30 @@ public final class CraftingListener implements Listener { } if (dustCount <= 0) return; - if (extraneousItem == null || (blazePowderCount > 0 && copperIngotCount > 0)) { + + boolean isWearable; + if (extraneousItem == null + || (blazePowderCount > 0 && copperIngotCount > 0) + || (isWearable = MaterialUtils.isWearable(extraneousItem)) + && (blazePowderCount > 0 || copperIngotCount > 0)) { craftingInventory.setResult(null); return; } ItemStack enchantedItem = extraneousItem.clone(); boolean success; - if (blazePowderCount > 0) { + if (isWearable) { + success = MaterialUtils.reinforceWithDust(enchantedItem, dustCount); + } else if (blazePowderCount > 0) { success = - SpellUtils.addSpell( + SpellUtils.imbueSpell( enchantedItem, Spell.FIREBALL, dustCount, Math.min(blazePowderCount, dustCount)); } else if (copperIngotCount > 0) { success = - SpellUtils.addSpell( + SpellUtils.imbueSpell( enchantedItem, Spell.LIGHTNING, dustCount, @@ -78,7 +85,7 @@ public final class CraftingListener implements Listener { int dustCount = 0; for (ItemStack stack : craftingInventory.getMatrix()) { - if (stack == null || !DustUtils.isDust(stack)) continue; + if (stack == null || !MaterialUtils.isDust(stack)) continue; dustCount += stack.getAmount(); stack.setAmount(0); } diff --git a/src/main/java/net/cflems/mc/penguin_dust/listener/DamageListener.java b/src/main/java/net/cflems/mc/penguin_dust/listener/DamageListener.java index a60a5e7..c1a48f8 100644 --- a/src/main/java/net/cflems/mc/penguin_dust/listener/DamageListener.java +++ b/src/main/java/net/cflems/mc/penguin_dust/listener/DamageListener.java @@ -4,23 +4,32 @@ import com.google.common.collect.MoreCollectors; import net.cflems.mc.penguin_dust.PenguinDust; import net.cflems.mc.penguin_dust.Spell; +import net.cflems.mc.penguin_dust.utils.MaterialUtils; import net.cflems.mc.penguin_dust.utils.SpellUtils; import org.bukkit.Bukkit; import org.bukkit.entity.Entity; import org.bukkit.entity.Fireball; import org.bukkit.entity.LightningStrike; +import org.bukkit.entity.LivingEntity; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.inventory.EntityEquipment; +import org.bukkit.inventory.ItemStack; import org.bukkit.metadata.MetadataValue; +import java.util.Arrays; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; public final class DamageListener implements Listener { - @EventHandler(priority = EventPriority.NORMAL) + @EventHandler(priority = EventPriority.HIGHEST) public void onEntityDamageByEntity(EntityDamageByEntityEvent event) { Entity damager = event.getDamager(); @@ -30,6 +39,7 @@ public final class DamageListener implements Listener { .filter(md -> md.getOwningPlugin() instanceof PenguinDust) .collect(MoreCollectors.toOptional()); if (strengthValue.isEmpty()) return; + int spellStrength = strengthValue.get().asInt(); Spell causingSpell = switch (damager) { @@ -45,8 +55,45 @@ public final class DamageListener implements Listener { return; } - double distance = event.getEntity().getLocation().distance(damager.getLocation()); - double damage = causingSpell.calculateDamage(strengthValue.get().asInt(), distance); + Entity damagee = event.getEntity(); + if (damagee instanceof LivingEntity livingDamagee) { + EntityEquipment damageeEquipment = livingDamagee.getEquipment(); + if (damageeEquipment != null) + spellStrength = consumeReinforcement(damageeEquipment, spellStrength); + } + + double distance = damagee.getLocation().distance(damager.getLocation()); + double damage = causingSpell.calculateDamage(spellStrength, distance); event.setDamage(damage); } + + private static int consumeReinforcement(EntityEquipment equipment, int damageToTake) { + Map magicArmor = + Arrays.stream(equipment.getArmorContents()) + .filter(Objects::nonNull) + .map(piece -> Map.entry(piece, MaterialUtils.getReinforcement(piece))) + .filter(entry -> entry.getValue() > 0) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + while (damageToTake > 0 && !magicArmor.isEmpty()) { + int fairShare = Math.ceilDiv(damageToTake, magicArmor.size()); + + Iterator> magicArmorIter = + magicArmor.entrySet().iterator(); + while (magicArmorIter.hasNext()) { + Map.Entry entry = magicArmorIter.next(); + if (fairShare >= entry.getValue()) { + damageToTake -= entry.getValue(); + entry.getKey().setAmount(0); + magicArmorIter.remove(); + } else { + damageToTake -= fairShare; + entry.setValue(entry.getValue() - fairShare); + } + } + } + + magicArmor.forEach(MaterialUtils::setReinforcement); + return damageToTake; + } } diff --git a/src/main/java/net/cflems/mc/penguin_dust/listener/PlayerXPListener.java b/src/main/java/net/cflems/mc/penguin_dust/listener/PlayerXPListener.java index 2ef7b6f..18f318f 100644 --- a/src/main/java/net/cflems/mc/penguin_dust/listener/PlayerXPListener.java +++ b/src/main/java/net/cflems/mc/penguin_dust/listener/PlayerXPListener.java @@ -1,6 +1,6 @@ package net.cflems.mc.penguin_dust.listener; -import net.cflems.mc.penguin_dust.utils.DustUtils; +import net.cflems.mc.penguin_dust.utils.MaterialUtils; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -15,7 +15,7 @@ public final class PlayerXPListener implements Listener { public void onPlayerExpChange(@NotNull PlayerExpChangeEvent event) { if (event.getAmount() < 1) return; - ItemStack dust = DustUtils.createDust(event.getAmount()); + ItemStack dust = MaterialUtils.createDust(event.getAmount()); event.getPlayer().getInventory().addItem(dust); } } diff --git a/src/main/java/net/cflems/mc/penguin_dust/spells/Lightning.java b/src/main/java/net/cflems/mc/penguin_dust/spells/Lightning.java index 6ad1dba..87bfc45 100644 --- a/src/main/java/net/cflems/mc/penguin_dust/spells/Lightning.java +++ b/src/main/java/net/cflems/mc/penguin_dust/spells/Lightning.java @@ -31,6 +31,8 @@ public final class Lightning implements SpellExecutor { LightningStrike lightningStrike = world.strikeLightning(rayTraceResult.getHitPosition().toLocation(world)); lightningStrike.setCausingPlayer(player); + lightningStrike.setLifeTicks(1); + lightningStrike.setFlashes(0); lightningStrike.setMetadata( SpellUtils.SPELL_STRENGTH_KEY, PenguinDust.createMetadataValue(strength)); diff --git a/src/main/java/net/cflems/mc/penguin_dust/utils/DustUtils.java b/src/main/java/net/cflems/mc/penguin_dust/utils/DustUtils.java deleted file mode 100644 index 55e06e5..0000000 --- a/src/main/java/net/cflems/mc/penguin_dust/utils/DustUtils.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.cflems.mc.penguin_dust.utils; - -import com.google.common.base.Preconditions; - -import net.cflems.mc.penguin_dust.exceptions.DustException; - -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.persistence.PersistentDataType; -import org.jetbrains.annotations.NotNull; - -public final class DustUtils { - private static final NamespacedKey IS_DUST_KEY = - Preconditions.checkNotNull(NamespacedKey.fromString("penguin-dust:is-penguin-dust")); - - private DustUtils() {} - - @NotNull - public static ItemStack createDust(int amount) { - if (amount <= 0) throw new DustException("Cannot have zero dust"); - - ItemStack base = new ItemStack(Material.PUMPKIN_SEEDS, amount); - ItemMeta meta = - Preconditions.checkNotNull( - base.getItemMeta(), "this plugin doesn't work if we can't set metadata"); - meta.setItemName("Penguin Dust"); - meta.getPersistentDataContainer().set(IS_DUST_KEY, PersistentDataType.BOOLEAN, true); - - if (!base.setItemMeta(meta)) throw new DustException("Failed to set dust metadata"); - return base; - } - - public static boolean isDust(@NotNull ItemStack itemStack) { - if (itemStack.getType() != Material.PUMPKIN_SEEDS) return false; - - ItemMeta meta = itemStack.getItemMeta(); - if (meta == null) return false; - - return meta.getPersistentDataContainer() - .getOrDefault(IS_DUST_KEY, PersistentDataType.BOOLEAN, false); - } -} diff --git a/src/main/java/net/cflems/mc/penguin_dust/utils/MaterialUtils.java b/src/main/java/net/cflems/mc/penguin_dust/utils/MaterialUtils.java new file mode 100644 index 0000000..fa5417e --- /dev/null +++ b/src/main/java/net/cflems/mc/penguin_dust/utils/MaterialUtils.java @@ -0,0 +1,95 @@ +package net.cflems.mc.penguin_dust.utils; + +import com.google.common.base.Preconditions; + +import net.cflems.mc.penguin_dust.exceptions.MaterialException; + +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ArmorMeta; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public final class MaterialUtils { + private static final NamespacedKey IS_DUST_KEY = + Preconditions.checkNotNull(NamespacedKey.fromString("penguin-dust:is-penguin-dust")); + private static final NamespacedKey REINFORCEMENT_KEY = + Preconditions.checkNotNull(NamespacedKey.fromString("penguin-dust:reinforcement")); + + private MaterialUtils() {} + + @NotNull + public static ItemStack createDust(int amount) { + if (amount <= 0) throw new MaterialException("Cannot have zero dust"); + + ItemStack base = new ItemStack(Material.PUMPKIN_SEEDS, amount); + ItemMeta meta = + Preconditions.checkNotNull( + base.getItemMeta(), "this plugin doesn't work if we can't set metadata"); + meta.setItemName("Penguin Dust"); + meta.getPersistentDataContainer().set(IS_DUST_KEY, PersistentDataType.BOOLEAN, true); + + if (!base.setItemMeta(meta)) throw new MaterialException("Failed to set dust metadata"); + return base; + } + + public static boolean isDust(@NotNull ItemStack itemStack) { + if (itemStack.getType() != Material.PUMPKIN_SEEDS) return false; + + ItemMeta meta = itemStack.getItemMeta(); + if (meta == null) return false; + + return meta.getPersistentDataContainer() + .getOrDefault(IS_DUST_KEY, PersistentDataType.BOOLEAN, false); + } + + public static boolean isWearable(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + return meta != null + && (meta instanceof ArmorMeta || itemStack.getType() == Material.CARVED_PUMPKIN); + } + + public static boolean reinforceWithDust(@NotNull ItemStack itemStack, int amount) { + ItemMeta meta = itemStack.getItemMeta(); + if (meta == null) return false; + + PersistentDataContainer persistentDataContainer = meta.getPersistentDataContainer(); + amount += + persistentDataContainer.getOrDefault( + REINFORCEMENT_KEY, PersistentDataType.INTEGER, 0); + persistentDataContainer.set(REINFORCEMENT_KEY, PersistentDataType.INTEGER, amount); + setReinforcementLore(meta, amount); + + return itemStack.setItemMeta(meta); + } + + public static int getReinforcement(@NotNull ItemStack itemStack) { + ItemMeta meta = itemStack.getItemMeta(); + if (meta == null) return 0; + + return meta.getPersistentDataContainer() + .getOrDefault(REINFORCEMENT_KEY, PersistentDataType.INTEGER, 0); + } + + public static void setReinforcement(@NotNull ItemStack itemStack, int amount) { + ItemMeta meta = itemStack.getItemMeta(); + if (meta == null) throw new MaterialException("Could not set reinforcement data"); + + meta.getPersistentDataContainer() + .set(REINFORCEMENT_KEY, PersistentDataType.INTEGER, amount); + setReinforcementLore(meta, amount); + + if (!itemStack.setItemMeta(meta)) + throw new MaterialException("Could not set reinforcement data"); + } + + private static void setReinforcementLore(@NotNull ItemMeta meta, int amount) { + if (amount > 0) meta.setLore(List.of("Reinforced with: " + amount + " Dust")); + else meta.setLore(null); + } +} diff --git a/src/main/java/net/cflems/mc/penguin_dust/utils/SpellUtils.java b/src/main/java/net/cflems/mc/penguin_dust/utils/SpellUtils.java index 333bcd2..55092d5 100644 --- a/src/main/java/net/cflems/mc/penguin_dust/utils/SpellUtils.java +++ b/src/main/java/net/cflems/mc/penguin_dust/utils/SpellUtils.java @@ -52,7 +52,7 @@ public final class SpellUtils { PersistentDataType.INTEGER, newRemainingCapacity); - setLore( + setImbuementLore( meta, spellData.spell, spellData.throughput, @@ -66,7 +66,7 @@ public final class SpellUtils { return true; } - public static boolean addSpell( + public static boolean imbueSpell( @NotNull ItemStack itemStack, @NotNull Spell spell, int maxCapacity, int throughput) { ItemMeta meta = itemStack.getItemMeta(); if (meta == null) return false; @@ -79,7 +79,7 @@ public final class SpellUtils { SPELL_MAX_CAPACITY_KEY, PersistentDataType.INTEGER, maxCapacity); persistentDataContainer.set(SPELL_THROUGHPUT_KEY, PersistentDataType.INTEGER, throughput); - setLore(meta, spell, throughput, maxCapacity, maxCapacity); + setImbuementLore(meta, spell, throughput, maxCapacity, maxCapacity); return itemStack.setItemMeta(meta); } @@ -99,7 +99,8 @@ public final class SpellUtils { persistentDataContainer.set( SPELL_MAX_CAPACITY_KEY, PersistentDataType.INTEGER, newMaxCapacity); - setLore(meta, spellData.spell, spellData.throughput, newRemainingCapacity, newMaxCapacity); + setImbuementLore( + meta, spellData.spell, spellData.throughput, newRemainingCapacity, newMaxCapacity); return itemStack.setItemMeta(meta); } @@ -130,7 +131,7 @@ public final class SpellUtils { return new SpellData(spell, throughput, remainingCapacity, maxCapacity); } - private static void setLore( + private static void setImbuementLore( @NotNull ItemMeta meta, @NotNull Spell spell, int throughput, -- cgit v1.2.3