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

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

package com.magistuarmory.item;

import com.magistuarmory.EpicKnights;
import com.magistuarmory.client.ClientHelper;
import com.magistuarmory.network.PacketLanceCollision;
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.client.Minecraft;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.animal.horse.Horse;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.*;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import me.shedaniel.cloth.clothconfig.shadowed.blue.endless.jankson.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


public class LanceItem extends MedievalWeaponItem
{
	private List dropItems = new ArrayList<>();
	protected int clickedticks = 0;

	public LanceItem(Properties properties, ModItemTier material, WeaponType type)
	{
		super(properties, material, type);
		this.setDropItems(material);
	}

	public LanceItem setDropItems(ModItemTier material)
	{
		this.dropItems.add(new ItemStack(Items.f_42398_, 2));
		Arrays.stream(material.m_6282_().m_43908_())
				.filter(stack -> stack.m_150930_(Items.f_42127_))
				.findFirst()
				.ifPresent(stack -> this.dropItems.add(stack));
		return this;
	}

	@Override
	public InteractionResultHolder m_7203_(Level level, Player player, InteractionHand hand)
	{
		this.setRaised(player, !this.isRaised(player));
		return super.m_7203_(level, player, hand);
	}

	@Override
	public boolean onAttackClickEntity(ItemStack stack, Player player, Entity entity)
	{
		if (EpicKnights.GENERAL_CONFIG.disableLanceCollision)
			return super.onAttackClickEntity(stack, player, entity);

		if (player.m_20159_() && !this.isRaised(player) && !player.m_36335_().m_41519_(this))
			this.clickedticks = 15;
		player.m_6674_(InteractionHand.MAIN_HAND);

		return false;
	}

	public void collide(Player player, LivingEntity victim, Level level)
	{
		if (player == null || level == null)
			return;

		if (!this.isRaised(player) && !player.m_36335_().m_41519_(this) && player.m_20159_())
		{
			float speed = this.getVelocityProjection(player);

			if ((player.m_20201_() instanceof Horse &&
					speed >= ((Horse)player.m_20201_()).m_21051_(Attributes.f_22279_).m_22135_())
					|| (!(player.m_20201_() instanceof Horse) && speed >= 0.233))
			{
				boolean dismount = level.m_213780_().m_188500_() * (this.clickedticks / 15.0 * 0.5 + 0.5) > 0.45;
				PacketLanceCollision.sendToServer(victim.m_19879_(), speed, dismount);
				player.m_36334_();
			}
		}
	}

	@Override
	public boolean onHurtEntity(DamageSource source, LivingEntity victim, float damage)
	{
		if (EpicKnights.GENERAL_CONFIG.disableLanceCollision)
			return super.onHurtEntity(source, victim, damage);

		if (victim.f_19853_.m_5776_() || ModDamageSources.isAdditional(source) || !(source.m_7639_() instanceof LivingEntity attacker))
			return true;

		float speed = 0.0f;
		float bonusdamage = 0.0f;
		boolean dismount = false;

		if (attacker instanceof Mob mob)
		{
			ItemStack stack = mob.m_21205_();
			speed = this.getRideSpeed(stack);
			this.setRideSpeed(stack, 0.0f);
			bonusdamage = this.calcBonusDamage(attacker, speed);
			dismount = this.getDismount(stack);
			this.setDismount(stack, false);
		}
		else if (attacker instanceof Player player)
		{
			ItemStack stack = player.m_21205_();
			speed = this.getRideSpeed(stack);
			this.setRideSpeed(stack, 0.0f);
			bonusdamage = this.calcBonusDamage(attacker, speed);
			dismount = this.getDismount(stack);
			this.setDismount(stack, false);

			if (stack.m_41773_() >= stack.m_41776_() - 1)
				this.onBroken(player);
			else if (!player.m_7500_() && (victim.m_21230_() >= 18 || victim.m_21254_()))
				stack.m_41721_(stack.m_41773_() + (int) ((0.6 + bonusdamage / 20) * victim.f_19853_.m_213780_().m_188500_() * stack.m_41776_()));

			for (ItemStack stack0 : player.m_150109_().f_35974_)
			{
				this.setRaised(player, true);
				player.m_36335_().m_41524_(stack0.m_41720_(), (int) (40 / (4 + this.getAttackSpeed(stack))));
			}

			if (stack.m_41773_() >= stack.m_41776_())
			{
				this.onBroken(player);
				stack.m_41764_(0);
			}
		}

		Vec3 vec = attacker.m_20252_(1.0f);
		double magnitude = Math.min(1.0f, speed * this.getTotalMass(attacker) / this.getTotalMass(victim));
		Vec3 vel = vec.m_82542_(magnitude, magnitude, magnitude);
		
		if (victim.m_20159_())
		{
			victim.m_20201_().m_20256_(victim.m_20201_().m_20184_().m_82549_(vel));
			victim.m_20201_().f_19812_ = true;
			if (dismount)
				victim.m_8127_();
		}
		else
		{
			victim.m_20256_(victim.m_20184_().m_82549_(vel));
			victim.f_19812_ = true;
		}

		if (!super.onHurtEntity(source, victim, bonusdamage + damage) && bonusdamage != 0.0f)
		{
			victim.m_6469_(ModDamageSources.additional(attacker), bonusdamage + damage);
			return true;
		}

		return false;
	}

	@Override
	public UseAnim m_6164_(ItemStack stack)
	{
		return UseAnim.BOW;
	}

