All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.magistuarmory.item.MedievalWeaponItem Maven / Gradle / Ivy

package com.magistuarmory.item;

import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableMultimap.Builder;
import com.google.common.collect.Multimap;
import com.magistuarmory.EpicKnights;
import com.magistuarmory.effects.LacerationEffect;
import com.magistuarmory.network.PacketLongReachAttack;
import com.magistuarmory.util.CombatHelper;
import com.magistuarmory.util.ModDamageSources;
import dev.architectury.registry.item.ItemPropertiesRegistry;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.ChatFormatting;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.RandomSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.MobType;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import me.shedaniel.cloth.clothconfig.shadowed.blue.endless.jankson.annotation.Nullable;
import java.util.List;


public class MedievalWeaponItem extends SwordItem implements IHasModelProperty
{
	private final Multimap defaultModifiers;
	private final Multimap decreasedModifiers;

	public final WeaponType type;
	protected final float attackDamage;
	protected final float attackSpeed;
	private final float decreasedAttackDamage;
	private final float decreasedAttackSpeed;
	private boolean isSilver = false;
	private float silverAttackDamage = 0.0f;
	private boolean blockingPriority = false;

	public MedievalWeaponItem(Properties properties, ModItemTier material, WeaponType type)
	{
		super(material, (int) CombatHelper.getBaseAttackDamage(material, type), CombatHelper.getBaseAttackSpeed(material, type), properties.m_41503_(type.getDurability(material)));
		this.type = type;
		this.attackDamage = CombatHelper.getBaseAttackDamage(material, type);
		this.attackSpeed = CombatHelper.getBaseAttackSpeed(material, type);
		this.decreasedAttackDamage = CombatHelper.getDecreasedAttackDamage(this.attackDamage, type);
		this.decreasedAttackSpeed = CombatHelper.getDecreasedAttackSpeed(this.attackSpeed, type);
		
		if (material.equals(ModItemTier.SILVER))
		{
			this.isSilver = true;
			this.silverAttackDamage = CombatHelper.getSilverAttackDamage(material, type);
		}
		
		Builder builder = ImmutableMultimap.builder();
		builder.put(Attributes.f_22281_, new AttributeModifier(f_41374_, "Weapon modifier", this.attackDamage, Operation.ADDITION));
		builder.put(Attributes.f_22283_, new AttributeModifier(f_41375_, "Weapon modifier", this.attackSpeed, Operation.ADDITION));
		this.defaultModifiers = builder.build();

		Builder builder2 = ImmutableMultimap.builder();
		builder2.put(Attributes.f_22281_, new AttributeModifier(f_41374_, "Weapon modifier", this.decreasedAttackDamage, Operation.ADDITION));
		builder2.put(Attributes.f_22283_, new AttributeModifier(f_41375_, "Weapon modifier", this.decreasedAttackSpeed, Operation.ADDITION));
		this.decreasedModifiers = builder2.build();
	}

	public boolean onAttackClickEntity(ItemStack stack, Player player, Entity entity)
	{
		if (!this.isLong())
			return true;
		
		if (entity != player && entity != player.m_20202_())
			PacketLongReachAttack.sendToServer(entity.m_19879_());
		
		player.m_36334_();

		return false;
	}
	
	public Multimap getAttributeModifiers(ItemStack stack, @NotNull EquipmentSlot slot)
	{
		return this.getAttributeModifiers(this.hasTwoHandedPenalty(stack), slot);
	}

	public Multimap getAttributeModifiers(boolean decreased, @NotNull EquipmentSlot slot)
	{
		return slot == EquipmentSlot.MAINHAND && decreased ? this.decreasedModifiers : this.m_7167_(slot);
	}

	@Override
	public @NotNull Multimap m_7167_(EquipmentSlot slot)
	{
		return slot == EquipmentSlot.MAINHAND ? this.defaultModifiers : super.m_7167_(slot);
	}

