From ef2a8d1157e8a1497133bf08b7088c7c29345a96 Mon Sep 17 00:00:00 2001 From: Swedz Date: Fri, 27 Dec 2024 05:06:42 -0500 Subject: [PATCH 1/3] Use new NeoForge attribute API for quantum armor, quantum sword and gravichestplate --- gradle.properties | 4 +- .../modern_industrialization/lang/en_us.json | 3 +- .../aztech/modern_industrialization/MI.java | 17 +++++ .../MIRegistries.java | 11 +++ .../modern_industrialization/MIText.java | 3 +- .../attributes/DisplayNamedAttribute.java | 72 +++++++++++++++++++ .../attributes/InfiniteDamageAttribute.java | 46 ++++++++++++ .../attributes/QuantumArmorAttribute.java | 46 ++++++++++++ .../items/armor/GraviChestPlateItem.java | 16 +---- .../items/armor/MIArmorEffects.java | 11 ++- .../items/armor/QuantumArmorItem.java | 44 ++++-------- .../items/tools/QuantumSword.java | 41 +++++------ .../mixin/ItemStackMixin.java | 58 --------------- .../modern_industrialization.mixins.json | 3 +- 14 files changed, 233 insertions(+), 142 deletions(-) create mode 100644 src/main/java/aztech/modern_industrialization/attributes/DisplayNamedAttribute.java create mode 100644 src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java create mode 100644 src/main/java/aztech/modern_industrialization/attributes/QuantumArmorAttribute.java delete mode 100644 src/main/java/aztech/modern_industrialization/mixin/ItemStackMixin.java diff --git a/gradle.properties b/gradle.properties index ce8cb1dd4..c9c317ee3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,8 +9,8 @@ org.gradle.jvmargs=-Xmx2G \ # Core NeoForge properties minecraft_version=1.21.1 -neo_version=21.1.37 -neo_version_range=[21.1.37, 22-) +neo_version=21.1.60 +neo_version_range=[21.1.60, 22-) # For latest see https://parchmentmc.org/docs/getting-started neoForge.parchment.minecraftVersion=1.21 neoForge.parchment.mappingsVersion=2024.07.28 diff --git a/src/generated/resources/assets/modern_industrialization/lang/en_us.json b/src/generated/resources/assets/modern_industrialization/lang/en_us.json index 5484ae970..c28008e3c 100644 --- a/src/generated/resources/assets/modern_industrialization/lang/en_us.json +++ b/src/generated/resources/assets/modern_industrialization/lang/en_us.json @@ -1500,7 +1500,8 @@ "text.modern_industrialization.AcceptsSteamToo": "Also Accepts Steam (1 mb \u003d 1 EU)", "text.modern_industrialization.AcceptsUpgrades": "Add upgrades to increase max processing EU/t.", "text.modern_industrialization.Activated": "Activated", - "text.modern_industrialization.AllowCreativeFlight": "Allow Creative Flight", + "text.modern_industrialization.AttributeInfiniteDamage": "Infinite Damage", + "text.modern_industrialization.AttributeQuantumArmor": "Quantum Armor", "text.modern_industrialization.BarrelStack": "Can store up to %d stacks", "text.modern_industrialization.BarrelStorageComponent": "%s / %s (%s)", "text.modern_industrialization.BaseDurationSeconds": "%s sec", diff --git a/src/main/java/aztech/modern_industrialization/MI.java b/src/main/java/aztech/modern_industrialization/MI.java index 9e8f50405..e43bb381b 100644 --- a/src/main/java/aztech/modern_industrialization/MI.java +++ b/src/main/java/aztech/modern_industrialization/MI.java @@ -66,6 +66,8 @@ import net.minecraft.server.packs.repository.PackCompatibility; import net.minecraft.server.packs.repository.PackSource; import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.flag.FeatureFlagSet; import net.minecraft.world.inventory.AnvilMenu; import net.minecraft.world.item.ItemStack; @@ -80,6 +82,8 @@ import net.neoforged.neoforge.event.AddPackFindersEvent; import net.neoforged.neoforge.event.AnvilUpdateEvent; import net.neoforged.neoforge.event.RegisterGameTestsEvent; +import net.neoforged.neoforge.event.entity.EntityAttributeModificationEvent; +import net.neoforged.neoforge.event.entity.living.LivingIncomingDamageEvent; import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent; import net.neoforged.neoforge.event.village.VillagerTradesEvent; @@ -174,6 +178,19 @@ public MI(IEventBus modBus, Dist dist) { } }); + modBus.addListener(EntityAttributeModificationEvent.class, event -> { + for (EntityType entityType : event.getTypes()) { + event.add(entityType, MIRegistries.QUANTUM_ARMOR); + event.add(entityType, MIRegistries.INFINITE_DAMAGE); + } + }); + NeoForge.EVENT_BUS.addListener(LivingIncomingDamageEvent.class, event -> { + if (event.getSource().getDirectEntity() instanceof LivingEntity damager + && damager.getAttributeValue(MIRegistries.INFINITE_DAMAGE) > 0) { + event.setAmount((float) Integer.MAX_VALUE); + } + }); + modBus.addListener(FMLCommonSetupEvent.class, event -> { MIBlock.BLOCK_DEFINITIONS.values().forEach(BlockDefinition::onRegister); MIItem.ITEM_DEFINITIONS.values().forEach(ItemDefinition::onRegister); diff --git a/src/main/java/aztech/modern_industrialization/MIRegistries.java b/src/main/java/aztech/modern_industrialization/MIRegistries.java index e55c8d513..fb72180d0 100644 --- a/src/main/java/aztech/modern_industrialization/MIRegistries.java +++ b/src/main/java/aztech/modern_industrialization/MIRegistries.java @@ -23,6 +23,8 @@ */ package aztech.modern_industrialization; +import aztech.modern_industrialization.attributes.InfiniteDamageAttribute; +import aztech.modern_industrialization.attributes.QuantumArmorAttribute; import aztech.modern_industrialization.blocks.creativestorageunit.CreativeStorageUnitBlockEntity; import aztech.modern_industrialization.blocks.forgehammer.ForgeHammerRecipe; import aztech.modern_industrialization.blocks.forgehammer.ForgeHammerScreenHandler; @@ -39,6 +41,7 @@ import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.entity.ai.attributes.Attribute; import net.minecraft.world.entity.ai.village.poi.PoiType; import net.minecraft.world.entity.npc.VillagerProfession; import net.minecraft.world.flag.FeatureFlags; @@ -135,6 +138,13 @@ public class MIRegistries { SoundEvents.VILLAGER_WORK_TOOLSMITH); }); + // Attributes + public static final DeferredRegister ATTRIBUTES = DeferredRegister.create(Registries.ATTRIBUTE, MI.ID); + + public static final Holder QUANTUM_ARMOR = ATTRIBUTES.register("quantum_armor", () -> new QuantumArmorAttribute().setSyncable(true)); + public static final Holder INFINITE_DAMAGE = ATTRIBUTES.register("infinite_damage", + () -> new InfiniteDamageAttribute().setSyncable(true)); + static void init(IEventBus modBus) { BLOCK_ENTITIES.register(modBus); CONDITIONS.register(modBus); @@ -144,5 +154,6 @@ static void init(IEventBus modBus) { RECIPE_TYPES.register(modBus); TABS.register(modBus); VILLAGER_PROFESSIONS.register(modBus); + ATTRIBUTES.register(modBus); } } diff --git a/src/main/java/aztech/modern_industrialization/MIText.java b/src/main/java/aztech/modern_industrialization/MIText.java index b5aa0d440..d55d273dd 100644 --- a/src/main/java/aztech/modern_industrialization/MIText.java +++ b/src/main/java/aztech/modern_industrialization/MIText.java @@ -45,8 +45,9 @@ public enum MIText { AcceptsSteam("Accepts Steam (1 mb = 1 EU)"), AcceptsSteamToo("Also Accepts Steam (1 mb = 1 EU)"), AcceptsUpgrades("Add upgrades to increase max processing EU/t."), - AllowCreativeFlight("Allow Creative Flight"), Activated("Activated"), + AttributeInfiniteDamage("Infinite Damage"), + AttributeQuantumArmor("Quantum Armor"), BarrelStack("Can store up to %d stacks"), BarrelStorageComponent("%s / %s (%s)"), BaseDurationSeconds("%s sec"), diff --git a/src/main/java/aztech/modern_industrialization/attributes/DisplayNamedAttribute.java b/src/main/java/aztech/modern_industrialization/attributes/DisplayNamedAttribute.java new file mode 100644 index 000000000..c8a470002 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/attributes/DisplayNamedAttribute.java @@ -0,0 +1,72 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.attributes; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.entity.ai.attributes.Attribute; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.item.TooltipFlag; + +public abstract class DisplayNamedAttribute extends Attribute { + protected DisplayNamedAttribute(String descriptionId, double defaultValue) { + super(descriptionId, defaultValue); + } + + public abstract String getDisplayDescriptionId(); + + /* + * The below two methods are copied from IAttributeExtension and use DisplayAttribute#getDisplayDescriptionId so that Attribute#getDescriptionId + * can return the MIText.AttributeQuantumArmor description id. This is desirable because when using the /attribute command it will display the + * attribute name as "Quantum Armor" instead of just "Armor" like it does when using "attribute.name.generic.armor" as the description id (or + * "Infinite Damage" instead of just "Damage" for the InfiniteDamageAttribute). + */ + + @Override + public MutableComponent toComponent(AttributeModifier modif, TooltipFlag flag) { + double value = modif.amount(); + String key = value > 0 ? "neoforge.modifier.plus" : "neoforge.modifier.take"; + ChatFormatting color = this.getStyle(value > 0); + + Component attrDesc = Component.translatable(this.getDisplayDescriptionId()); + Component valueComp = this.toValueComponent(modif.operation(), value, flag); + MutableComponent comp = Component.translatable(key, valueComp, attrDesc).withStyle(color); + + return comp.append(this.getDebugInfo(modif, flag)); + } + + @Override + public MutableComponent toBaseComponent(double value, double entityBase, boolean merged, TooltipFlag flag) { + MutableComponent comp = Component.translatable("attribute.modifier.equals.0", FORMAT.format(value), + Component.translatable(this.getDisplayDescriptionId())); + if (flag.isAdvanced() && !merged) { + Component debugInfo = Component.literal(" ") + .append(Component.translatable("neoforge.attribute.debug.base", FORMAT.format(entityBase), FORMAT.format(value - entityBase)) + .withStyle(ChatFormatting.GRAY)); + comp.append(debugInfo); + } + return comp; + } +} diff --git a/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java b/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java new file mode 100644 index 000000000..054f4550d --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java @@ -0,0 +1,46 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.attributes; + +import aztech.modern_industrialization.MIText; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.item.TooltipFlag; + +public class InfiniteDamageAttribute extends DisplayNamedAttribute { + public InfiniteDamageAttribute() { + super(MIText.AttributeInfiniteDamage.getTranslationKey(), 0); + } + + @Override + public MutableComponent toValueComponent(AttributeModifier.Operation operation, double value, TooltipFlag flag) { + return Component.literal("\u221e"); + } + + @Override + public String getDisplayDescriptionId() { + return "attribute.name.generic.attack_damage"; + } +} diff --git a/src/main/java/aztech/modern_industrialization/attributes/QuantumArmorAttribute.java b/src/main/java/aztech/modern_industrialization/attributes/QuantumArmorAttribute.java new file mode 100644 index 000000000..db371e305 --- /dev/null +++ b/src/main/java/aztech/modern_industrialization/attributes/QuantumArmorAttribute.java @@ -0,0 +1,46 @@ +/* + * MIT License + * + * Copyright (c) 2020 Azercoco & Technici4n + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package aztech.modern_industrialization.attributes; + +import aztech.modern_industrialization.MIText; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; +import net.minecraft.world.item.TooltipFlag; + +public class QuantumArmorAttribute extends DisplayNamedAttribute { + public QuantumArmorAttribute() { + super(MIText.AttributeQuantumArmor.getTranslationKey(), 0); + } + + @Override + public MutableComponent toValueComponent(AttributeModifier.Operation operation, double value, TooltipFlag flag) { + return Component.literal("\u00B9\u2044\u2084 |\u221E> + \u00B3\u2044\u2084 |0>"); + } + + @Override + public String getDisplayDescriptionId() { + return "attribute.name.generic.armor"; + } +} diff --git a/src/main/java/aztech/modern_industrialization/items/armor/GraviChestPlateItem.java b/src/main/java/aztech/modern_industrialization/items/armor/GraviChestPlateItem.java index 70c7ce141..f13ab4697 100644 --- a/src/main/java/aztech/modern_industrialization/items/armor/GraviChestPlateItem.java +++ b/src/main/java/aztech/modern_industrialization/items/armor/GraviChestPlateItem.java @@ -25,23 +25,17 @@ import aztech.modern_industrialization.MI; import aztech.modern_industrialization.MIComponents; -import aztech.modern_industrialization.MIText; import aztech.modern_industrialization.items.ActivatableItem; import dev.technici4n.grandpower.api.ISimpleEnergyItem; -import java.util.List; -import net.minecraft.ChatFormatting; import net.minecraft.core.component.DataComponentType; -import net.minecraft.network.chat.Component; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ArmorItem; -import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Rarity; -import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.component.ItemAttributeModifiers; import net.minecraft.world.level.Level; import net.neoforged.neoforge.common.NeoForgeMod; @@ -60,8 +54,7 @@ public ItemAttributeModifiers getDefaultAttributeModifiers(ItemStack stack) { NeoForgeMod.CREATIVE_FLIGHT, new AttributeModifier(MI.id("gravichestplate_flight"), 1, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.CHEST) - .build() - .withTooltip(false); + .build(); } return ItemAttributeModifiers.EMPTY; } @@ -117,11 +110,4 @@ public long getEnergyMaxInput(ItemStack stack) { public long getEnergyMaxOutput(ItemStack stack) { return 0; } - - @Override - public void appendHoverText(ItemStack stack, Item.TooltipContext context, List list, TooltipFlag flag) { - list.add(Component.empty()); - list.add(Component.translatable("item.modifiers." + getType().getSlot().getName()).withStyle(ChatFormatting.GRAY)); - list.add(MIText.AllowCreativeFlight.text().withStyle(ChatFormatting.BLUE)); - } } diff --git a/src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java b/src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java index 09a18d46b..47ad0bd4f 100644 --- a/src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java +++ b/src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java @@ -24,6 +24,7 @@ package aztech.modern_industrialization.items.armor; import aztech.modern_industrialization.MIItem; +import aztech.modern_industrialization.MIRegistries; import java.util.concurrent.ThreadLocalRandom; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.EquipmentSlot; @@ -37,13 +38,9 @@ private MIArmorEffects() { } public static boolean quantumArmorPreventsDamage(LivingEntity entity) { - int parts = 0; - for (QuantumArmorItem item : QuantumArmorItem.ITEMS) { - if (entity.getItemBySlot(item.getType().getSlot()).getItem() == item) { - parts++; - } - } - return ThreadLocalRandom.current().nextDouble() < parts / 4d; + var attribute = entity.getAttribute(MIRegistries.QUANTUM_ARMOR); + int parts = attribute != null ? (int) attribute.getValue() : 0; + return parts >= 4 || ThreadLocalRandom.current().nextDouble() < parts / 4d; } public static boolean canTankFlyIntoWall(ItemStack helmet) { diff --git a/src/main/java/aztech/modern_industrialization/items/armor/QuantumArmorItem.java b/src/main/java/aztech/modern_industrialization/items/armor/QuantumArmorItem.java index cf20de041..b054da83d 100644 --- a/src/main/java/aztech/modern_industrialization/items/armor/QuantumArmorItem.java +++ b/src/main/java/aztech/modern_industrialization/items/armor/QuantumArmorItem.java @@ -24,52 +24,32 @@ package aztech.modern_industrialization.items.armor; import aztech.modern_industrialization.MI; -import aztech.modern_industrialization.MIText; -import java.util.ArrayList; -import java.util.List; -import net.minecraft.ChatFormatting; -import net.minecraft.network.chat.Component; +import aztech.modern_industrialization.MIRegistries; import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.item.ArmorItem; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.item.component.ItemAttributeModifiers; import net.neoforged.neoforge.common.NeoForgeMod; public class QuantumArmorItem extends ArmorItem { - public static final List ITEMS = new ArrayList<>(); - public QuantumArmorItem(ArmorItem.Type type, Properties settings) { super(MIArmorMaterials.QUANTUM, type, settings.stacksTo(1)); - ITEMS.add(this); } @Override public ItemAttributeModifiers getDefaultAttributeModifiers() { + var builder = ItemAttributeModifiers.builder() + .add( + MIRegistries.QUANTUM_ARMOR, + // This needs a unique name for each armor piece or else the value of one piece will override the others + new AttributeModifier(MI.id("quantum_armor_%s".formatted(type.getName())), 1, AttributeModifier.Operation.ADD_VALUE), + EquipmentSlotGroup.bySlot(type.getSlot())); if (type == Type.CHESTPLATE) { - return ItemAttributeModifiers.builder() - .add( - NeoForgeMod.CREATIVE_FLIGHT, - new AttributeModifier(MI.id("quantum_flight"), 1, AttributeModifier.Operation.ADD_VALUE), - EquipmentSlotGroup.CHEST) - .build() - .withTooltip(false); - } else { - return ItemAttributeModifiers.EMPTY; - } - } - - @Override - public void appendHoverText(ItemStack stack, Item.TooltipContext context, List list, TooltipFlag flag) { - list.add(Component.empty()); - list.add(Component.translatable("item.modifiers." + getType().getSlot().getName()).withStyle(ChatFormatting.GRAY)); - String oneQuarterInfinity = " \u00B9\u2044\u2084 |\u221E> + \u00B3\u2044\u2084 |0>"; - list.add(Component.translatable("attribute.modifier.plus.0", oneQuarterInfinity, Component.translatable("attribute.name.generic.armor")) - .withStyle(ChatFormatting.BLUE)); - if (type == Type.CHESTPLATE) { - list.add(MIText.AllowCreativeFlight.text().withStyle(ChatFormatting.BLUE)); + builder.add( + NeoForgeMod.CREATIVE_FLIGHT, + new AttributeModifier(MI.id("quantum_flight"), 1, AttributeModifier.Operation.ADD_VALUE), + EquipmentSlotGroup.CHEST); } + return builder.build(); } } diff --git a/src/main/java/aztech/modern_industrialization/items/tools/QuantumSword.java b/src/main/java/aztech/modern_industrialization/items/tools/QuantumSword.java index 78a805dc4..d2166632d 100644 --- a/src/main/java/aztech/modern_industrialization/items/tools/QuantumSword.java +++ b/src/main/java/aztech/modern_industrialization/items/tools/QuantumSword.java @@ -23,16 +23,16 @@ */ package aztech.modern_industrialization.items.tools; -import java.util.List; -import net.minecraft.ChatFormatting; +import aztech.modern_industrialization.MI; +import aztech.modern_industrialization.MIRegistries; import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.item.component.ItemAttributeModifiers; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; @@ -41,33 +41,26 @@ public QuantumSword(Properties settings) { super(settings); } - private void onHurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) { - var damageSources = attacker.level().damageSources(); - // Note: Don't use Float.MAX_VALUE, calculations using it might produce infinite or NaN values. - target.hurt(new DamageSource(damageSources.genericKill().typeHolder(), attacker), (float) Integer.MAX_VALUE); - - // TODO: if lama was hit, kill the wander trader (and the opposite) and give an - // advancement - // TODO: same for phantoms + @Override + public ItemAttributeModifiers getDefaultAttributeModifiers() { + return ItemAttributeModifiers.builder() + .add( + MIRegistries.INFINITE_DAMAGE, + new AttributeModifier(MI.id("infinite_damage"), 1, AttributeModifier.Operation.ADD_VALUE), + EquipmentSlotGroup.MAINHAND) + .build(); } @Override public boolean hurtEnemy(ItemStack pStack, LivingEntity pTarget, LivingEntity pAttacker) { - onHurtEnemy(pStack, pTarget, pAttacker); - return true; + // TODO: if lama was hit, kill the wander trader (and the opposite) and give an + // advancement + // TODO: same for phantoms + return false; } @Override public boolean canAttackBlock(BlockState state, Level level, BlockPos pos, Player player) { return !player.isCreative(); } - - @Override - public void appendHoverText(ItemStack stack, Item.TooltipContext context, List list, TooltipFlag flag) { - list.add(Component.empty()); - list.add(Component.translatable("item.modifiers.mainhand").withStyle(ChatFormatting.GRAY)); - String infinity = "\u221e"; - list.add(Component.translatable("attribute.modifier.plus.0", infinity, Component.translatable("attribute.name.generic.attack_damage")) - .withStyle(ChatFormatting.BLUE)); - } } diff --git a/src/main/java/aztech/modern_industrialization/mixin/ItemStackMixin.java b/src/main/java/aztech/modern_industrialization/mixin/ItemStackMixin.java deleted file mode 100644 index eb9960fc2..000000000 --- a/src/main/java/aztech/modern_industrialization/mixin/ItemStackMixin.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * MIT License - * - * Copyright (c) 2020 Azercoco & Technici4n - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package aztech.modern_industrialization.mixin; - -import aztech.modern_industrialization.items.armor.GraviChestPlateItem; -import aztech.modern_industrialization.items.armor.QuantumArmorItem; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import java.util.function.Consumer; -import net.minecraft.core.component.DataComponentType; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.component.ItemAttributeModifiers; -import net.neoforged.neoforge.common.extensions.IItemStackExtension; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -/** - * When overriding {@link Item#getDefaultAttributeModifiers(ItemStack)} and creating an {@link ItemAttributeModifiers} instance and using - * {@link ItemAttributeModifiers#withTooltip(boolean)} (false as the input) and the item doesn't have an attribute component, it will - * still display the defaulted attribute. This is because {@link ItemStack#addAttributeTooltips(Consumer, Player)} directly uses - * {@link ItemStack#getOrDefault(DataComponentType, Object)} to get the item attribute modifiers rather than - * {@link IItemStackExtension#getAttributeModifiers()}. Despite the comment in the code saying otherwise, this is the cause of the issue. - *
- *
- * This is a workaround for an issue in NeoForge. This fix is only applied to the relevant items (GraviChestplate & Quantum Armor). - */ -@Mixin(ItemStack.class) -public class ItemStackMixin { - @WrapOperation(method = "addAttributeTooltips", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;getOrDefault(Lnet/minecraft/core/component/DataComponentType;Ljava/lang/Object;)Ljava/lang/Object;")) - private Object addAttributeTooltips(ItemStack instance, DataComponentType dataComponentType, Object defaultValue, Operation original) { - Item item = instance.getItem(); - return item instanceof GraviChestPlateItem || item instanceof QuantumArmorItem ? instance.getAttributeModifiers() - : original.call(instance, dataComponentType, defaultValue); - } -} diff --git a/src/main/resources/modern_industrialization.mixins.json b/src/main/resources/modern_industrialization.mixins.json index a46448f5b..ae150daac 100644 --- a/src/main/resources/modern_industrialization.mixins.json +++ b/src/main/resources/modern_industrialization.mixins.json @@ -4,8 +4,7 @@ "package": "aztech.modern_industrialization.mixin", "compatibilityLevel": "JAVA_8", "mixins": [ - "BlockStateBaseMixin", - "ItemStackMixin" + "BlockStateBaseMixin" ], "injectors": { "defaultRequire": 1 From 3bfa66c8cf91bb0e5344022521155f4f87859174 Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Thu, 2 Jan 2025 10:30:24 +0100 Subject: [PATCH 2/3] PR Tweaks --- .../aztech/modern_industrialization/MI.java | 3 +- .../attributes/DisplayNamedAttribute.java | 23 ++++--------- .../attributes/InfiniteDamageAttribute.java | 32 +++++++++++++++++-- .../attributes/QuantumArmorAttribute.java | 2 +- .../items/armor/MIArmorEffects.java | 5 ++- .../items/armor/QuantumArmorItem.java | 5 ++- .../items/tools/QuantumSword.java | 16 ++++------ 7 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/MI.java b/src/main/java/aztech/modern_industrialization/MI.java index e43bb381b..eab1cb919 100644 --- a/src/main/java/aztech/modern_industrialization/MI.java +++ b/src/main/java/aztech/modern_industrialization/MI.java @@ -65,6 +65,7 @@ import net.minecraft.server.packs.repository.Pack; import net.minecraft.server.packs.repository.PackCompatibility; import net.minecraft.server.packs.repository.PackSource; +import net.minecraft.util.Mth; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; @@ -186,7 +187,7 @@ public MI(IEventBus modBus, Dist dist) { }); NeoForge.EVENT_BUS.addListener(LivingIncomingDamageEvent.class, event -> { if (event.getSource().getDirectEntity() instanceof LivingEntity damager - && damager.getAttributeValue(MIRegistries.INFINITE_DAMAGE) > 0) { + && damager.getAttributeValue(MIRegistries.INFINITE_DAMAGE) > Mth.EPSILON) { event.setAmount((float) Integer.MAX_VALUE); } }); diff --git a/src/main/java/aztech/modern_industrialization/attributes/DisplayNamedAttribute.java b/src/main/java/aztech/modern_industrialization/attributes/DisplayNamedAttribute.java index c8a470002..861195f08 100644 --- a/src/main/java/aztech/modern_industrialization/attributes/DisplayNamedAttribute.java +++ b/src/main/java/aztech/modern_industrialization/attributes/DisplayNamedAttribute.java @@ -35,10 +35,14 @@ protected DisplayNamedAttribute(String descriptionId, double defaultValue) { super(descriptionId, defaultValue); } - public abstract String getDisplayDescriptionId(); + /** + * Translation key to use in tooltips, thanks to our override of {@link #toComponent(AttributeModifier, TooltipFlag)}. + * {@link #getDescriptionId()} is still used in /attribute commands and other contexts. + */ + public abstract String getTooltipDescriptionId(); /* - * The below two methods are copied from IAttributeExtension and use DisplayAttribute#getDisplayDescriptionId so that Attribute#getDescriptionId + * The below methods is copied from IAttributeExtension and uses DisplayAttribute#getDisplayDescriptionId so that Attribute#getDescriptionId * can return the MIText.AttributeQuantumArmor description id. This is desirable because when using the /attribute command it will display the * attribute name as "Quantum Armor" instead of just "Armor" like it does when using "attribute.name.generic.armor" as the description id (or * "Infinite Damage" instead of just "Damage" for the InfiniteDamageAttribute). @@ -50,23 +54,10 @@ public MutableComponent toComponent(AttributeModifier modif, TooltipFlag flag) { String key = value > 0 ? "neoforge.modifier.plus" : "neoforge.modifier.take"; ChatFormatting color = this.getStyle(value > 0); - Component attrDesc = Component.translatable(this.getDisplayDescriptionId()); + Component attrDesc = Component.translatable(this.getTooltipDescriptionId()); Component valueComp = this.toValueComponent(modif.operation(), value, flag); MutableComponent comp = Component.translatable(key, valueComp, attrDesc).withStyle(color); return comp.append(this.getDebugInfo(modif, flag)); } - - @Override - public MutableComponent toBaseComponent(double value, double entityBase, boolean merged, TooltipFlag flag) { - MutableComponent comp = Component.translatable("attribute.modifier.equals.0", FORMAT.format(value), - Component.translatable(this.getDisplayDescriptionId())); - if (flag.isAdvanced() && !merged) { - Component debugInfo = Component.literal(" ") - .append(Component.translatable("neoforge.attribute.debug.base", FORMAT.format(entityBase), FORMAT.format(value - entityBase)) - .withStyle(ChatFormatting.GRAY)); - comp.append(debugInfo); - } - return comp; - } } diff --git a/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java b/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java index 054f4550d..d2b7e9243 100644 --- a/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java +++ b/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java @@ -24,23 +24,51 @@ package aztech.modern_industrialization.attributes; import aztech.modern_industrialization.MIText; +import aztech.modern_industrialization.items.tools.QuantumSword; +import net.minecraft.ChatFormatting; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.item.TooltipFlag; +import org.jetbrains.annotations.Nullable; public class InfiniteDamageAttribute extends DisplayNamedAttribute { + private static final String INFINITY = "\u221e"; + public InfiniteDamageAttribute() { super(MIText.AttributeInfiniteDamage.getTranslationKey(), 0); } + // Allows a modifier with the base id to render green with the effective value. + // Other modifiers still render blue with the additional value. + @Override + public @Nullable ResourceLocation getBaseId() { + return QuantumSword.BASE_INFINITE_DAMAGE; + } + @Override public MutableComponent toValueComponent(AttributeModifier.Operation operation, double value, TooltipFlag flag) { - return Component.literal("\u221e"); + return Component.literal(INFINITY); + } + + @Override + public MutableComponent toBaseComponent(double value, double entityBase, boolean merged, TooltipFlag flag) { + String stringValue = value > Mth.EPSILON ? INFINITY : FORMAT.format(0); + MutableComponent comp = Component.translatable("attribute.modifier.equals.0", stringValue, + Component.translatable(this.getTooltipDescriptionId())); + if (flag.isAdvanced() && !merged) { + Component debugInfo = Component.literal(" ") + .append(Component.translatable("neoforge.attribute.debug.base", FORMAT.format(entityBase), FORMAT.format(value - entityBase)) + .withStyle(ChatFormatting.GRAY)); + comp.append(debugInfo); + } + return comp; } @Override - public String getDisplayDescriptionId() { + public String getTooltipDescriptionId() { return "attribute.name.generic.attack_damage"; } } diff --git a/src/main/java/aztech/modern_industrialization/attributes/QuantumArmorAttribute.java b/src/main/java/aztech/modern_industrialization/attributes/QuantumArmorAttribute.java index db371e305..f22ab8a6b 100644 --- a/src/main/java/aztech/modern_industrialization/attributes/QuantumArmorAttribute.java +++ b/src/main/java/aztech/modern_industrialization/attributes/QuantumArmorAttribute.java @@ -40,7 +40,7 @@ public MutableComponent toValueComponent(AttributeModifier.Operation operation, } @Override - public String getDisplayDescriptionId() { + public String getTooltipDescriptionId() { return "attribute.name.generic.armor"; } } diff --git a/src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java b/src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java index 47ad0bd4f..8d0581ebf 100644 --- a/src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java +++ b/src/main/java/aztech/modern_industrialization/items/armor/MIArmorEffects.java @@ -38,9 +38,8 @@ private MIArmorEffects() { } public static boolean quantumArmorPreventsDamage(LivingEntity entity) { - var attribute = entity.getAttribute(MIRegistries.QUANTUM_ARMOR); - int parts = attribute != null ? (int) attribute.getValue() : 0; - return parts >= 4 || ThreadLocalRandom.current().nextDouble() < parts / 4d; + double parts = entity.getAttributeValue(MIRegistries.QUANTUM_ARMOR); + return ThreadLocalRandom.current().nextDouble() < parts / 4d; } public static boolean canTankFlyIntoWall(ItemStack helmet) { diff --git a/src/main/java/aztech/modern_industrialization/items/armor/QuantumArmorItem.java b/src/main/java/aztech/modern_industrialization/items/armor/QuantumArmorItem.java index b054da83d..602940161 100644 --- a/src/main/java/aztech/modern_industrialization/items/armor/QuantumArmorItem.java +++ b/src/main/java/aztech/modern_industrialization/items/armor/QuantumArmorItem.java @@ -33,11 +33,10 @@ public class QuantumArmorItem extends ArmorItem { public QuantumArmorItem(ArmorItem.Type type, Properties settings) { - super(MIArmorMaterials.QUANTUM, type, settings.stacksTo(1)); + super(MIArmorMaterials.QUANTUM, type, settings.stacksTo(1).attributes(buildModifiers(type))); } - @Override - public ItemAttributeModifiers getDefaultAttributeModifiers() { + private static ItemAttributeModifiers buildModifiers(ArmorItem.Type type) { var builder = ItemAttributeModifiers.builder() .add( MIRegistries.QUANTUM_ARMOR, diff --git a/src/main/java/aztech/modern_industrialization/items/tools/QuantumSword.java b/src/main/java/aztech/modern_industrialization/items/tools/QuantumSword.java index d2166632d..7fee35050 100644 --- a/src/main/java/aztech/modern_industrialization/items/tools/QuantumSword.java +++ b/src/main/java/aztech/modern_industrialization/items/tools/QuantumSword.java @@ -26,6 +26,7 @@ import aztech.modern_industrialization.MI; import aztech.modern_industrialization.MIRegistries; import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.entity.EquipmentSlotGroup; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.ai.attributes.AttributeModifier; @@ -37,18 +38,15 @@ import net.minecraft.world.level.block.state.BlockState; public class QuantumSword extends Item { - public QuantumSword(Properties settings) { - super(settings); - } + public static final ResourceLocation BASE_INFINITE_DAMAGE = MI.id("base_infinite_damage"); - @Override - public ItemAttributeModifiers getDefaultAttributeModifiers() { - return ItemAttributeModifiers.builder() + public QuantumSword(Properties settings) { + super(settings.attributes(ItemAttributeModifiers.builder() .add( MIRegistries.INFINITE_DAMAGE, - new AttributeModifier(MI.id("infinite_damage"), 1, AttributeModifier.Operation.ADD_VALUE), + new AttributeModifier(BASE_INFINITE_DAMAGE, 1, AttributeModifier.Operation.ADD_VALUE), EquipmentSlotGroup.MAINHAND) - .build(); + .build())); } @Override @@ -56,7 +54,7 @@ public boolean hurtEnemy(ItemStack pStack, LivingEntity pTarget, LivingEntity pA // TODO: if lama was hit, kill the wander trader (and the opposite) and give an // advancement // TODO: same for phantoms - return false; + return true; } @Override From fde954ebcdce5e755dfb9b2e29cf98b55db407f1 Mon Sep 17 00:00:00 2001 From: Technici4n <13494793+Technici4n@users.noreply.github.com> Date: Thu, 2 Jan 2025 10:32:22 +0100 Subject: [PATCH 3/3] Remove nullable --- .../attributes/InfiniteDamageAttribute.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java b/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java index d2b7e9243..379b234e8 100644 --- a/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java +++ b/src/main/java/aztech/modern_industrialization/attributes/InfiniteDamageAttribute.java @@ -32,7 +32,6 @@ import net.minecraft.util.Mth; import net.minecraft.world.entity.ai.attributes.AttributeModifier; import net.minecraft.world.item.TooltipFlag; -import org.jetbrains.annotations.Nullable; public class InfiniteDamageAttribute extends DisplayNamedAttribute { private static final String INFINITY = "\u221e"; @@ -44,7 +43,7 @@ public InfiniteDamageAttribute() { // Allows a modifier with the base id to render green with the effective value. // Other modifiers still render blue with the additional value. @Override - public @Nullable ResourceLocation getBaseId() { + public ResourceLocation getBaseId() { return QuantumSword.BASE_INFINITE_DAMAGE; }