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",