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 808676fc86..a5b7355658 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 @@ -152,14 +152,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 bd1a61450e..cbdb53aa90 100644 --- a/Fabric/src/main/java/vazkii/botania/fabric/mixin/PlayerFabricMixin.java +++ b/Fabric/src/main/java/vazkii/botania/fabric/mixin/PlayerFabricMixin.java @@ -33,6 +33,7 @@ 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; @@ -123,7 +124,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/forge/ForgeCommonInitializer.java b/NeoForge/src/main/java/vazkii/botania/forge/ForgeCommonInitializer.java index df2c2808c2..5ea0a1ae88 100644 --- a/NeoForge/src/main/java/vazkii/botania/forge/ForgeCommonInitializer.java +++ b/NeoForge/src/main/java/vazkii/botania/forge/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; @@ -65,10 +66,7 @@ import vazkii.botania.api.BotaniaRegistries; import vazkii.botania.api.block.HornHarvestable; import vazkii.botania.api.block.Wandable; -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.api.mana.spark.SparkAttachable; import vazkii.botania.client.fx.BotaniaParticles; @@ -450,11 +448,11 @@ private void registerEvents() { if (e.getEntity().level().isClientSide || result == Event.Result.DENY || result == Event.Result.DEFAULT && !e.isVanillaCritical() - || !TerrasteelHelmItem.hasTerraArmorSet(e.getEntity()) + || !(e.getEntity().getItemBySlot(EquipmentSlot.HEAD).getItem() instanceof AncientWillContainer awc && awc.hasFullArmorSet(e.getEntity())) || !(e.getTarget() instanceof LivingEntity target)) { return; } - e.setDamageModifier(e.getDamageModifier() * TerrasteelHelmItem.getCritDamageMult(e.getEntity())); + e.setDamageModifier(e.getDamageModifier() * 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..63b4273590 100644 --- a/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java +++ b/Xplat/src/main/java/vazkii/botania/api/item/AncientWillContainer.java @@ -8,13 +8,32 @@ */ 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.Entity; +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 net.minecraft.world.level.Level; +import vazkii.botania.api.mana.ManaItemHandler; +import vazkii.botania.common.BotaniaDamageTypes; +import vazkii.botania.common.helper.ItemNBTHelper; +import vazkii.botania.common.item.equipment.armor.terrasteel.TerrasteelHelmItem; + +import java.util.List; +import java.util.Locale; /** * An item that implements this can have Ancient Wills * crafted onto it. */ public interface AncientWillContainer { + + String TAG_ANCIENT_WILL = "AncientWill"; enum AncientWillType { AHRIM, DHAROK, @@ -24,8 +43,81 @@ enum AncientWillType { KARIL } - void addAncientWill(ItemStack stack, AncientWillType will); + static void addAncientWill(ItemStack stack, AncientWillType will) { + ItemNBTHelper.setBoolean(stack, TAG_ANCIENT_WILL + "_" + will.name().toLowerCase(Locale.ROOT), true); + } + + static boolean hasAncientWill(ItemStack stack, AncientWillType will) { + return ItemNBTHelper.getBoolean(stack, TAG_ANCIENT_WILL + "_" + will.name().toLowerCase(Locale.ROOT), false); + } + + 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; + } + } + + return 1.0F; + } + + static boolean hasAnyWill(ItemStack stack) { + for (AncientWillType type : AncientWillType.values()) { + if (AncientWillContainer.hasAncientWill(stack, type)) { + return true; + } + } + + return false; + } - boolean hasAncientWill(ItemStack stack, AncientWillType will); + 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)) { + 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)); + } + } + } + + static void ancientWillInventoryTick(ItemStack stack, Level world, Entity entity){ + if (!world.isClientSide && entity instanceof Player player && player.getInventory().armor.contains(stack) && stack.getItem() instanceof AncientWillContainer awc && awc.hasFullArmorSet(player)) { + int food = player.getFoodData().getFoodLevel(); + if (food > 0 && food < 18 && player.isHurt() && player.tickCount % 80 == 0) { + player.heal(1F); + } + if (player.tickCount % 10 == 0) { + ManaItemHandler.instance().dispatchManaExact(stack, player, 10, true); + } + } + } + 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 95c7945632..d94f10f1ab 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 @@ -49,7 +49,7 @@ public void setRecipe(RecipeHolder recipe, @NotNull IRecipeLa 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 81da62ea01..8df2b51b00 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 @@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull; +import vazkii.botania.api.item.AncientWillContainer; import vazkii.botania.client.core.handler.MiscellaneousModels; import vazkii.botania.common.item.equipment.armor.terrasteel.TerrasteelHelmItem; @@ -37,7 +38,7 @@ public TerrasteelHelmetLayer(RenderLayerParent 0 && food < 18 && player.isHurt() && player.tickCount % 80 == 0) { - player.heal(1F); - } - if (player.tickCount % 10 == 0) { - ManaItemHandler.instance().dispatchManaExact(stack, player, 10, true); - } - } + AncientWillContainer.ancientWillInventoryTick(stack, world, entity); } @Override @@ -61,77 +49,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) { - ItemNBTHelper.setBoolean(stack, TAG_ANCIENT_WILL + "_" + will.name().toLowerCase(Locale.ROOT), true); - } - - @Override - public boolean hasAncientWill(ItemStack stack, AncientWillType will) { - return hasAncientWill_(stack, will); - } - - private static boolean hasAncientWill_(ItemStack stack, AncientWillType will) { - return ItemNBTHelper.getBoolean(stack, TAG_ANCIENT_WILL + "_" + will.name().toLowerCase(Locale.ROOT), false); - } - @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_" + type.name().toLowerCase(Locale.ROOT) + ".desc").withStyle(ChatFormatting.GRAY)); - } - } + AncientWillContainer.addAncientWillDescription(stack, list); } - public static boolean hasAnyWill(ItemStack stack) { - for (AncientWillType type : AncientWillType.values()) { - if (hasAncientWill_(stack, type)) { - return true; - } - } - - return false; - } - - 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) { - 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 2ac963dd06..5b310b795b 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.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +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; @Mixin(Player.class) public abstract class PlayerMixin extends LivingEntity implements PlayerAccess { @@ -39,7 +39,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; }