Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separation of AncientWillContainer and TerrasteelHelmItem #4749

Open
wants to merge 5 commits into
base: 1.21.1-porting
Choose a base branch
from
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 @@ -152,14 +152,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,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;
Expand Down Expand Up @@ -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;
}
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 @@ -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;
Expand Down Expand Up @@ -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);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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<Component> 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);
}
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 @@ -49,7 +49,7 @@ public void setRecipe(RecipeHolder<AncientWillRecipe> recipe, @NotNull IRecipeLa
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 @@ -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;

Expand All @@ -37,7 +38,7 @@ public TerrasteelHelmetLayer(RenderLayerParent<AbstractClientPlayer, PlayerModel
public void render(@NotNull PoseStack ms, @NotNull 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,13 +69,12 @@ public ItemStack assemble(@NotNull CraftingContainer inv, @NotNull RegistryAcces
}
}

AncientWillContainer container = (AncientWillContainer) item.getItem();
if (container.hasAncientWill(item, will)) {
if (AncientWillContainer.hasAncientWill(item, 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 @@ -34,104 +34,29 @@

public class TerrasteelHelmItem extends TerrasteelArmorItem implements ManaDiscountArmor, AncientWillContainer {

public static final String TAG_ANCIENT_WILL = "AncientWill";

public TerrasteelHelmItem(Properties props) {
super(Type.HELMET, 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)) {
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);
}
}
AncientWillContainer.ancientWillInventoryTick(stack, world, entity);
}

@Override
public float getDiscount(ItemStack stack, int slot, Player player, @Nullable ItemStack tool) {
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<Component> 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);
}

}
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.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 {
Expand All @@ -39,7 +39,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