package com.dairymoose.modernlife.items; import com.dairymoose.modernlife.core.CustomBlocks; import com.dairymoose.modernlife.core.ModernLifeCommon; import com.dairymoose.modernlife.core.ModernLifeConfig; import com.dairymoose.modernlife.core.ModernLifeNetwork; import com.dairymoose.modernlife.network.play.client.ServerboundChainsawTargetPacket; import com.google.common.collect.Sets; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import javax.annotation.Nullable; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.particles.BlockParticleOption; import net.minecraft.core.particles.ParticleType; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.TextComponent; import net.minecraft.server.level.ServerLevel; import net.minecraft.sounds.SoundSource; import net.minecraft.tags.BlockTags; 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.LivingEntity; import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.ProjectileUtil; import net.minecraft.world.item.DiggerItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Tier; import net.minecraft.world.item.TooltipFlag; import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.material.Material; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.common.ForgeMod; import net.minecraftforge.registries.ForgeRegistries; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; /* loaded from: outputsrg.jar:com/dairymoose/modernlife/items/ChainsawItem.class */ public class ChainsawItem extends DiggerItem { private final ScheduledExecutorService scheduler; boolean isWieldingChainsaw; private int chainsawStartTick; private static final int CHAINSAW_START_PAUSE = 6; private static final int CHAINSAW_IDLE_PAUSE = 18; private static final Logger LOGGER = LogManager.getLogger(); private static final Set CHAINSAW_MATERIALS = Sets.newHashSet(new Material[]{Material.LEAVES, Material.WOOD, Material.NETHER_WOOD, Material.PLANT, Material.REPLACEABLE_PLANT, Material.BAMBOO, Material.VEGETABLE}); private static final Set CHAINSAW_BLOCKS = Sets.newHashSet(new Block[]{Blocks.WARPED_WART_BLOCK, Blocks.NETHER_WART_BLOCK, Blocks.COBWEB}); private static final Set OTHER_DIGGABLE_BLOCKS = Sets.newHashSet(new Block[]{Blocks.LADDER, Blocks.SCAFFOLDING, Blocks.OAK_BUTTON, Blocks.SPRUCE_BUTTON, Blocks.BIRCH_BUTTON, Blocks.JUNGLE_BUTTON, Blocks.DARK_OAK_BUTTON, Blocks.ACACIA_BUTTON, Blocks.CRIMSON_BUTTON, Blocks.WARPED_BUTTON, Blocks.NETHER_WART_BLOCK, Blocks.COBWEB}); private static final Set CHAINSAW_DIGGABLE_SET = Sets.union(CHAINSAW_BLOCKS, OTHER_DIGGABLE_BLOCKS); public static Map mineMap = new HashMap(); /* loaded from: outputsrg.jar:com/dairymoose/modernlife/items/ChainsawItem$MiningInfo.class */ public static class MiningInfo { public float miningProgress; public BlockPos pos; public HitResult rayTrace; } public ChainsawItem(Tier tier, float p_i48530_2_, float p_i48530_3_, Properties p_i48530_4_) { super(p_i48530_2_, p_i48530_3_, tier, BlockTags.MINEABLE_WITH_AXE, p_i48530_4_); this.scheduler = Executors.newScheduledThreadPool(3); this.isWieldingChainsaw = false; this.chainsawStartTick = 0; } public float getDestroySpeed(ItemStack p_150893_1_, BlockState p_150893_2_) { Material material = p_150893_2_.m_60767_(); float webMult = 1.0f; if (p_150893_2_.is(Blocks.COBWEB)) { webMult = 2.0f; } return (CHAINSAW_MATERIALS.contains(material) || CHAINSAW_DIGGABLE_SET.contains(p_150893_2_.getBlock())) ? webMult * this.speed : super.getDestroySpeed(p_150893_1_, p_150893_2_); } void chainsawAttack(Level world, Player player, ItemStack itemStack, Entity targetEntity, Vec3 loc) { LivingEntity livingEntity = (LivingEntity) targetEntity; if (livingEntity.isAlive() && livingEntity.isAttackable()) { int initialInvulnerableTime = livingEntity.invulnerableTime; AttributeInstance kbResist = livingEntity.getAttribute(Attributes.KNOCKBACK_RESISTANCE); double kbResistInitial = kbResist.getBaseValue(); try { double pickRange = player.getAttribute(ForgeMod.REACH_DISTANCE.get()).getValue(); double chainsawRange = pickRange * 1.0d; double chainsawRangeSqr = chainsawRange * chainsawRange; if (livingEntity.distanceToSqr(player.getEyePosition(1.0f)) <= chainsawRangeSqr && (world instanceof ServerLevel)) { livingEntity.invulnerableTime = 0; kbResist.setBaseValue(1.0d); if (livingEntity.hurt(DamageSource.playerAttack(player), 1.87f)) { ((ServerLevel) world).sendParticles(ParticleTypes.CRIMSON_SPORE, livingEntity.getX() + ((Math.random() * 0.5d) - 0.25d), loc.y, livingEntity.getZ() + ((Math.random() * 0.5d) - 0.25d), 30, 0.0d, 0.0d, 0.0d, 0.0d); int durabilityDamage = 26; Integer chainsawConfigDamage = (Integer) ModernLifeConfig.SERVER.chainsawDurabilityDamageOnAttack.get(); if (chainsawConfigDamage != null) { durabilityDamage = chainsawConfigDamage.intValue(); } itemStack.hurtAndBreak(durabilityDamage, player, t -> { }); if (itemStack.getCount() <= 0) { return; } } } livingEntity.invulnerableTime = initialInvulnerableTime; kbResist.setBaseValue(kbResistInitial); } finally { livingEntity.invulnerableTime = initialInvulnerableTime; kbResist.setBaseValue(kbResistInitial); } } } private void chainsawSound(Level world, Player player, int count, float pitchMod) { if (count % 4 == 0) { world.playSound(player, player.blockPosition(), CustomBlocks.SOUND_CHAINSAW_RUNNING.get(), SoundSource.BLOCKS, 0.15f, 0.9f + pitchMod); } } private boolean shouldPlayChainsawIdleSound() { boolean shouldPlay = true; Boolean shouldPlayConfig = (Boolean) ModernLifeConfig.CLIENT.chainsawPlaysIdleSound.get(); if (shouldPlayConfig != null) { shouldPlay = shouldPlayConfig.booleanValue(); } return shouldPlay; } private void chainsawStartSound(Level world, Player player, int count) { if (shouldPlayChainsawIdleSound()) { world.playSound(player, player.blockPosition(), CustomBlocks.SOUND_CHAINSAW_START.get(), SoundSource.BLOCKS, 0.15f, 1.0f); } } private void chainsawIdleSound(Level world, Player player, int count) { if (count % 4 == 0 && shouldPlayChainsawIdleSound()) { world.playSound(player, player.blockPosition(), CustomBlocks.SOUND_CHAINSAW_IDLE.get(), SoundSource.BLOCKS, 0.04f, 1.0f); } } private void chainsawStopSound(Level world, Player player, int count) { if (shouldPlayChainsawIdleSound()) { world.playSound(player, player.blockPosition(), CustomBlocks.SOUND_CHAINSAW_STOP.get(), SoundSource.BLOCKS, 0.15f, 1.0f); } } @OnlyIn(Dist.CLIENT) public void inventoryTick(ItemStack itemStack, Level level, Entity entity, int slot, boolean isMainHand) { if (level.isClientSide && (entity instanceof LivingEntity)) { LivingEntity le = (LivingEntity) entity; if (le.getId() == Minecraft.getInstance().player.getId()) { LocalPlayer localPlayer = Minecraft.getInstance().player; ItemStack mainHandItem = le.getMainHandItem(); ItemStack offHandItem = le.getOffhandItem(); if (!this.isWieldingChainsaw) { if (mainHandItem.is(CustomBlocks.ITEM_CHAINSAW.get()) || offHandItem.is(CustomBlocks.ITEM_CHAINSAW.get())) { this.isWieldingChainsaw = true; this.chainsawStartTick = ModernLifeCommon.clientTickCounter; } } else { int tickDiff = ModernLifeCommon.clientTickCounter - this.chainsawStartTick; if (!mainHandItem.is(CustomBlocks.ITEM_CHAINSAW.get()) && !offHandItem.is(CustomBlocks.ITEM_CHAINSAW.get())) { if (this.isWieldingChainsaw && tickDiff >= 18) { chainsawStopSound(level, localPlayer, 0); } this.isWieldingChainsaw = false; } else if (tickDiff == 6) { chainsawStartSound(level, localPlayer, 0); } else if (tickDiff >= 18 && (le.getUseItem() == null || !le.getUseItem().is(CustomBlocks.ITEM_CHAINSAW.get()))) { chainsawIdleSound(level, localPlayer, ModernLifeCommon.clientTickCounter); } } } } super.inventoryTick(itemStack, level, entity, slot, isMainHand); } public void onUsingTick(ItemStack itemStack, LivingEntity livingEntity, int count) { if (livingEntity instanceof Player) { Player player = (Player) livingEntity; if (livingEntity.level.isClientSide) { if (livingEntity != Minecraft.getInstance().player) { return; } EntityHitResult rayTraceForPlayer = getRayTraceForPlayer(player.level, player); BlockHitResult blockRayTrace = null; int entityId = -1; if (rayTraceForPlayer.getType() == HitResult.Type.ENTITY) { EntityHitResult entityRayTrace = rayTraceForPlayer; Entity entity = entityRayTrace.getEntity(); if (entity instanceof LivingEntity) { entityId = entity.getId(); Vec3 loc = entityRayTrace.getLocation(); blockRayTrace = BlockHitResult.miss(loc, Direction.UP, new BlockPos(loc.x, loc.y, loc.z)); } } else if (rayTraceForPlayer.getType() == HitResult.Type.BLOCK) { blockRayTrace = (BlockHitResult) rayTraceForPlayer; } float pitchMod = 0.0f; if (rayTraceForPlayer.getType() == HitResult.Type.BLOCK || rayTraceForPlayer.getType() == HitResult.Type.ENTITY) { pitchMod = 0.1f; } chainsawSound(player.level, player, count, pitchMod); ServerboundChainsawTargetPacket chainsawTarget = new ServerboundChainsawTargetPacket(blockRayTrace, entityId); ModernLifeNetwork.INSTANCE.sendToServer(chainsawTarget); return; } MiningInfo mInfo = mineMap.get(player); if (mInfo == null) { mInfo = new MiningInfo(); mineMap.put(player, mInfo); } ServerLevel serverLevel = livingEntity.level; EntityHitResult entityRayTrace2 = mInfo.rayTrace; if (entityRayTrace2 == null) { return; } float pitchMod2 = 0.0f; if (entityRayTrace2.getType() == HitResult.Type.BLOCK || entityRayTrace2.getType() == HitResult.Type.ENTITY) { pitchMod2 = 0.1f; } chainsawSound(player.level, player, count, pitchMod2); Vec3 loc2 = entityRayTrace2.getLocation(); if (entityRayTrace2.getType() == HitResult.Type.ENTITY) { mInfo.rayTrace = entityRayTrace2; Entity entity2 = entityRayTrace2.getEntity(); if ((entity2 instanceof LivingEntity) && itemStack != null && itemStack.getItem() == CustomBlocks.ITEM_CHAINSAW.get() && itemStack.getCount() > 0) { chainsawAttack(serverLevel, player, itemStack, entity2, loc2); if (!entity2.isAlive()) { mInfo.rayTrace = null; return; } return; } return; } if (entityRayTrace2.getType() == HitResult.Type.BLOCK) { BlockHitResult blockRayTrace2 = (BlockHitResult) entityRayTrace2; double pickRange = player.getAttribute(ForgeMod.REACH_DISTANCE.get()).getValue(); double chainsawRange = pickRange * 1.0d; double chainsawRangeSqr = chainsawRange * chainsawRange; if (blockRayTrace2.getLocation().distanceToSqr(player.getEyePosition(1.0f)) > chainsawRangeSqr) { return; } BlockPos pos = blockRayTrace2.getBlockPos(); BlockState state = serverLevel.getBlockState(pos); if (!state.isAir()) { ParticleType particles = ForgeRegistries.PARTICLE_TYPES.getValue(ForgeRegistries.PARTICLE_TYPES.getKey(ParticleTypes.BLOCK)); if (particles != null) { BlockParticleOption blockParticle = new BlockParticleOption(particles, state); if (serverLevel instanceof ServerLevel) { for (int i = 0; i < 10; i++) { serverLevel.sendParticles(blockParticle, loc2.x + ((Math.random() * 1.0d) - 0.5d), loc2.y + ((Math.random() * 1.0d) - 0.5d), loc2.z + ((Math.random() * 1.0d) - 0.5d), 1, 0.0d, 0.0d, 0.0d, 0.0d); } } } mineIfPossible(player, serverLevel, pos, mInfo); } } } } public boolean shouldCauseReequipAnimation(ItemStack oldStack, ItemStack newStack, boolean slotChanged) { return false; } public void destroyGrid(Level world, BlockPos center, int width, int height) { BlockPos newCenter = center.below(height / 2); for (int h = 0; h < height; h++) { BlockPos westPos = newCenter.west(width / 2); for (int w = 0; w < width; w++) { BlockPos destroyPos = westPos.north(width / 2); for (int slice = 0; slice < width; slice++) { if (!destroyPos.equals(center) && world.getBlockState(destroyPos).is(world.getBlockState(center).getBlock())) { destroyIfPossible(world, destroyPos); } destroyPos = destroyPos.south(); } westPos = westPos.east(); } newCenter = newCenter.above(); } } public boolean mineIfPossible(Player player, Level world, BlockPos pos, MiningInfo mInfo) { if (!pos.equals(mInfo.pos)) { mInfo.pos = pos; mInfo.miningProgress = 0.0f; return false; } BlockState state = world.getBlockState(pos); float toolMult = getDestroySpeed(player.getUseItem(), state); float usingChainsawMult = 2.0f; ItemStack itemStack = player.getUseItem(); float enchantMult = 1.0f; if (CHAINSAW_MATERIALS.contains(state.m_60767_()) || CHAINSAW_BLOCKS.contains(state.getBlock())) { usingChainsawMult = 6.0f; if (itemStack.isEnchanted()) { ListTag enchantmentTags = itemStack.getEnchantmentTags(); for (int i = 0; i < enchantmentTags.size(); i++) { CompoundTag compoundTag = enchantmentTags.get(i); if (compoundTag instanceof CompoundTag) { CompoundTag nbt = compoundTag; String id = nbt.getString("id"); int level = nbt.getInt("lvl"); if (id != null && "minecraft:efficiency".equals(id) && level > 0) { enchantMult = 1.0f + (level / 5.0f); } } } } } float blockDestroySpeed = state.m_60800_(world, pos); float progressIncrement = ((usingChainsawMult * toolMult) * enchantMult) / blockDestroySpeed; mInfo.miningProgress += progressIncrement; state.m_60625_(player, world, pos); int newProgressValueToSet = (int) (mInfo.miningProgress / 10.0f); world.destroyBlockProgress(-1, pos, newProgressValueToSet - 1); if (mInfo.miningProgress >= 100.0f && (world instanceof ServerLevel)) { mInfo.pos = null; mInfo.miningProgress = 0.0f; if (CHAINSAW_MATERIALS.contains(state.m_60767_()) || CHAINSAW_BLOCKS.contains(state.getBlock())) { destroyGrid(world, pos, 3, 3); if (state.m_60767_() != Material.LEAVES) { itemStack.hurtAndBreak(3, player, x -> { }); } } else { itemStack.hurtAndBreak(6, player, x2 -> { }); } world.destroyBlockProgress(player.getId(), pos, 10); return world.m_46961_(pos, true); } return false; } public boolean destroyIfPossible(Level world, BlockPos pos) { BlockState state = world.getBlockState(pos); if (CHAINSAW_MATERIALS.contains(state.m_60767_()) || CHAINSAW_BLOCKS.contains(state.getBlock())) { return world.m_46961_(pos, true); } return false; } private HitResult getRayTraceForPlayer(Level world, Player player) { double d0; double d02 = Minecraft.getInstance().gameMode.getPickRange(); HitResult rayTrace = Item.getPlayerPOVHitResult(world, player, ClipContext.Fluid.NONE); Vec3 Vec3 = player.getEyePosition(1.0f); boolean flag = false; double d1 = d02; if (Minecraft.getInstance().gameMode.hasFarPickRange()) { d1 = 6.0d; d0 = 6.0d; } else { if (d02 > 3.0d) { flag = true; } d0 = d02; } double d12 = d1 * d1; if (rayTrace != null) { d12 = rayTrace.getLocation().distanceToSqr(Vec3); } Vec3 Vec31 = player.getViewVector(1.0f); Vec3 Vec32 = Vec3.add(Vec31.x * d0, Vec31.y * d0, Vec31.z * d0); AABB axisalignedbb = player.getBoundingBox().expandTowards(Vec31.scale(d0)).inflate(1.0d, 1.0d, 1.0d); HitResult entityHitResult = ProjectileUtil.getEntityHitResult(player, Vec3, Vec32, axisalignedbb, entity -> { return !entity.isSpectator() && entity.isPickable(); }, d12); if (entityHitResult != null) { entityHitResult.getEntity(); Vec3 Vec33 = entityHitResult.getLocation(); double d2 = Vec3.distanceToSqr(Vec33); if (flag && d2 > 9.0d) { rayTrace = BlockHitResult.miss(Vec33, Direction.getNearest(Vec31.x, Vec31.y, Vec31.z), new BlockPos(Vec33)); } else if (d2 < d12 || rayTrace == null) { rayTrace = entityHitResult; } } return rayTrace; } public void appendHoverText(ItemStack itemStack, @Nullable Level world, List text, TooltipFlag flag) { text.add(new TextComponent("Right click to use")); text.add(new TextComponent("* Highly effective on trees and leaves")); } public void releaseUsing(ItemStack itemStack, Level p_77615_2_, LivingEntity entity, int p_77615_4_) { if (entity instanceof Player) { Player player = (Player) entity; player.stopUsingItem(); MiningInfo mInfo = mineMap.get(player); if (mInfo != null) { mInfo.pos = null; } } } public int getUseDuration(ItemStack stack) { return 72000; } public InteractionResultHolder use(Level world, Player player, InteractionHand p_77659_3_) { ItemStack itemStack = player.getItemInHand(p_77659_3_); player.startUsingItem(p_77659_3_); return InteractionResultHolder.consume(itemStack); } }