	@Override
	public void m_6883_(ItemStack stack, Level level, Entity entity, int i, boolean selected)
	{
		if (EpicKnights.GENERAL_CONFIG.disableLanceCollision)
		{
			super.m_6883_(stack, level, entity, i, selected);
			return;
		}

		if (entity instanceof Player player)
		{
			if (level.f_46443_ && player.m_21205_().m_41720_() instanceof LanceItem)
			{
				HitResult hit = ClientHelper.getMouseOver(Minecraft.m_91087_(), CombatHelper.getAttackReach(player, this));
				if (hit instanceof EntityHitResult entityhit)
				{
					Entity victim = entityhit.m_82443_();
					if (player.m_20159_() && victim instanceof LivingEntity && victim.m_6084_() && victim.m_19879_() != player.m_20202_().m_19879_())
						this.collide(player, (LivingEntity) victim, level);
				}

				if (this.clickedticks > 0)
					this.clickedticks--;
			}

			if (!this.isRaised(player) && player.m_36335_().m_41519_(this))
				this.setRaised(player, true);
		}
		super.m_6883_(stack, level, entity, i, selected);
	}

	@Override
	public InteractionResult m_6225_(UseOnContext context)
	{
		return InteractionResult.PASS;
	}

	public float calcBonusDamage(Entity entity, float speed)
	{
		float bonusdamage = 3.0f * this.getTotalMass(entity) * speed;
		return Math.min(Math.max(0.0f, bonusdamage), 0.7f * this.attackDamage);
	}

	@Override
	public void m_7373_(ItemStack stack, @Nullable Level level, List tooltip, TooltipFlag flag)
	{
		tooltip.add(Component.m_237115_("lance.rideronly").m_130940_(ChatFormatting.BLUE));
		tooltip.add(Component.m_237115_("lance.leftclick").m_130940_(ChatFormatting.BLUE));
		tooltip.add(Component.m_237115_("lance.bonusdamage").m_130940_(ChatFormatting.BLUE));

		super.m_7373_(stack, level, tooltip, flag);
	}


	float getVelocityProjection(Entity entity)
	{
		Vec3 velocity;
		if (entity.m_20159_())
			velocity = entity.m_20201_().m_20184_();
		else
			velocity = entity.m_20184_();

		Vec3 vec = entity.m_20252_(1.0f);

		if (vec.m_82556_() == 0.0f)
			return 0.0f;

		return (float) (velocity.m_82526_(vec) / vec.m_82553_());
	}


	public float getTotalMass(Entity entity)
	{
		float totalmass = this.getMass(entity);

		Entity entity2 = entity;
		while (entity2.m_20159_())
		{
			entity2 = entity2.m_20202_();
			totalmass += this.getMass(entity2);
		}

		for (Entity passenger : entity.m_20197_())
			totalmass += this.getMass(passenger);

		return totalmass;
	}


	public float getMass(Entity entity)
	{
		float mass = 0.0f;

		AABB box = entity.m_20191_();
		if (box != null)
			mass += (box.m_82362_()) * (box.m_82376_()) * (box.m_82385_());

		for (ItemStack armorpiece : entity.m_6168_())
		{
			if (!armorpiece.m_41619_() && armorpiece.m_41720_() instanceof ArmorItem)
				mass += (((ArmorItem)armorpiece.m_41720_()).m_40404_() + ((ArmorItem)armorpiece.m_41720_()).m_40405_()) / 20.0;
		}

		return mass;
	}

	public void onBroken(Player player)
	{
		if (player.m_21205_() != null && player.m_21205_().m_41720_() == this)
		{
			for (ItemStack stack : this.dropItems)
				player.m_36176_(stack, true);
			player.m_5496_(SoundEvents.f_12018_, 1.0f, 1.0f);
		}
	}

	public boolean isRaised(@Nullable LivingEntity entity)
	{
		if (entity == null)
			return false;

		ItemStack stack = entity.m_21205_();
		if (stack.m_41782_())
		{
			CompoundTag nbt = stack.m_41783_();
			return nbt.m_128441_("raised") && nbt.m_128451_("raised") == 1;
		}

		return false;
	}

	public void setRaised(LivingEntity entity, boolean raised)
	{
		ItemStack stack = entity.m_21205_();
		CompoundTag nbt = stack.m_41782_() ? stack.m_41783_() : new CompoundTag();
		nbt.m_128405_("raised", raised ? 1 : 0);
		stack.m_41751_(nbt);
	}

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

		return false;
	}

	public void setDismount(ItemStack stack, boolean dismount)
	{
		CompoundTag nbt = stack.m_41784_();
		nbt.m_128379_("dismount", dismount);
		stack.m_41751_(nbt);
	}

	public float getRideSpeed(ItemStack stack)
	{
		if (stack.m_41782_())
		{
			CompoundTag nbt = stack.m_41783_();
			if (nbt.m_128441_("rideSpeed"))
				return nbt.m_128457_("rideSpeed");
		}

		return 0.0f;
	}

	public void setRideSpeed(ItemStack stack, float speed)
	{
		CompoundTag nbt = stack.m_41784_();
		nbt.m_128350_("rideSpeed", speed);
		stack.m_41751_(nbt);
	}

	@Override
	@Environment(EnvType.CLIENT)
	public void registerModelProperty()
	{
		ItemPropertiesRegistry.register(this, new ResourceLocation(EpicKnights.ID, "raised"), (stack, level, entity, i) -> this.isRaised(entity) ? 1 : 0);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy