Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,13 @@ void registerAncientWillRecipeWrapper(DisplayRegistry helper) {
ImmutableList.Builder<EntryIngredient> input = ImmutableList.builder();
ImmutableList.Builder<EntryStack<ItemStack>> output = ImmutableList.builder();
Set<ItemStack> 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()))));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,8 +37,76 @@ enum AncientWillType {
KARIL
}

void addAncientWill(ItemStack stack, AncientWillType will);
static void addAncientWill(ItemStack stack, AncientWillType will) {
Set<String> 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<String> 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<Component> list){
for (AncientWillType type : AncientWillType.values()) {
if (hasAncientWill(stack, type)) {
list.add(Component.translatable("botania.armorset.will_" + getWillId(type) + ".desc").withStyle(ChatFormatting.GRAY));
}
}
}

boolean hasFullArmorSet(Player player);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public void setRecipe(RecipeHolder<AncientWillRecipe> recipe, IRecipeLayoutBuild
var outputStacks = new ArrayList<ItemStack>();
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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -35,7 +36,7 @@ public TerrasteelHelmetLayer(RenderLayerParent<AbstractClientPlayer, PlayerModel
public void render(PoseStack ms, MultiBufferSource buffers, int light, AbstractClientPlayer player, float limbSwing, float limbSwingAmount, float partialTicks, float ageInTicks, float netHeadYaw, float headPitch) {
ItemStack helm = player.getItemBySlot(EquipmentSlot.HEAD);
if (!helm.isEmpty() && helm.getItem() instanceof TerrasteelHelmItem terraHelm) {
if (TerrasteelHelmItem.hasAnyWill(helm) && !terraHelm.hasPhantomInk(helm)) {
if (AncientWillContainer.hasAnyWill(helm) && !terraHelm.hasPhantomInk(helm)) {
ms.pushPose();
getParentModel().head.translateAndRotate(ms);
ms.translate(-0.2, -0.15, -0.3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ public ItemStack assemble(CraftingInput inv, HolderLookup.Provider registries) {
}

AncientWillContainer container = (AncientWillContainer) item.getItem();
if (container.hasAncientWill(item, Objects.requireNonNull(will))) {
if (AncientWillContainer.hasAncientWill(item, Objects.requireNonNull(will))) {
return ItemStack.EMPTY;
}

ItemStack copy = item.copy();
container.addAncientWill(copy, will);
AncientWillContainer.addAncientWill(copy, will);
return copy;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,17 @@
*/
package vazkii.botania.common.item.equipment.armor.terrasteel;

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 org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;

import vazkii.botania.api.item.AncientWillContainer;
import vazkii.botania.api.mana.ManaDiscountArmor;
import vazkii.botania.api.mana.ManaItemHandler;
import vazkii.botania.common.BotaniaDamageTypes;
import vazkii.botania.common.component.BotaniaDataComponents;
import vazkii.botania.common.item.BotaniaItems;

import java.util.*;

Expand All @@ -41,9 +31,7 @@ public TerrasteelHelmItem(Properties props) {
@Override
public void inventoryTick(ItemStack stack, Level world, Entity entity, int slot, boolean selected) {
super.inventoryTick(stack, world, entity, slot, selected);
if (!world.isClientSide && entity instanceof Player player
&& player.getInventory().armor.contains(stack)
&& hasArmorSet(player)) {
if (!world.isClientSide && entity instanceof Player player && player.getInventory().armor.contains(stack) && hasArmorSet(player)) {
int food = player.getFoodData().getFoodLevel();
if (food > 0 && food < 18 && player.isHurt() && player.tickCount % 80 == 0) {
player.heal(1F);
Expand All @@ -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<String> 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<String> getAncientWillsList(ItemStack stack) {
return stack.getOrDefault(BotaniaDataComponents.ANCIENT_WILLS, Collections.emptyList());
}

@Override
public void addArmorSetDescription(ItemStack stack, List<Component> 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);
}

}
4 changes: 2 additions & 2 deletions Xplat/src/main/java/vazkii/botania/mixin/PlayerMixin.java
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -40,7 +40,7 @@ protected PlayerMixin(EntityType<? extends LivingEntity> 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;
}
Expand Down