diff --git a/sakura-server/minecraft-patches/features/0014-Use-maxEntityCollision-limit-for-entity-retrieval.patch b/sakura-server/minecraft-patches/features/0014-Use-maxEntityCollision-limit-for-entity-retrieval.patch index ba1b1f7..bb12451 100644 --- a/sakura-server/minecraft-patches/features/0014-Use-maxEntityCollision-limit-for-entity-retrieval.patch +++ b/sakura-server/minecraft-patches/features/0014-Use-maxEntityCollision-limit-for-entity-retrieval.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Use maxEntityCollision limit for entity retrieval diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index d4276654fe855d0f73b8c02f5576b69f48c269dd..3634a31f8ab0930bd4a5e249b7686036b0948f20 100644 +index 60b6b19ad5c70991afd5152b45ff20ade457bcd1..70f9a4e4d33dc349404e84faa834613a2d9f2e40 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -3691,7 +3691,17 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3696,7 +3696,17 @@ public abstract class LivingEntity extends Entity implements Attackable { return; } // Paper end - don't run getEntities if we're not going to use its result diff --git a/sakura-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/sakura-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index ef7c265..2a23a45 100644 --- a/sakura-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/sakura-server/minecraft-patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -53,6 +53,31 @@ if (!flag) { this.indicateDamage(d, d1); } +@@ -1583,6 +_,11 @@ + if (itemBlockingWith == null) { + return false; + } else { ++ // Sakura start - shield damage reduction & allow blocking with swords ++ if (itemBlockingWith.getItem() instanceof me.samsuik.sakura.player.item.BlockableSwordItem swordItem && swordItem.isSafeToOverrideBlocking(itemBlockingWith)) { ++ return true; ++ } ++ // Sakura end - shield damage reduction & allow blocking with swords + BlocksAttacks blocksAttacks = itemBlockingWith.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks != null && !blocksAttacks.bypassedBy().map(damageSource::is).orElse(false)) { + if (damageSource.getDirectEntity() instanceof AbstractArrow abstractArrow && abstractArrow.getPierceLevel() > 0) { +@@ -1609,6 +_,12 @@ + acos = (float) Math.PI; + } + ++ // Sakura start - shield damage reduction & allow blocking with swords ++ if (me.samsuik.sakura.player.combat.CombatUtil.overrideBlockingAndHalveDamage(this.getItemBlockingWith(), this)) { ++ final boolean lookingAtSource = acos <= (float) (Math.PI / 180.0) * 90.0; ++ return lookingAtSource ? damageAmount * 0.5f : 0.0f; ++ } ++ // Sakura end - shield damage reduction & allow blocking with swords + BlocksAttacks blocksAttacks = this.getItemBlockingWith().get(DataComponents.BLOCKS_ATTACKS); + return blocksAttacks.resolveBlockedDamage(damageSource, damageAmount, acos); + } @@ -1676,7 +_,7 @@ } @@ -142,19 +167,6 @@ } return damageAmount; -@@ -2312,6 +_,12 @@ - amount += hardHatModifier; - - com.google.common.base.Function blocking = mod -> { -+ // Sakura start - shield damage reduction & allow blocking with swords -+ // todo: 1.21.5 update -+ if (LivingEntity.this.isBlockingWithSword() || LivingEntity.this.level().sakuraConfig().players.combat.shieldDamageReduction && !(damagesource.getDirectEntity() instanceof AbstractArrow)) { -+ return -(LivingEntity.this.isBlocking() ? mod * 0.5 : 0.0); -+ } -+ // Sakura end - shield damage reduction & allow blocking with swords - if (!LivingEntity.this.canBlockAttack(damagesource, mod.floatValue())) { - return 0D; - } @@ -2406,6 +_,12 @@ armorDamage += (float) event.getDamage(DamageModifier.BLOCKING); armorDamage += (float) event.getDamage(DamageModifier.FREEZING); @@ -189,22 +201,17 @@ this.hurtServer(serverLevel, this.damageSources().drown(), 1.0F); } } -@@ -4099,8 +_,16 @@ - } - - public boolean isBlocking() { -- return this.getItemBlockingWith() != null; -- } -+ // Sakura start - allow blocking with swords -+ return this.getItemBlockingWith() != null || this.isBlockingWithSword(); -+ } +@@ -4107,6 +_,13 @@ + if (!this.isUsingItem()) { + return null; + } else { ++ // Sakura start - allow blocking with swords ++ final ItemStack usingItem = this.useItem; ++ if (usingItem.getItem() instanceof me.samsuik.sakura.player.item.BlockableSwordItem swordItem && swordItem.isSafeToOverrideBlocking(usingItem)) { ++ return usingItem; ++ } ++ // Sakura end - allow blocking with swords + -+ public final boolean isBlockingWithSword() { -+ return this.isUsingItem() && !this.useItem.isEmpty() -+ && me.samsuik.sakura.configuration.GlobalConfiguration.get().players.combat.blockWithSwords -+ && this.useItem.getItem() instanceof me.samsuik.sakura.player.item.BlockableSwordItem; -+ } -+ // Sakura end - allow blocking with swords - - @Nullable - public ItemStack getItemBlockingWith() { + BlocksAttacks blocksAttacks = this.useItem.get(DataComponents.BLOCKS_ATTACKS); + if (blocksAttacks != null) { + int i = this.useItem.getItem().getUseDuration(this.useItem, this) - this.useItemRemaining; diff --git a/sakura-server/src/main/java/me/samsuik/sakura/player/combat/CombatUtil.java b/sakura-server/src/main/java/me/samsuik/sakura/player/combat/CombatUtil.java index e0aa768..302732f 100644 --- a/sakura-server/src/main/java/me/samsuik/sakura/player/combat/CombatUtil.java +++ b/sakura-server/src/main/java/me/samsuik/sakura/player/combat/CombatUtil.java @@ -1,5 +1,7 @@ package me.samsuik.sakura.player.combat; +import me.samsuik.sakura.player.item.BlockableSwordItem; +import me.samsuik.sakura.player.item.DataComponentHelper; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; import net.minecraft.core.RegistryAccess; @@ -23,6 +25,12 @@ import org.apache.commons.lang3.mutable.MutableFloat; import java.util.OptionalDouble; public final class CombatUtil { + public static boolean overrideBlockingAndHalveDamage(ItemStack stack, LivingEntity entity) { + return stack.getItem() instanceof BlockableSwordItem swordItem && swordItem.isSafeToOverrideBlocking(stack) + || stack.is(Items.SHIELD) && !DataComponentHelper.itemHasComponent(stack, DataComponents.BLOCKS_ATTACKS) + && entity.level().sakuraConfig().players.combat.shieldDamageReduction; + } + public static double getLegacyAttackDifference(ItemStack itemstack) { ItemAttributeModifiers defaultModifiers = itemstack.getItem().components().get(DataComponents.ATTRIBUTE_MODIFIERS); if (defaultModifiers != null && !defaultModifiers.modifiers().isEmpty()) { // exists diff --git a/sakura-server/src/main/java/me/samsuik/sakura/player/item/BlockableSwordItem.java b/sakura-server/src/main/java/me/samsuik/sakura/player/item/BlockableSwordItem.java index a5af7d2..2fde532 100644 --- a/sakura-server/src/main/java/me/samsuik/sakura/player/item/BlockableSwordItem.java +++ b/sakura-server/src/main/java/me/samsuik/sakura/player/item/BlockableSwordItem.java @@ -1,6 +1,7 @@ package me.samsuik.sakura.player.item; import me.samsuik.sakura.configuration.GlobalConfiguration; +import net.minecraft.core.component.DataComponentMap; import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.PatchedDataComponentMap; import net.minecraft.core.registries.BuiltInRegistries; @@ -17,7 +18,7 @@ import org.jspecify.annotations.NullMarked; @NullMarked public final class BlockableSwordItem extends Item { private static final Consumable BLOCKING_ANIMATION = Consumable.builder() - .consumeSeconds(720000) + .consumeSeconds(3600) .animation(ItemUseAnimation.BLOCK) .sound(BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.EMPTY)) .hasConsumeParticles(false) @@ -29,32 +30,40 @@ public final class BlockableSwordItem extends Item { @Override public void modifyComponentsSentToClient(PatchedDataComponentMap components) { - if (blockWithSwords()) { + if (hasCustomAnimationOrDisabled(components)) { + // When updating to 1.22 change CONSUMABLE to BLOCK_ATTACKS components.set(DataComponents.CONSUMABLE, BLOCKING_ANIMATION); } } @Override public InteractionResult use(Level level, Player player, InteractionHand hand) { - if (blockWithSwords()) { - ItemStack itemInHand = player.getItemInHand(hand); - return BLOCKING_ANIMATION.startConsuming(player, itemInHand, hand); + final ItemStack stack = player.getItemInHand(hand); + if (hasCustomAnimationOrDisabled(stack.getComponents())) { + return super.use(level, player, hand); + } else { + player.startUsingItem(hand); + return InteractionResult.CONSUME; } - return super.use(level, player, hand); - } - - @Override - public ItemUseAnimation getUseAnimation(ItemStack stack) { - return blockWithSwords() ? ItemUseAnimation.BLOCK : super.getUseAnimation(stack); } @Override public int getUseDuration(ItemStack stack, LivingEntity entity) { - return blockWithSwords() ? 720000 : super.getUseDuration(stack, entity); + if (hasCustomAnimationOrDisabled(stack.getComponents())) { + return super.getUseDuration(stack, entity); + } else { + return BLOCKING_ANIMATION.consumeTicks(); + } } - private static boolean blockWithSwords() { - GlobalConfiguration config = GlobalConfiguration.get(); - return config != null && config.players.combat.blockWithSwords; + public boolean isSafeToOverrideBlocking(ItemStack stack) { + return !hasCustomAnimationOrDisabled(stack.getComponents()); + } + + private static boolean hasCustomAnimationOrDisabled(DataComponentMap componentMap) { + final GlobalConfiguration config = GlobalConfiguration.get(); + return (config == null || !config.players.combat.blockWithSwords) + || componentMap.has(DataComponents.CONSUMABLE) + || componentMap.has(DataComponents.BLOCKS_ATTACKS); } } diff --git a/sakura-server/src/main/java/me/samsuik/sakura/player/item/DataComponentHelper.java b/sakura-server/src/main/java/me/samsuik/sakura/player/item/DataComponentHelper.java index 144cbeb..19b0bbc 100644 --- a/sakura-server/src/main/java/me/samsuik/sakura/player/item/DataComponentHelper.java +++ b/sakura-server/src/main/java/me/samsuik/sakura/player/item/DataComponentHelper.java @@ -2,7 +2,9 @@ package me.samsuik.sakura.player.item; import me.samsuik.sakura.configuration.GlobalConfiguration; import net.minecraft.core.component.DataComponentMap; +import net.minecraft.core.component.DataComponentType; import net.minecraft.core.component.DataComponents; +import net.minecraft.world.item.ItemStack; public final class DataComponentHelper { public static int bucketMaxStackSize() { @@ -10,6 +12,11 @@ public final class DataComponentHelper { return config == null || !config.players.bucketStackSize.isDefined() ? -1 : config.players.bucketStackSize.intValue(); } + @SuppressWarnings("OptionalAssignedToNull") + public static boolean itemHasComponent(ItemStack stack, DataComponentType component) { + return stack.getComponentsPatch().get(component) != null; + } + public static DataComponentMap copyComponentsAndModifyMaxStackSize(DataComponentMap componentMap, int maxItemSize) { if (maxItemSize > 0 && maxItemSize <= 99) { return DataComponentMap.builder() diff --git a/sakura-server/src/main/java/me/samsuik/sakura/player/item/LegacyGoldenAppleItem.java b/sakura-server/src/main/java/me/samsuik/sakura/player/item/LegacyGoldenAppleItem.java index 67b6868..2d1922a 100644 --- a/sakura-server/src/main/java/me/samsuik/sakura/player/item/LegacyGoldenAppleItem.java +++ b/sakura-server/src/main/java/me/samsuik/sakura/player/item/LegacyGoldenAppleItem.java @@ -16,10 +16,8 @@ import net.minecraft.world.level.Level; import org.jspecify.annotations.NullMarked; import java.util.List; -import java.util.Optional; @NullMarked -@SuppressWarnings("OptionalAssignedToNull") public final class LegacyGoldenAppleItem extends Item { private static final Consumable LEGACY_ENCHANTED_GOLDEN_APPLE = Consumables.defaultFood() .onConsume( @@ -40,8 +38,8 @@ public final class LegacyGoldenAppleItem extends Item { @Override public InteractionResult use(Level level, Player player, InteractionHand hand) { - ItemStack stack = player.getItemInHand(hand); - if (this.itemHasConsumableComponent(stack, level)) { + final ItemStack stack = player.getItemInHand(hand); + if (isItemConsumableOrDisabled(stack, level)) { return super.use(level, player, hand); } else { return LEGACY_ENCHANTED_GOLDEN_APPLE.startConsuming(player, stack, hand); @@ -50,15 +48,15 @@ public final class LegacyGoldenAppleItem extends Item { @Override public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity entity) { - if (this.itemHasConsumableComponent(stack, level)) { + if (isItemConsumableOrDisabled(stack, level)) { return super.finishUsingItem(stack, level, entity); } else { return LEGACY_ENCHANTED_GOLDEN_APPLE.onConsume(level, entity, stack); } } - private boolean itemHasConsumableComponent(ItemStack stack, Level level) { - Optional consumable = stack.getComponentsPatch().get(DataComponents.CONSUMABLE); - return consumable != null || !level.sakuraConfig().players.combat.oldEnchantedGoldenApple; + private static boolean isItemConsumableOrDisabled(ItemStack stack, Level level) { + return DataComponentHelper.itemHasComponent(stack, DataComponents.CONSUMABLE) + || !level.sakuraConfig().players.combat.oldEnchantedGoldenApple; } } diff --git a/sakura-server/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGuiItems.java b/sakura-server/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGuiItems.java index ca26410..6e335f8 100644 --- a/sakura-server/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGuiItems.java +++ b/sakura-server/src/main/java/me/samsuik/sakura/player/visibility/VisibilityGuiItems.java @@ -6,7 +6,7 @@ import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; import me.samsuik.sakura.player.gui.ItemStackUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.bukkit.Material; import org.bukkit.inventory.ItemStack;