From c2e3caa73b2b6899b57798338e45507e15099063 Mon Sep 17 00:00:00 2001 From: haykam821 <24855774+haykam821@users.noreply.github.com> Date: Tue, 28 Jan 2025 00:26:13 -0500 Subject: [PATCH] Add sword blocking to old combat --- .../plasmid/api/game/common/OldCombat.java | 28 ++++++- .../xyz/nucleoid/plasmid/impl/Plasmid.java | 3 + .../component/PlasmidDataComponentTypes.java | 26 +++++++ .../mixin/game/common/LivingEntityMixin.java | 75 +++++++++++++++++++ src/main/resources/plasmid.mixins.json | 1 + 5 files changed, 130 insertions(+), 3 deletions(-) create mode 100644 src/main/java/xyz/nucleoid/plasmid/impl/component/PlasmidDataComponentTypes.java create mode 100644 src/main/java/xyz/nucleoid/plasmid/mixin/game/common/LivingEntityMixin.java diff --git a/src/main/java/xyz/nucleoid/plasmid/api/game/common/OldCombat.java b/src/main/java/xyz/nucleoid/plasmid/api/game/common/OldCombat.java index 25441d60..d6c7a052 100644 --- a/src/main/java/xyz/nucleoid/plasmid/api/game/common/OldCombat.java +++ b/src/main/java/xyz/nucleoid/plasmid/api/game/common/OldCombat.java @@ -2,17 +2,23 @@ import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.AttributeModifierSlot; +import net.minecraft.component.type.ConsumableComponent; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttributeModifier; import net.minecraft.entity.attribute.EntityAttributes; import net.minecraft.item.*; +import net.minecraft.item.consume.UseAction; import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.sound.SoundEvents; import net.minecraft.util.Identifier; +import net.minecraft.util.Unit; +import xyz.nucleoid.plasmid.impl.component.PlasmidDataComponentTypes; /** * A utility class that allows old-style 1.8 combat to be applied to any given {@link ItemStack}. *

* This works by modifying the damage and attack speed attributes to match their 1.8 levels. + * In addition, sword blocking is reinstated. */ public final class OldCombat { private static final RegistryEntry DAMAGE_ATTRIBUTE = EntityAttributes.ATTACK_DAMAGE; @@ -37,14 +43,31 @@ public final class OldCombat { private static final int SWORD_BASE_DAMAGE = 3; public static ItemStack applyTo(ItemStack stack) { + stack.set(PlasmidDataComponentTypes.OLD_COMBAT, Unit.INSTANCE); + + if (stack.getItem() instanceof SwordItem) { + stack.set(DataComponentTypes.CONSUMABLE, ConsumableComponent.builder() + .consumeSeconds(Float.MAX_VALUE) + .useAction(UseAction.BLOCK) + .sound(RegistryEntry.of(SoundEvents.INTENTIONALLY_EMPTY)) + .consumeParticles(false) + .build()); + } + + applyAttributeModifiersTo(stack); + + return stack; + } + + private static void applyAttributeModifiersTo(ItemStack stack) { if (!stack.contains(DataComponentTypes.TOOL)) { - return stack; + return; } var material = getToolMaterial(stack); if (material == null) { - return stack; + return; } var defaultModifiers = stack.get(DataComponentTypes.ATTRIBUTE_MODIFIERS); @@ -63,7 +86,6 @@ public static ItemStack applyTo(ItemStack stack) { } stack.set(DataComponentTypes.ATTRIBUTE_MODIFIERS, defaultModifiers); - return stack; } private static EntityAttributeModifier createSpeedModifier() { diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/Plasmid.java b/src/main/java/xyz/nucleoid/plasmid/impl/Plasmid.java index f3095520..4f62a026 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/Plasmid.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/Plasmid.java @@ -39,6 +39,7 @@ import xyz.nucleoid.plasmid.impl.portal.game.SingleGamePortalConfig; import xyz.nucleoid.plasmid.impl.command.*; import xyz.nucleoid.plasmid.impl.compatibility.TrinketsCompatibility; +import xyz.nucleoid.plasmid.impl.component.PlasmidDataComponentTypes; import xyz.nucleoid.plasmid.impl.portal.menu.*; public final class Plasmid implements ModInitializer { @@ -67,6 +68,8 @@ public void onInitialize() { throw new GameOpenException(Text.translatable("text.plasmid.map.open.invalid_game", id != null ? id.toString() : context.game())); }); + PlasmidDataComponentTypes.register(); + this.registerCallbacks(); if (FabricLoader.getInstance().isModLoaded("trinkets")) { diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/component/PlasmidDataComponentTypes.java b/src/main/java/xyz/nucleoid/plasmid/impl/component/PlasmidDataComponentTypes.java new file mode 100644 index 00000000..724b37dd --- /dev/null +++ b/src/main/java/xyz/nucleoid/plasmid/impl/component/PlasmidDataComponentTypes.java @@ -0,0 +1,26 @@ +package xyz.nucleoid.plasmid.impl.component; + +import eu.pb4.polymer.core.api.other.PolymerComponent; +import net.minecraft.component.ComponentType; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; +import net.minecraft.util.Unit; +import xyz.nucleoid.plasmid.impl.Plasmid; + +public final class PlasmidDataComponentTypes { + private PlasmidDataComponentTypes() { + } + + public static final ComponentType OLD_COMBAT = register("old_combat", ComponentType.builder() + .codec(Unit.CODEC) + .build()); + + private static ComponentType register(String path, ComponentType type) { + return Registry.register(Registries.DATA_COMPONENT_TYPE, Identifier.of(Plasmid.ID, path), type); + } + + public static void register() { + PolymerComponent.registerDataComponent(OLD_COMBAT); + } +} diff --git a/src/main/java/xyz/nucleoid/plasmid/mixin/game/common/LivingEntityMixin.java b/src/main/java/xyz/nucleoid/plasmid/mixin/game/common/LivingEntityMixin.java new file mode 100644 index 00000000..c458d577 --- /dev/null +++ b/src/main/java/xyz/nucleoid/plasmid/mixin/game/common/LivingEntityMixin.java @@ -0,0 +1,75 @@ +package xyz.nucleoid.plasmid.mixin.game.common; + +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.ref.LocalFloatRef; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.item.ShieldItem; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; +import xyz.nucleoid.plasmid.impl.component.PlasmidDataComponentTypes; + +@Mixin(LivingEntity.class) +public class LivingEntityMixin { + @Shadow + @Final + private ItemStack activeItemStack; + + @WrapOperation( + method = "blockedByShield", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;getItem()Lnet/minecraft/item/Item;" + ) + ) + private Item allowOldCombatSwordBlocking(ItemStack stack, Operation operation) { + // Allow fulfilling the instanceof ShieldItem check + if (stack.contains(PlasmidDataComponentTypes.OLD_COMBAT)) { + return Items.SHIELD; + } + + return operation.call(stack); + } + + @WrapOperation( + method = "damage", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/LivingEntity;blockedByShield(Lnet/minecraft/entity/damage/DamageSource;)Z" + ) + ) + private boolean applyHalfDamageFromSwordBlocking(LivingEntity entity, DamageSource source, Operation operation, @Local(ordinal = 0, argsOnly = true) LocalFloatRef amount) { + if (operation.call(entity, source)) { + ItemStack stack = entity.getBlockingItem(); + + if (!stack.contains(PlasmidDataComponentTypes.OLD_COMBAT) || stack.getItem() instanceof ShieldItem) { + return true; + } + + amount.set(Math.max(0, (amount.get() / 2) - 0.5f)); + } + + return false; + } + + @ModifyConstant( + method = "getBlockingItem", + constant = @Constant(intValue = 5) + ) + private int allowInstantSwordBlocking(int original) { + if (!this.activeItemStack.contains(PlasmidDataComponentTypes.OLD_COMBAT) || this.activeItemStack.getItem() instanceof ShieldItem) { + return original; + } + + return 0; + } +} diff --git a/src/main/resources/plasmid.mixins.json b/src/main/resources/plasmid.mixins.json index abb31506..134e35bc 100644 --- a/src/main/resources/plasmid.mixins.json +++ b/src/main/resources/plasmid.mixins.json @@ -8,6 +8,7 @@ "chat.PlayerEntityMixin", "chat.PlayerListS2CPacketEntryAccessor", "chat.ServerPlayerEntityMixin", + "game.common.LivingEntityMixin", "game.portal.EntityMixin", "game.portal.SignBlockEntityMixin", "game.rule.EquippableComponentMixin",