152 lines
7.1 KiB
Java
152 lines
7.1 KiB
Java
/*
|
|
* Decompiled with CFR 0.152.
|
|
*/
|
|
package net.minecraft.world.item;
|
|
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.particles.BlockParticleOption;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.sounds.SoundEvent;
|
|
import net.minecraft.sounds.SoundEvents;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.InteractionResult;
|
|
import net.minecraft.world.entity.EntitySelector;
|
|
import net.minecraft.world.entity.EquipmentSlot;
|
|
import net.minecraft.world.entity.HumanoidArm;
|
|
import net.minecraft.world.entity.LivingEntity;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.entity.projectile.ProjectileUtil;
|
|
import net.minecraft.world.item.Item;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.ItemUseAnimation;
|
|
import net.minecraft.world.item.context.UseOnContext;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.BrushableBlock;
|
|
import net.minecraft.world.level.block.RenderShape;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.block.entity.BrushableBlockEntity;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.phys.BlockHitResult;
|
|
import net.minecraft.world.phys.HitResult;
|
|
import net.minecraft.world.phys.Vec3;
|
|
|
|
public class BrushItem
|
|
extends Item {
|
|
public static final int ANIMATION_DURATION = 10;
|
|
private static final int USE_DURATION = 200;
|
|
|
|
public BrushItem(Item.Properties properties) {
|
|
super(properties);
|
|
}
|
|
|
|
@Override
|
|
public InteractionResult useOn(UseOnContext context) {
|
|
Player player = context.getPlayer();
|
|
if (player != null && this.calculateHitResult(player).getType() == HitResult.Type.BLOCK) {
|
|
player.startUsingItem(context.getHand());
|
|
}
|
|
return InteractionResult.CONSUME;
|
|
}
|
|
|
|
@Override
|
|
public ItemUseAnimation getUseAnimation(ItemStack itemStack) {
|
|
return ItemUseAnimation.BRUSH;
|
|
}
|
|
|
|
@Override
|
|
public int getUseDuration(ItemStack itemStack, LivingEntity user) {
|
|
return 200;
|
|
}
|
|
|
|
@Override
|
|
public void onUseTick(Level level, LivingEntity livingEntity, ItemStack itemStack, int ticksRemaining) {
|
|
boolean isLastTickBeforeBackswing;
|
|
BlockHitResult blockHitResult;
|
|
Player player;
|
|
block11: {
|
|
block10: {
|
|
if (ticksRemaining < 0 || !(livingEntity instanceof Player)) {
|
|
livingEntity.releaseUsingItem();
|
|
return;
|
|
}
|
|
player = (Player)livingEntity;
|
|
HitResult hitResult = this.calculateHitResult(player);
|
|
if (!(hitResult instanceof BlockHitResult)) break block10;
|
|
blockHitResult = (BlockHitResult)hitResult;
|
|
if (hitResult.getType() == HitResult.Type.BLOCK) break block11;
|
|
}
|
|
livingEntity.releaseUsingItem();
|
|
return;
|
|
}
|
|
int timeElapsed = this.getUseDuration(itemStack, livingEntity) - ticksRemaining + 1;
|
|
boolean bl = isLastTickBeforeBackswing = timeElapsed % 10 == 5;
|
|
if (isLastTickBeforeBackswing) {
|
|
SoundEvent brushSound;
|
|
Block block;
|
|
HumanoidArm brushingArm;
|
|
BlockPos pos = blockHitResult.getBlockPos();
|
|
BlockState state = level.getBlockState(pos);
|
|
HumanoidArm humanoidArm = brushingArm = livingEntity.getUsedItemHand() == InteractionHand.MAIN_HAND ? player.getMainArm() : player.getMainArm().getOpposite();
|
|
if (state.shouldSpawnTerrainParticles() && state.getRenderShape() != RenderShape.INVISIBLE) {
|
|
this.spawnDustParticles(level, blockHitResult, state, livingEntity.getViewVector(0.0f), brushingArm);
|
|
}
|
|
if ((block = state.getBlock()) instanceof BrushableBlock) {
|
|
BrushableBlock brushableBlock = (BrushableBlock)block;
|
|
brushSound = brushableBlock.getBrushSound();
|
|
} else {
|
|
brushSound = SoundEvents.BRUSH_GENERIC;
|
|
}
|
|
level.playSound(player, pos, brushSound, SoundSource.BLOCKS);
|
|
if (level instanceof ServerLevel) {
|
|
BrushableBlockEntity brushableBlockEntity;
|
|
boolean brushingUpdatedState;
|
|
ServerLevel serverLevel = (ServerLevel)level;
|
|
BlockEntity blockEntity = level.getBlockEntity(pos);
|
|
if (blockEntity instanceof BrushableBlockEntity && (brushingUpdatedState = (brushableBlockEntity = (BrushableBlockEntity)blockEntity).brush(level.getGameTime(), serverLevel, player, blockHitResult.getDirection(), itemStack))) {
|
|
EquipmentSlot equippedHand = itemStack.equals(player.getItemBySlot(EquipmentSlot.OFFHAND)) ? EquipmentSlot.OFFHAND : EquipmentSlot.MAINHAND;
|
|
itemStack.hurtAndBreak(1, (LivingEntity)player, equippedHand);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private HitResult calculateHitResult(Player player) {
|
|
return ProjectileUtil.getHitResultOnViewVector(player, EntitySelector.CAN_BE_PICKED, player.blockInteractionRange());
|
|
}
|
|
|
|
private void spawnDustParticles(Level level, BlockHitResult hitResult, BlockState state, Vec3 viewVector, HumanoidArm brushingArm) {
|
|
double deltaScale = 3.0;
|
|
int flip = brushingArm == HumanoidArm.RIGHT ? 1 : -1;
|
|
int particles = level.getRandom().nextInt(7, 12);
|
|
BlockParticleOption particle = new BlockParticleOption(ParticleTypes.BLOCK, state);
|
|
Direction hitDirection = hitResult.getDirection();
|
|
DustParticlesDelta dustParticlesDelta = DustParticlesDelta.fromDirection(viewVector, hitDirection);
|
|
Vec3 hitLocation = hitResult.getLocation();
|
|
for (int i = 0; i < particles; ++i) {
|
|
level.addParticle(particle, hitLocation.x - (double)(hitDirection == Direction.WEST ? 1.0E-6f : 0.0f), hitLocation.y, hitLocation.z - (double)(hitDirection == Direction.NORTH ? 1.0E-6f : 0.0f), dustParticlesDelta.xd() * (double)flip * 3.0 * level.getRandom().nextDouble(), 0.0, dustParticlesDelta.zd() * (double)flip * 3.0 * level.getRandom().nextDouble());
|
|
}
|
|
}
|
|
|
|
private record DustParticlesDelta(double xd, double yd, double zd) {
|
|
private static final double ALONG_SIDE_DELTA = 1.0;
|
|
private static final double OUT_FROM_SIDE_DELTA = 0.1;
|
|
|
|
public static DustParticlesDelta fromDirection(Vec3 viewVector, Direction hitDirection) {
|
|
double yd = 0.0;
|
|
return switch (hitDirection) {
|
|
default -> throw new MatchException(null, null);
|
|
case Direction.DOWN, Direction.UP -> new DustParticlesDelta(viewVector.z(), 0.0, -viewVector.x());
|
|
case Direction.NORTH -> new DustParticlesDelta(1.0, 0.0, -0.1);
|
|
case Direction.SOUTH -> new DustParticlesDelta(-1.0, 0.0, 0.1);
|
|
case Direction.WEST -> new DustParticlesDelta(-0.1, 0.0, -1.0);
|
|
case Direction.EAST -> new DustParticlesDelta(0.1, 0.0, 1.0);
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|