From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com> Date: Mon, 2 Jun 2025 03:29:20 +0800 Subject: [PATCH] Old Blast Protection explosion knockback diff --git a/net/minecraft/world/entity/EquipmentSlot.java b/net/minecraft/world/entity/EquipmentSlot.java index 0a5611b1ece4dbe2887e7fbdef45f58e7f4d53ad..9f6fc274525f2fe4e4e35e0feaa410bf5d8eba04 100644 --- a/net/minecraft/world/entity/EquipmentSlot.java +++ b/net/minecraft/world/entity/EquipmentSlot.java @@ -21,6 +21,7 @@ public enum EquipmentSlot implements StringRepresentable { public static final int NO_COUNT_LIMIT = 0; public static final EquipmentSlot[] VALUES_ARRAY = values(); // Gale - JettPack - reduce array allocations public static final List VALUES = List.of(VALUES_ARRAY); // Gale - JettPack - reduce array allocations + public static final EquipmentSlot[] ARMOR_SLOTS = new EquipmentSlot[]{EquipmentSlot.HEAD, EquipmentSlot.CHEST, EquipmentSlot.LEGS, EquipmentSlot.FEET}; // Leaf - Old Blast Protection explosion knockback public static final IntFunction BY_ID = ByIdMap.continuous(equipmentSlot -> equipmentSlot.id, values(), ByIdMap.OutOfBoundsStrategy.ZERO); public static final StringRepresentable.EnumCodec CODEC = StringRepresentable.fromEnum(EquipmentSlot::values); public static final StreamCodec STREAM_CODEC = ByteBufCodecs.idMapper(BY_ID, equipmentSlot -> equipmentSlot.id); diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java index ea9c641fe9a9685307b6de2999ea4ff5342269b7..ae0dab1f8470cf53031a2ba776fa70d8ae074a87 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -532,7 +532,7 @@ public class ServerExplosion implements Explosion { double d4 = (1.0 - d) * f1 * knockbackMultiplier; double d5; if (entity instanceof LivingEntity livingEntity) { - d5 = entity instanceof Player && this.level.paperConfig().environment.disableExplosionKnockback ? 0 : d4 * (1.0 - livingEntity.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE)); // Paper + d5 = entity instanceof Player && this.level.paperConfig().environment.disableExplosionKnockback ? 0 : getExplosionKnockback(livingEntity, d4); // Paper // Leaf - Old Blast Protection explosion knockback } else { d5 = d4; } @@ -564,6 +564,49 @@ public class ServerExplosion implements Explosion { } } + // Leaf start - Old Blast Protection explosion knockback + private static double getExplosionKnockback(LivingEntity entity, double velocity) { + if (!org.dreeam.leaf.config.modules.gameplay.Knockback.oldBlastProtectionKnockbackBehavior) { + return velocity * (1.0 - entity.getAttributeValue(Attributes.EXPLOSION_KNOCKBACK_RESISTANCE)); + } + + // Old BLAST_PROTECTION logic + // BLAST_PROTECTION used ARMOR_SLOTS for slot types + // See 1.20.4's ProtectionEnchantment#getExplosionKnockbackAfterDampener, + // EnchantmentHelper#getEnchantmentLevel, Enchantment#getSlotItems, + // EnchantmentHelper#getItemEnchantmentLevel, Enchantments#BLAST_PROTECTION, + // these methods/fields for reference. + Map map = com.google.common.collect.Maps.newEnumMap(net.minecraft.world.entity.EquipmentSlot.class); + + for (net.minecraft.world.entity.EquipmentSlot slot : net.minecraft.world.entity.EquipmentSlot.ARMOR_SLOTS) { + ItemStack itemStack = entity.getItemBySlot(slot); + if (!itemStack.isEmpty()) { + map.put(slot, itemStack); + } + } + + Iterable items = map.values(); + int i = 0; + + if (items == null) { + return 0; + } + + for (ItemStack itemStack : items) { + int enchantmentLevel = net.minecraft.world.item.enchantment.EnchantmentHelper.getItemEnchantmentLevel(net.minecraft.world.item.enchantment.Enchantments.BLAST_PROTECTION, itemStack); + if (enchantmentLevel > i) { + i = enchantmentLevel; + } + } + + if (i > 0) { + velocity *= Mth.clamp(1.0 - (double) i * 0.15, 0.0, 1.0); + } + + return velocity; + } + // Leaf end - Old Blast Protection explosion knockback + private void interactWithBlocks(List blocks) { List list = new ArrayList<>(); Util.shuffle(blocks, this.level.random);