140 lines
6.5 KiB
Java
140 lines
6.5 KiB
Java
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.context.UseOnContext;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.BrushableBlock;
|
|
import net.minecraft.world.level.block.RenderShape;
|
|
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 p_272907_) {
|
|
super(p_272907_);
|
|
}
|
|
|
|
@Override
|
|
public InteractionResult useOn(UseOnContext p_272607_) {
|
|
Player player = p_272607_.getPlayer();
|
|
if (player != null && this.calculateHitResult(player).getType() == HitResult.Type.BLOCK) {
|
|
player.startUsingItem(p_272607_.getHand());
|
|
}
|
|
|
|
return InteractionResult.CONSUME;
|
|
}
|
|
|
|
@Override
|
|
public ItemUseAnimation getUseAnimation(ItemStack p_273490_) {
|
|
return ItemUseAnimation.BRUSH;
|
|
}
|
|
|
|
@Override
|
|
public int getUseDuration(ItemStack p_272765_, LivingEntity p_343510_) {
|
|
return 200;
|
|
}
|
|
|
|
@Override
|
|
public void onUseTick(Level p_273467_, LivingEntity p_273619_, ItemStack p_273316_, int p_273101_) {
|
|
if (p_273101_ >= 0 && p_273619_ instanceof Player player) {
|
|
HitResult hitresult = this.calculateHitResult(player);
|
|
if (hitresult instanceof BlockHitResult blockhitresult && hitresult.getType() == HitResult.Type.BLOCK) {
|
|
int i = this.getUseDuration(p_273316_, p_273619_) - p_273101_ + 1;
|
|
boolean flag = i % 10 == 5;
|
|
if (flag) {
|
|
BlockPos blockpos = blockhitresult.getBlockPos();
|
|
BlockState blockstate = p_273467_.getBlockState(blockpos);
|
|
HumanoidArm humanoidarm = p_273619_.getUsedItemHand() == InteractionHand.MAIN_HAND ? player.getMainArm() : player.getMainArm().getOpposite();
|
|
if (blockstate.shouldSpawnTerrainParticles() && blockstate.getRenderShape() != RenderShape.INVISIBLE) {
|
|
this.spawnDustParticles(p_273467_, blockhitresult, blockstate, p_273619_.getViewVector(0.0F), humanoidarm);
|
|
}
|
|
|
|
SoundEvent soundevent;
|
|
if (blockstate.getBlock() instanceof BrushableBlock brushableblock) {
|
|
soundevent = brushableblock.getBrushSound();
|
|
} else {
|
|
soundevent = SoundEvents.BRUSH_GENERIC;
|
|
}
|
|
|
|
p_273467_.playSound(player, blockpos, soundevent, SoundSource.BLOCKS);
|
|
if (p_273467_ instanceof ServerLevel serverlevel && p_273467_.getBlockEntity(blockpos) instanceof BrushableBlockEntity brushableblockentity) {
|
|
boolean flag1 = brushableblockentity.brush(p_273467_.getGameTime(), serverlevel, player, blockhitresult.getDirection(), p_273316_);
|
|
if (flag1) {
|
|
EquipmentSlot equipmentslot = p_273316_.equals(player.getItemBySlot(EquipmentSlot.OFFHAND))
|
|
? EquipmentSlot.OFFHAND
|
|
: EquipmentSlot.MAINHAND;
|
|
p_273316_.hurtAndBreak(1, player, equipmentslot);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
p_273619_.releaseUsingItem();
|
|
}
|
|
} else {
|
|
p_273619_.releaseUsingItem();
|
|
}
|
|
}
|
|
|
|
private HitResult calculateHitResult(Player p_311819_) {
|
|
return ProjectileUtil.getHitResultOnViewVector(p_311819_, EntitySelector.CAN_BE_PICKED, p_311819_.blockInteractionRange());
|
|
}
|
|
|
|
private void spawnDustParticles(Level p_278327_, BlockHitResult p_278272_, BlockState p_278235_, Vec3 p_278337_, HumanoidArm p_285071_) {
|
|
double d0 = 3.0;
|
|
int i = p_285071_ == HumanoidArm.RIGHT ? 1 : -1;
|
|
int j = p_278327_.getRandom().nextInt(7, 12);
|
|
BlockParticleOption blockparticleoption = new BlockParticleOption(ParticleTypes.BLOCK, p_278235_);
|
|
Direction direction = p_278272_.getDirection();
|
|
BrushItem.DustParticlesDelta brushitem$dustparticlesdelta = BrushItem.DustParticlesDelta.fromDirection(p_278337_, direction);
|
|
Vec3 vec3 = p_278272_.getLocation();
|
|
|
|
for (int k = 0; k < j; k++) {
|
|
p_278327_.addParticle(
|
|
blockparticleoption,
|
|
vec3.x - (direction == Direction.WEST ? 1.0E-6F : 0.0F),
|
|
vec3.y,
|
|
vec3.z - (direction == Direction.NORTH ? 1.0E-6F : 0.0F),
|
|
brushitem$dustparticlesdelta.xd() * i * 3.0 * p_278327_.getRandom().nextDouble(),
|
|
0.0,
|
|
brushitem$dustparticlesdelta.zd() * i * 3.0 * p_278327_.getRandom().nextDouble()
|
|
);
|
|
}
|
|
}
|
|
|
|
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 BrushItem.DustParticlesDelta fromDirection(Vec3 p_273421_, Direction p_272987_) {
|
|
double d0 = 0.0;
|
|
|
|
return switch (p_272987_) {
|
|
case DOWN, UP -> new BrushItem.DustParticlesDelta(p_273421_.z(), 0.0, -p_273421_.x());
|
|
case NORTH -> new BrushItem.DustParticlesDelta(1.0, 0.0, -0.1);
|
|
case SOUTH -> new BrushItem.DustParticlesDelta(-1.0, 0.0, 0.1);
|
|
case WEST -> new BrushItem.DustParticlesDelta(-0.1, 0.0, -1.0);
|
|
case EAST -> new BrushItem.DustParticlesDelta(0.1, 0.0, 1.0);
|
|
};
|
|
}
|
|
}
|
|
} |