package at.hannibal2.skyhanni.data import at.hannibal2.skyhanni.events.ActionBarUpdateEvent import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent import at.hannibal2.skyhanni.events.ProfileJoinEvent import at.hannibal2.skyhanni.events.SkillExpGainEvent import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.name import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.NumberUtil.formatLong import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import net.minecraftforge.fml.common.eventhandler.SubscribeEvent class SkillExperience { private val patternGroup = RepoPattern.group("data.skill") private val actionBarPattern by patternGroup.pattern( "actionbar", ".*§3\\+.* (?<skill>.*) \\((?<overflow>.*)/(?<needed>.*)\\).*" ) private val inventoryPattern by patternGroup.pattern( "inventory", ".* §e(?<number>.*)§6/.*" ) private val actionBarLowLevelPattern by patternGroup.pattern( "actionbarlow", ".*§3+(?<add>.+) (?<skill>.*) \\((?<percentage>.*)%\\).*" ) @SubscribeEvent fun onProfileJoin(event: ProfileJoinEvent) { skillExp.clear() } @SubscribeEvent fun onActionBarUpdate(event: ActionBarUpdateEvent) { if (!LorenzUtils.inSkyBlock) return actionBarPattern.matchMatcher(event.actionBar) { val skill = group("skill").lowercase() val overflow = group("overflow").formatLong() val neededForNextLevel = group("needed").formatLong() val nextLevel = getLevelForExpExactly(neededForNextLevel) val baseExp = getExpForLevel(nextLevel - 1) val totalExp = baseExp + overflow skillExp[skill] = totalExp SkillExpGainEvent(skill).postAndCatch() } actionBarLowLevelPattern.matchMatcher(event.actionBar) { val skill = group("skill").lowercase() SkillExpGainEvent(skill).postAndCatch() } } @SubscribeEvent fun onInventoryOpen(event: InventoryFullyOpenedEvent) { if (event.inventoryName != "Your Skills") return for ((_, stack) in event.inventoryItems) { val name = stack.name.removeColor() if (!name.contains(" ")) continue val lore = stack.getLore() var next = false for (line in lore) { if (line.contains("Progress to Level")) { next = true continue } if (next) { val split = name.split(" ") val skillName = split[0].lowercase() val level = split[1].romanToDecimal() val baseExp = getExpForLevel(level) inventoryPattern.matchMatcher(line) { val overflow = group("number").formatLong() val experience = baseExp + overflow skillExp[skillName] = experience } next = false } } } if (skillExp.isNotEmpty()) return } companion object { private val skillExp = mutableMapOf<String, Long>() private fun getLevelForExpExactly(experience: Long): Int { var level = 1 for (levelXp in levelingExp) { if (levelXp.toLong() == experience) { return level } level++ } return 0 } fun getExpForNextLevel(requestedLevel: Int) = levelingExp[requestedLevel] fun getExpForLevel(requestedLevel: Int): Long { var total = 0L var level = 0 for (levelXp in levelingExp) { total += levelXp level++ if (level == requestedLevel) { return total } } return 0 } // TODO create additional event fun getExpForSkill(skillName: String) = skillExp[skillName.lowercase()] ?: 0 private val levelingExp = listOf( 50, 125, 200, 300, 500, 750, 1000, 1500, 2000, 3500, 5000, 7500, 10000, 15000, 20000, 30000, 50000, 75000, 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000, 1100000, 1200000, 1300000, 1400000, 1500000, 1600000, 1700000, 1800000, 1900000, 2000000, 2100000, 2200000, 2300000, 2400000, 2500000, 2600000, 2750000, 2900000, 3100000, 3400000, 3700000, 4000000, 4300000, 4600000, 4900000, 5200000, 5500000, 5800000, 6100000, 6400000, 6700000, 7000000 ) } }