package at.hannibal2.skyhanni.features.fishing import at.hannibal2.skyhanni.data.jsonobjects.repo.ItemsJson import at.hannibal2.skyhanni.events.FishingBobberCastEvent import at.hannibal2.skyhanni.events.FishingBobberInWaterEvent import at.hannibal2.skyhanni.events.ItemInHandChangeEvent import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.events.RepositoryReloadEvent import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager import at.hannibal2.skyhanni.features.fishing.trophy.TrophyFishManager.getFilletValue import at.hannibal2.skyhanni.features.fishing.trophy.TrophyRarity import at.hannibal2.skyhanni.utils.BlockUtils.getBlockAt import at.hannibal2.skyhanni.utils.ItemCategory import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.ItemUtils.getItemCategoryOrNull import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.NEUInternalName import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.getLorenzVec import net.minecraft.client.Minecraft import net.minecraft.entity.item.EntityArmorStand import net.minecraft.entity.projectile.EntityFishHook import net.minecraft.init.Blocks import net.minecraft.item.ItemStack import net.minecraftforge.event.entity.EntityJoinWorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent object FishingAPI { val lavaBlocks = listOf(Blocks.lava, Blocks.flowing_lava) private val waterBlocks = listOf(Blocks.water, Blocks.flowing_water) var lastCastTime = SimpleTimeMark.farPast() var holdingRod = false var holdingLavaRod = false var holdingWaterRod = false private var lavaRods = listOf() private var waterRods = listOf() var bobber: EntityFishHook? = null var bobberHasTouchedWater = false @SubscribeEvent fun onJoinWorld(event: EntityJoinWorldEvent) { if (!LorenzUtils.inSkyBlock || !holdingRod) return val entity = event.entity ?: return if (entity !is EntityFishHook) return if (entity.angler != Minecraft.getMinecraft().thePlayer) return lastCastTime = SimpleTimeMark.now() bobber = entity bobberHasTouchedWater = false FishingBobberCastEvent(entity).postAndCatch() } private fun resetBobber() { bobber = null bobberHasTouchedWater = false } @SubscribeEvent fun onWorldChange(event: LorenzWorldChangeEvent) { resetBobber() } @SubscribeEvent fun onTick(event: LorenzTickEvent) { if (!LorenzUtils.inSkyBlock) return val bobber = bobber ?: return if (bobber.isDead) { resetBobber() } else { if (!bobberHasTouchedWater) { val block = bobber.getLorenzVec().getBlockAt() if (block in getAllowedBlocks()) { bobberHasTouchedWater = true FishingBobberInWaterEvent().postAndCatch() } } } } fun ItemStack.isFishingRod() = getInternalName().isFishingRod() fun NEUInternalName.isFishingRod() = isLavaRod() || isWaterRod() fun NEUInternalName.isLavaRod() = this in lavaRods fun NEUInternalName.isWaterRod() = this in waterRods fun ItemStack.isBait(): Boolean = stackSize == 1 && getItemCategoryOrNull() == ItemCategory.FISHING_BAIT @SubscribeEvent fun onItemInHandChange(event: ItemInHandChangeEvent) { // TODO correct rod type per island water/lava holdingRod = event.newItem.isFishingRod() holdingLavaRod = event.newItem.isLavaRod() holdingWaterRod = event.newItem.isWaterRod() } @SubscribeEvent fun onRepoReload(event: RepositoryReloadEvent) { val data = event.getConstant("Items") lavaRods = data.lava_fishing_rods waterRods = data.water_fishing_rods } private fun getAllowedBlocks() = if (holdingLavaRod) lavaBlocks else waterBlocks fun getFilletPerTrophy(internalName: NEUInternalName): Int { val internal = internalName.asString() val trophyFishName = internal.substringBeforeLast("_") .replace("_", "").lowercase() val trophyRarityName = internal.substringAfterLast("_") val info = TrophyFishManager.getInfo(trophyFishName) val rarity = TrophyRarity.getByName(trophyRarityName) ?: TrophyRarity.BRONZE return info?.getFilletValue(rarity) ?: 0 } fun isFishing(checkRodInHand: Boolean = true) = IsFishingDetection.isFishing || (checkRodInHand && holdingRod) fun seaCreatureCount(entity: EntityArmorStand): Int { val name = entity.name // a dragon, will always be fought if (name == "Reindrake") return 0 // a npc shop if (name == "ยง5Frosty the Snow Blaster") return 0 if (name == "Frosty") { val npcLocation = LorenzVec(-1.5, 76.0, 92.5) if (entity.getLorenzVec().distance(npcLocation) < 1) { return 0 } } val isSummonedSoul = name.contains("'") val hasFishingMobName = SeaCreatureManager.allFishingMobs.keys.any { name.contains(it) } if (!hasFishingMobName || isSummonedSoul) return 0 if (name == "Sea Emperor" || name == "Rider of the Deep") { return 2 } return 1 } }