112 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
			
		
		
	
	
			112 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Java
		
	
	
	
	
	
| package net.minecraft.world.item;
 | |
| 
 | |
| import java.util.List;
 | |
| import java.util.function.Predicate;
 | |
| import net.minecraft.server.level.ServerLevel;
 | |
| import net.minecraft.sounds.SoundEvents;
 | |
| import net.minecraft.sounds.SoundSource;
 | |
| import net.minecraft.stats.Stats;
 | |
| import net.minecraft.world.InteractionHand;
 | |
| import net.minecraft.world.InteractionResult;
 | |
| import net.minecraft.world.entity.LivingEntity;
 | |
| import net.minecraft.world.entity.player.Player;
 | |
| import net.minecraft.world.entity.projectile.Projectile;
 | |
| import net.minecraft.world.level.Level;
 | |
| import org.jetbrains.annotations.Nullable;
 | |
| 
 | |
| public class BowItem extends ProjectileWeaponItem {
 | |
| 	public static final int MAX_DRAW_DURATION = 20;
 | |
| 	public static final int DEFAULT_RANGE = 15;
 | |
| 
 | |
| 	public BowItem(Item.Properties properties) {
 | |
| 		super(properties);
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public boolean releaseUsing(ItemStack stack, Level level, LivingEntity entity, int timeLeft) {
 | |
| 		if (!(entity instanceof Player player)) {
 | |
| 			return false;
 | |
| 		} else {
 | |
| 			ItemStack itemStack = player.getProjectile(stack);
 | |
| 			if (itemStack.isEmpty()) {
 | |
| 				return false;
 | |
| 			} else {
 | |
| 				int i = this.getUseDuration(stack, entity) - timeLeft;
 | |
| 				float f = getPowerForTime(i);
 | |
| 				if (f < 0.1) {
 | |
| 					return false;
 | |
| 				} else {
 | |
| 					List<ItemStack> list = draw(stack, itemStack, player);
 | |
| 					if (level instanceof ServerLevel serverLevel && !list.isEmpty()) {
 | |
| 						this.shoot(serverLevel, player, player.getUsedItemHand(), stack, list, f * 3.0F, 1.0F, f == 1.0F, null);
 | |
| 					}
 | |
| 
 | |
| 					level.playSound(
 | |
| 						null,
 | |
| 						player.getX(),
 | |
| 						player.getY(),
 | |
| 						player.getZ(),
 | |
| 						SoundEvents.ARROW_SHOOT,
 | |
| 						SoundSource.PLAYERS,
 | |
| 						1.0F,
 | |
| 						1.0F / (level.getRandom().nextFloat() * 0.4F + 1.2F) + f * 0.5F
 | |
| 					);
 | |
| 					player.awardStat(Stats.ITEM_USED.get(this));
 | |
| 					return true;
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	protected void shootProjectile(
 | |
| 		LivingEntity shooter, Projectile projectile, int index, float velocity, float inaccuracy, float angle, @Nullable LivingEntity target
 | |
| 	) {
 | |
| 		projectile.shootFromRotation(shooter, shooter.getXRot(), shooter.getYRot() + angle, 0.0F, velocity, inaccuracy);
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * Gets the velocity of the arrow entity from the bow's charge
 | |
| 	 */
 | |
| 	public static float getPowerForTime(int charge) {
 | |
| 		float f = charge / 20.0F;
 | |
| 		f = (f * f + f * 2.0F) / 3.0F;
 | |
| 		if (f > 1.0F) {
 | |
| 			f = 1.0F;
 | |
| 		}
 | |
| 
 | |
| 		return f;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public int getUseDuration(ItemStack stack, LivingEntity entity) {
 | |
| 		return 72000;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public ItemUseAnimation getUseAnimation(ItemStack stack) {
 | |
| 		return ItemUseAnimation.BOW;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public InteractionResult use(Level level, Player player, InteractionHand hand) {
 | |
| 		ItemStack itemStack = player.getItemInHand(hand);
 | |
| 		boolean bl = !player.getProjectile(itemStack).isEmpty();
 | |
| 		if (!player.hasInfiniteMaterials() && !bl) {
 | |
| 			return InteractionResult.FAIL;
 | |
| 		} else {
 | |
| 			player.startUsingItem(hand);
 | |
| 			return InteractionResult.CONSUME;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public Predicate<ItemStack> getAllSupportedProjectiles() {
 | |
| 		return ARROW_ONLY;
 | |
| 	}
 | |
| 
 | |
| 	@Override
 | |
| 	public int getDefaultProjectileRange() {
 | |
| 		return 15;
 | |
| 	}
 | |
| }
 |