	@Override
	public void m_6883_(ItemStack stack, Level level, Entity entity, int i, boolean selected)
	{
		if (entity instanceof LivingEntity livingentity)
		{
			boolean flag = type.getTwoHanded() > 0 && !livingentity.m_21206_().m_41720_().equals(Items.f_41852_);
			if (this.hasTwoHandedPenalty(stack) != flag)
				this.setTwoHandedPenalty(stack, flag);
			
			if (this.canBlock()) 
				this.blockingPriority = !(livingentity.m_21205_().m_41720_() instanceof ShieldItem) && !(livingentity.m_21206_().m_41720_() instanceof ShieldItem);
		}
		super.m_6883_(stack, level, entity, i, selected);
	}

	public boolean onHurtEntity(DamageSource source, LivingEntity victim, float damage)
	{
		if (victim.f_19853_.m_5776_() || ModDamageSources.isAdditional(source) || !(source.m_7639_() instanceof LivingEntity attacker))
			return true;
		
		float attackscale = source.m_7639_() instanceof LivingEntity livingentity ? damage / this.getAttackDamage(livingentity.m_21205_()) : 1.0f;
		
		if (type.isHalberd() && victim.m_20159_() && victim.f_19853_.m_213780_().m_188503_(20) * attackscale >= 14)
			victim.m_8127_();
		
		boolean flag = false;
		if (this.isSilver())
			flag = this.dealSilverDamage(source, attacker, victim, damage, attackscale);
		if (!flag && this.type.getArmorPiercing() != 0 && victim.m_21230_() > 0)
			flag = this.dealArmorPiercingDamage(source, attacker, victim, damage);

		if (type.isFlamebladed())
			LacerationEffect.apply(source, victim, damage * attackscale);

		return flag;
	}

	@Override
	public void m_7373_(ItemStack stack, @Nullable Level level, List tooltip, TooltipFlag flag)
	{
		if (this.isSilver)
			tooltip.add(Component.m_237110_("silvertools.hurt", this.silverAttackDamage).m_130940_(ChatFormatting.GREEN));
		if (type.isFlamebladed())
			tooltip.add(Component.m_237115_("flamebladed.hurt").m_130940_(ChatFormatting.BLUE));
		if (type.isHalberd())
			tooltip.add(Component.m_237115_("halberd.hurt").m_130940_(ChatFormatting.BLUE));
		if (type.getArmorPiercing() != 0)
			tooltip.add(Component.m_237110_("armorpiercing", this.type.getArmorPiercing()).m_130940_(ChatFormatting.BLUE));
		if (this.isLong())
			tooltip.add(Component.m_237110_("bonusattackreach", this.type.getBonusAttackReach()).m_130940_(ChatFormatting.BLUE));
		if (type.getTwoHanded() == 1)
			tooltip.add(Component.m_237115_("twohandedi").m_130940_(ChatFormatting.BLUE));
		else if (type.getTwoHanded() > 1)
			tooltip.add(Component.m_237115_("twohandedii").m_130940_(ChatFormatting.BLUE));
		if (this.canBlock())
			tooltip.add(Component.m_237110_("maxdamageblock", this.getMaxBlockDamage()).m_130940_(ChatFormatting.BLUE));
		tooltip.add(Component.m_237110_("kgweight", this.getWeight()).m_130940_(ChatFormatting.BLUE));
		if (this.hasTwoHandedPenalty(stack))
		{
			tooltip.add(Component.m_237115_("twohandedpenalty_1").m_130940_(ChatFormatting.RED));
			tooltip.add(Component.m_237115_("twohandedpenalty_2").m_130940_(ChatFormatting.RED));
		}
		super.m_7373_(stack, level, tooltip, flag);
	}

	public void setTwoHandedPenalty(ItemStack stack, boolean b)
	{
		CompoundTag nbt = stack.m_41784_();
		nbt.m_128379_("twoHandedPenalty", b);
		stack.m_41751_(nbt);
	}

	public boolean hasTwoHandedPenalty(ItemStack stack)
	{
		if (stack.m_41782_())
		{
			CompoundTag nbt = stack.m_41783_();
			if (nbt.m_128441_("twoHandedPenalty"))
				return nbt.m_128471_("twoHandedPenalty");
		}

		return false;
	}

	public float getAttackDamage(ItemStack stack)
	{
		return hasTwoHandedPenalty(stack) ? this.attackDamage : this.decreasedAttackDamage;
	}

	public float getAttackSpeed(ItemStack stack)
	{
		return hasTwoHandedPenalty(stack) ? this.attackSpeed : this.decreasedAttackSpeed;
	}
	
