From 4621d39a87b6c61763e7274a3b9c98dd0ad90447 Mon Sep 17 00:00:00 2001 From: Louis Caron Date: Tue, 15 Apr 2025 15:37:57 -0400 Subject: [PATCH 1/2] separation of AncientWillContainer and TerrasteelHelmItem --- .../integration/rei/BotaniaREIPlugin.java | 3 +- .../fabric/mixin/PlayerFabricMixin.java | 4 +- .../neoforge/ForgeCommonInitializer.java | 11 +-- .../api/item/AncientWillContainer.java | 85 ++++++++++++++++- .../integration/emi/AncientWillEmiRecipe.java | 2 +- .../crafting/AncientWillRecipeWrapper.java | 2 +- .../render/entity/TerrasteelHelmetLayer.java | 3 +- .../crafting/recipe/AncientWillRecipe.java | 4 +- .../armor/terrasteel/TerrasteelHelmItem.java | 91 +------------------ .../vazkii/botania/mixin/PlayerMixin.java | 4 +- 10 files changed, 103 insertions(+), 106 deletions(-) diff --git a/Fabric/src/main/java/vazkii/botania/fabric/integration/rei/BotaniaREIPlugin.java b/Fabric/src/main/java/vazkii/botania/fabric/integration/rei/BotaniaREIPlugin.java index e36f7f672c..720d65e730 100644 --- a/Fabric/src/main/java/vazkii/botania/fabric/integration/rei/BotaniaREIPlugin.java +++ b/Fabric/src/main/java/vazkii/botania/fabric/integration/rei/BotaniaREIPlugin.java @@ -151,14 +151,13 @@ void registerAncientWillRecipeWrapper(DisplayRegistry helper) { ImmutableList.Builder input = ImmutableList.builder(); ImmutableList.Builder> output = ImmutableList.builder(); Set wills = ImmutableSet.of(new ItemStack(BotaniaItems.ancientWillAhrim), new ItemStack(BotaniaItems.ancientWillDharok), new ItemStack(BotaniaItems.ancientWillGuthan), new ItemStack(BotaniaItems.ancientWillKaril), new ItemStack(BotaniaItems.ancientWillTorag), new ItemStack(BotaniaItems.ancientWillVerac)); - AncientWillContainer container = (AncientWillContainer) BotaniaItems.terrasteelHelm; ItemStack helmet = new ItemStack(BotaniaItems.terrasteelHelm); input.add(EntryIngredients.of(helmet)); input.add(EntryIngredients.ofItemStacks(wills)); for (ItemStack will : wills) { ItemStack copy = helmet.copy(); - container.addAncientWill(copy, ((AncientWillItem) will.getItem()).type); + AncientWillContainer.addAncientWill(copy, ((AncientWillItem) will.getItem()).type); output.add(EntryStacks.of(copy)); } helper.add(new DefaultCustomDisplay(null, input.build(), Collections.singletonList(EntryIngredient.of(output.build())))); diff --git a/Fabric/src/main/java/vazkii/botania/fabric/mixin/PlayerFabricMixin.java b/Fabric/src/main/java/vazkii/botania/fabric/mixin/PlayerFabricMixin.java index c2b2256ecf..4aab98b9db 100644 --- a/Fabric/src/main/java/vazkii/botania/fabric/mixin/PlayerFabricMixin.java +++ b/Fabric/src/main/java/vazkii/botania/fabric/mixin/PlayerFabricMixin.java @@ -33,10 +33,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.invoke.arg.Args; +import vazkii.botania.api.item.AncientWillContainer; import vazkii.botania.common.PlayerAccess; import vazkii.botania.common.handler.EquipmentHandler; import vazkii.botania.common.handler.PixieHandler; -import vazkii.botania.common.item.equipment.armor.terrasteel.TerrasteelHelmItem; import vazkii.botania.common.item.equipment.bauble.*; @Mixin(Player.class) @@ -112,7 +112,7 @@ private float cushionFall(float originalDist) { private float onCritMul(float f, Entity target) { if (target instanceof LivingEntity living) { ((PlayerAccess) this).botania$setCritTarget(living); - return f * TerrasteelHelmItem.getCritDamageMult((Player) (Object) this); + return f * AncientWillContainer.getCritDamageMult((Player) (Object) this); } return f; } diff --git a/NeoForge/src/main/java/vazkii/botania/neoforge/ForgeCommonInitializer.java b/NeoForge/src/main/java/vazkii/botania/neoforge/ForgeCommonInitializer.java index fc28117f6e..92df5bdc35 100644 --- a/NeoForge/src/main/java/vazkii/botania/neoforge/ForgeCommonInitializer.java +++ b/NeoForge/src/main/java/vazkii/botania/neoforge/ForgeCommonInitializer.java @@ -20,6 +20,7 @@ import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.monster.EnderMan; @@ -67,10 +68,7 @@ import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.BotaniaForgeCapabilities; import vazkii.botania.api.BotaniaRegistries; -import vazkii.botania.api.item.AvatarWieldable; -import vazkii.botania.api.item.BlockProvider; -import vazkii.botania.api.item.CoordBoundItem; -import vazkii.botania.api.item.Relic; +import vazkii.botania.api.item.*; import vazkii.botania.api.mana.*; import vazkii.botania.client.fx.BotaniaParticles; import vazkii.botania.common.BotaniaStats; @@ -107,7 +105,6 @@ import vazkii.botania.common.impl.mana.DefaultManaItemImpl; import vazkii.botania.common.integration.corporea.CorporeaNodeDetectors; import vazkii.botania.common.item.*; -import vazkii.botania.common.item.equipment.armor.terrasteel.TerrasteelHelmItem; import vazkii.botania.common.item.equipment.bauble.*; import vazkii.botania.common.item.equipment.tool.terrasteel.TerraBladeItem; import vazkii.botania.common.item.equipment.tool.terrasteel.TerraTruncatorItem; @@ -431,11 +428,11 @@ private void registerEvents() { bus.addListener(EventPriority.LOW, (CriticalHitEvent e) -> { if (e.getEntity().level().isClientSide || !e.isCriticalHit() - || !TerrasteelHelmItem.hasTerraArmorSet(e.getEntity()) + || !(e.getEntity().getItemBySlot(EquipmentSlot.HEAD).getItem() instanceof AncientWillContainer awc && awc.hasFullArmorSet(e.getEntity())) || !(e.getTarget() instanceof LivingEntity target)) { return; } - e.setDamageMultiplier(e.getDamageMultiplier() * TerrasteelHelmItem.getCritDamageMult(e.getEntity())); + e.setDamageMultiplier(e.getDamageMultiplier() * AncientWillContainer.getCritDamageMult(e.getEntity())); ((PlayerAccess) e.getEntity()).botania$setCritTarget(target); }); diff --git a/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java b/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java index 68e4b7d783..03c9e74459 100644 --- a/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java +++ b/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java @@ -8,7 +8,20 @@ */ package vazkii.botania.api.item; +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import org.jetbrains.annotations.Unmodifiable; +import vazkii.botania.common.BotaniaDamageTypes; +import vazkii.botania.common.component.BotaniaDataComponents; + +import java.util.*; /** * An item that implements this can have Ancient Wills @@ -24,8 +37,76 @@ enum AncientWillType { KARIL } - void addAncientWill(ItemStack stack, AncientWillType will); + static void addAncientWill(ItemStack stack, AncientWillType will) { + Set setOfWills = new TreeSet<>(getAncientWillsList(stack)); + setOfWills.add(getWillId(will)); + stack.set(BotaniaDataComponents.ANCIENT_WILLS, new ArrayList<>(setOfWills)); + } + + private static String getWillId(AncientWillType will) { + return will.name().toLowerCase(Locale.ROOT); + } + + @Unmodifiable + private static List getAncientWillsList(ItemStack stack) { + return stack.getOrDefault(BotaniaDataComponents.ANCIENT_WILLS, Collections.emptyList()); + } + + static boolean hasAncientWill(ItemStack stack, AncientWillType will) { + return getAncientWillsList(stack).contains(getWillId(will)); + } + + static float getCritDamageMult(Player player) { + ItemStack stack = player.getItemBySlot(EquipmentSlot.HEAD); + if (stack.getItem() instanceof AncientWillContainer awc && awc.hasFullArmorSet(player)) { + if (!stack.isEmpty() && AncientWillContainer.hasAncientWill(stack, AncientWillType.DHAROK)) { + return 1.0F + (1.0F - player.getHealth() / player.getMaxHealth()) * 0.5F; + } + } - boolean hasAncientWill(ItemStack stack, AncientWillType will); + return 1.0F; + } + + static boolean hasAnyWill(ItemStack stack) { + for (AncientWillType type : AncientWillType.values()) { + if (AncientWillContainer.hasAncientWill(stack, type)) { + return true; + } + } + + return false; + } + + static DamageSource onEntityAttacked(DamageSource source, float amount, Player player, LivingEntity entity) { + ItemStack stack = player.getItemBySlot(EquipmentSlot.HEAD); + if (stack.getItem() instanceof AncientWillContainer awc && awc.hasFullArmorSet(player)) { + // TODO: might be worth refactoring this to only get the set of wills once + if (AncientWillContainer.hasAncientWill(stack, AncientWillType.AHRIM)) { + entity.addEffect(new MobEffectInstance(MobEffects.WEAKNESS, 20, 1)); + } + if (AncientWillContainer.hasAncientWill(stack, AncientWillType.GUTHAN)) { + player.heal(amount * 0.25F); + } + if (AncientWillContainer.hasAncientWill(stack, AncientWillType.TORAG)) { + entity.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 60, 1)); + } + if (AncientWillContainer.hasAncientWill(stack, AncientWillType.VERAC)) { + source = BotaniaDamageTypes.Sources.playerAttackArmorPiercing(player.level().registryAccess(), player); + } + if (AncientWillContainer.hasAncientWill(stack, AncientWillType.KARIL)) { + entity.addEffect(new MobEffectInstance(MobEffects.WITHER, 60, 1)); + } + } + return source; + } + + static void addAncientWillDescription(ItemStack stack, List list){ + for (AncientWillType type : AncientWillType.values()) { + if (hasAncientWill(stack, type)) { + list.add(Component.translatable("botania.armorset.will_" + type.name().toLowerCase(Locale.ROOT) + ".desc").withStyle(ChatFormatting.GRAY)); + } + } + } + boolean hasFullArmorSet(Player player); } diff --git a/Xplat/src/main/java/vazkii/botania/client/integration/emi/AncientWillEmiRecipe.java b/Xplat/src/main/java/vazkii/botania/client/integration/emi/AncientWillEmiRecipe.java index 72f0f4e8a9..34c970278c 100644 --- a/Xplat/src/main/java/vazkii/botania/client/integration/emi/AncientWillEmiRecipe.java +++ b/Xplat/src/main/java/vazkii/botania/client/integration/emi/AncientWillEmiRecipe.java @@ -39,7 +39,7 @@ public SlotWidget getOutputWidget(int x, int y) { return new GeneratedSlotWidget(r -> { ItemStack stack = container.getItemStack().copy(); ItemStack will = wills.get(r.nextInt(wills.size())).getItemStack().copy(); - ((AncientWillContainer) stack.getItem()).addAncientWill(stack, ((AncientWillItem) will.getItem()).type); + AncientWillContainer.addAncientWill(stack, ((AncientWillItem) will.getItem()).type); return EmiStack.of(stack); }, unique, x, y); } diff --git a/Xplat/src/main/java/vazkii/botania/client/integration/jei/crafting/AncientWillRecipeWrapper.java b/Xplat/src/main/java/vazkii/botania/client/integration/jei/crafting/AncientWillRecipeWrapper.java index 2700e572bf..23d930e4a9 100644 --- a/Xplat/src/main/java/vazkii/botania/client/integration/jei/crafting/AncientWillRecipeWrapper.java +++ b/Xplat/src/main/java/vazkii/botania/client/integration/jei/crafting/AncientWillRecipeWrapper.java @@ -47,7 +47,7 @@ public void setRecipe(RecipeHolder recipe, IRecipeLayoutBuild var outputStacks = new ArrayList(); for (var will : !foci.isEmpty() ? foci : willStacks) { var stack = new ItemStack(BotaniaItems.terrasteelHelm); - ((AncientWillContainer) stack.getItem()).addAncientWill(stack, ((AncientWillItem) will.getItem()).type); + AncientWillContainer.addAncientWill(stack, ((AncientWillItem) will.getItem()).type); outputStacks.add(stack); } diff --git a/Xplat/src/main/java/vazkii/botania/client/render/entity/TerrasteelHelmetLayer.java b/Xplat/src/main/java/vazkii/botania/client/render/entity/TerrasteelHelmetLayer.java index 1441556962..61d80095cc 100644 --- a/Xplat/src/main/java/vazkii/botania/client/render/entity/TerrasteelHelmetLayer.java +++ b/Xplat/src/main/java/vazkii/botania/client/render/entity/TerrasteelHelmetLayer.java @@ -23,6 +23,7 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.item.ItemStack; +import vazkii.botania.api.item.AncientWillContainer; import vazkii.botania.client.core.handler.MiscellaneousModels; import vazkii.botania.common.item.equipment.armor.terrasteel.TerrasteelHelmItem; @@ -35,7 +36,7 @@ public TerrasteelHelmetLayer(RenderLayerParent 0 && food < 18 && player.isHurt() && player.tickCount % 80 == 0) { player.heal(1F); @@ -59,83 +47,14 @@ public float getDiscount(ItemStack stack, int slot, Player player, @Nullable Ite return hasArmorSet(player) ? 0.2F : 0F; } - @Override - public void addAncientWill(ItemStack stack, AncientWillType will) { - Set setOfWills = new TreeSet<>(getAncientWillsList(stack)); - setOfWills.add(getWillId(will)); - stack.set(BotaniaDataComponents.ANCIENT_WILLS, new ArrayList<>(setOfWills)); - } - - private static String getWillId(AncientWillType will) { - return will.name().toLowerCase(Locale.ROOT); - } - - @Override - public boolean hasAncientWill(ItemStack stack, AncientWillType will) { - return hasAncientWill_(stack, will); - } - - private static boolean hasAncientWill_(ItemStack stack, AncientWillType will) { - return getAncientWillsList(stack).contains(getWillId(will)); - } - - @Unmodifiable - private static List getAncientWillsList(ItemStack stack) { - return stack.getOrDefault(BotaniaDataComponents.ANCIENT_WILLS, Collections.emptyList()); - } - @Override public void addArmorSetDescription(ItemStack stack, List list) { super.addArmorSetDescription(stack, list); - for (AncientWillType type : AncientWillType.values()) { - if (hasAncientWill(stack, type)) { - list.add(Component.translatable("botania.armorset.will_" + getWillId(type) + ".desc").withStyle(ChatFormatting.GRAY)); - } - } - } - - public static boolean hasAnyWill(ItemStack stack) { - return !getAncientWillsList(stack).isEmpty(); + AncientWillContainer.addAncientWillDescription(stack, list); } - public static boolean hasTerraArmorSet(Player player) { - return ((TerrasteelHelmItem) BotaniaItems.terrasteelHelm).hasArmorSet(player); - } - - public static float getCritDamageMult(Player player) { - if (hasTerraArmorSet(player)) { - ItemStack stack = player.getItemBySlot(EquipmentSlot.HEAD); - if (!stack.isEmpty() && stack.getItem() instanceof TerrasteelHelmItem - && hasAncientWill_(stack, AncientWillType.DHAROK)) { - return 1F + (1F - player.getHealth() / player.getMaxHealth()) * 0.5F; - } - } - return 1.0F; - } - - public static DamageSource onEntityAttacked(DamageSource source, float amount, Player player, LivingEntity entity) { - if (hasTerraArmorSet(player)) { - ItemStack stack = player.getItemBySlot(EquipmentSlot.HEAD); - if (!stack.isEmpty() && stack.getItem() instanceof TerrasteelHelmItem) { - // TODO: might be worth refactoring this to only get the set of wills once - if (hasAncientWill_(stack, AncientWillType.AHRIM)) { - entity.addEffect(new MobEffectInstance(MobEffects.WEAKNESS, 20, 1)); - } - if (hasAncientWill_(stack, AncientWillType.GUTHAN)) { - player.heal(amount * 0.25F); - } - if (hasAncientWill_(stack, AncientWillType.TORAG)) { - entity.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 60, 1)); - } - if (hasAncientWill_(stack, AncientWillType.VERAC)) { - source = BotaniaDamageTypes.Sources.playerAttackArmorPiercing(player.level().registryAccess(), player); - } - if (hasAncientWill_(stack, AncientWillType.KARIL)) { - entity.addEffect(new MobEffectInstance(MobEffects.WITHER, 60, 1)); - } - } - } - return source; + @Override + public boolean hasFullArmorSet(Player player) { + return hasArmorSet(player); } - } diff --git a/Xplat/src/main/java/vazkii/botania/mixin/PlayerMixin.java b/Xplat/src/main/java/vazkii/botania/mixin/PlayerMixin.java index 77da04a8ab..9002b9b6a5 100644 --- a/Xplat/src/main/java/vazkii/botania/mixin/PlayerMixin.java +++ b/Xplat/src/main/java/vazkii/botania/mixin/PlayerMixin.java @@ -14,9 +14,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import vazkii.botania.api.item.AncientWillContainer; import vazkii.botania.common.PlayerAccess; import vazkii.botania.common.item.ResoluteIvyItem; -import vazkii.botania.common.item.equipment.armor.terrasteel.TerrasteelHelmItem; import vazkii.botania.common.item.relic.RingOfOdinItem; @Mixin(Player.class) @@ -40,7 +40,7 @@ protected PlayerMixin(EntityType type, Level level) { ) private DamageSource onDamageTarget(DamageSource source, float amount) { if (this.terraWillCritTarget != null) { - DamageSource newSource = TerrasteelHelmItem.onEntityAttacked(source, amount, (Player) (Object) this, terraWillCritTarget); + DamageSource newSource = AncientWillContainer.onEntityAttacked(source, amount, (Player) (Object) this, terraWillCritTarget); this.terraWillCritTarget = null; return newSource; } From 197b9254e3234c1d3f251edae71ce0b28d920c3e Mon Sep 17 00:00:00 2001 From: Louis Caron Date: Tue, 15 Apr 2025 15:38:59 -0400 Subject: [PATCH 2/2] adding missing file --- .../main/java/vazkii/botania/api/item/AncientWillContainer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java b/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java index 03c9e74459..2a055e9780 100644 --- a/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java +++ b/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java @@ -103,7 +103,7 @@ static DamageSource onEntityAttacked(DamageSource source, float amount, Player p static void addAncientWillDescription(ItemStack stack, List list){ for (AncientWillType type : AncientWillType.values()) { if (hasAncientWill(stack, type)) { - list.add(Component.translatable("botania.armorset.will_" + type.name().toLowerCase(Locale.ROOT) + ".desc").withStyle(ChatFormatting.GRAY)); + list.add(Component.translatable("botania.armorset.will_" + getWillId(type) + ".desc").withStyle(ChatFormatting.GRAY)); } } }