	@Override
	public float m_43299_()
	{
		return this.attackDamage;
	}

	public float getAttackReach(float baseReach)
	{
		return baseReach + getBonusAttackReach();
	}

	public float getBonusAttackReach()
	{
		return EpicKnights.BC_or_EF_installed ? 0.0f : type.getBonusAttackReach();
	}
	
	public boolean isLong()
	{
		return this.getBonusAttackReach() > 0.0;
	}

	@Deprecated(forRemoval = true)
	public float getSilverDamage(ItemStack stack, float damage)
	{
		return this.silverAttackDamage * damage / this.getAttackDamage(stack);
	}

	public float getMaxBlockDamage()
	{
		return type.getMaxBlockDamage();
	}

	public float getWeight()
	{
		return type.getWeight();
	}

	public boolean isSilver()
	{
		return this.isSilver;
	}

	public boolean canBlock(Player player)
	{
		return player.m_36403_(0.0f) == 1.0f && this.canBlock();
	}

	public boolean canBlock()
	{
		return type.canBlock();
	}

	boolean haveBlocked(RandomSource rand, DamageSource source)
	{
		return !source.m_19360_() && rand.m_188503_(18) > this.getWeight();
	}

	@Override
	public InteractionResultHolder m_7203_(Level level, Player player, InteractionHand hand)
	{
		if (canBlock(player) && blockingPriority)
		{
			ItemStack stack = player.m_21120_(hand);
			player.m_6672_(hand);

			return InteractionResultHolder.m_19096_(stack);
		}

		return super.m_7203_(level, player, hand);
	}

	public int m_8105_(ItemStack stack)
	{
		return this.canBlock() ? (int) (500 / this.getWeight()) : 0;
	}

	@Override
	public UseAnim m_6164_(ItemStack stack)
	{
		return (canBlock() && blockingPriority) ? UseAnim.BLOCK : super.m_6164_(stack);
	}

	public void onBlocked(ItemStack stack, float damage, LivingEntity victim, DamageSource source)
	{
		if (!this.canBlock() || ModDamageSources.isAdditional(source))
			return;

		Entity attacker = source.m_7639_();
		float f = CombatHelper.getArmorPiercingFactor(attacker);

		if (source.m_19372_())
		{
			victim.m_6469_(ModDamageSources.additional(), damage);
		}
		else if (!haveBlocked(victim.f_19853_.m_213780_(), source))
		{
			victim.m_6469_(ModDamageSources.additional(), damage);
		}
		else if (damage > this.getMaxBlockDamage())
		{
			f *= 1.5f;
			float damage1 = damage - getMaxBlockDamage();
			victim.m_6469_(ModDamageSources.additional(), damage1);
		}

		stack.m_41622_((int) (f * damage), victim, entity -> entity.m_21166_(EquipmentSlot.MAINHAND));
	}

	public boolean dealSilverDamage(DamageSource source, LivingEntity attacker, LivingEntity victim, float damage, float attackscale)
	{
		if (victim.m_6336_().equals(MobType.f_21641_))
		{
			victim.m_6469_(ModDamageSources.silverAttack(attacker), CombatHelper.getDamageAfterAbsorb(source, victim, this.silverAttackDamage) * attackscale + damage);
			return true;
		}
		return false;
	}

	public boolean dealArmorPiercingDamage(DamageSource source, LivingEntity attacker, LivingEntity victim, float damage)
	{
		float afterabsorb = CombatHelper.getDamageAfterAbsorb(source, victim, damage);
		afterabsorb = Math.max(afterabsorb - victim.m_6103_(), 0.0f);
		float pierced = Math.max(((float) type.getArmorPiercing()) / 100.0f * (damage - afterabsorb), 0.0f);
		victim.m_6469_(ModDamageSources.armorPiercing(attacker), damage + pierced);
		return true;
	}

	@Override
	@Environment(EnvType.CLIENT)
	public void registerModelProperty()
	{
		if (this.canBlock())
		{
			ItemPropertiesRegistry.register(this, new ResourceLocation("blocking"), (stack, level, entity, i) ->
					entity != null && entity.m_6117_() && entity.m_21211_() == stack ? 1.0F : 0.0F);
		}
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy