diff options
23 files changed, 1102 insertions, 413 deletions
diff --git a/Update Notes/2.1.1.md b/Update Notes/2.1.1.md index 0b7cc4a3..b5f660a4 100644 --- a/Update Notes/2.1.1.md +++ b/Update Notes/2.1.1.md @@ -7,6 +7,7 @@ - Added Custom Wither Cloak - Cobble8 - Added universal GUI editor - nopo - Added Essenceupgrades GUI - Lulonaut +- Added Katsitting recipe upgrade - nea89 ### **Minor Changes:** diff --git a/build.gradle.kts b/build.gradle.kts index a93fccfc..04207cf2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -174,6 +174,7 @@ val kotlinDependencyCollectionJar by tasks.creating(Zip::class) { tasks.shadowJar { archiveClassifier.set("dep-dev") + archiveBaseName.set("NotEnoughUpdates") configurations = listOf(shadowImplementation, shadowApi) exclude("**/module-info.class", "LICENSE.txt") dependencies { diff --git a/settings.gradle.kts b/settings.gradle.kts index eb291fb5..408d0f75 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -38,3 +38,5 @@ pluginManagement { } } } + +rootProject.name = "NotEnoughUpdates" diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index 32c8aa31..286f667a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -82,6 +82,7 @@ import io.github.moulberry.notenoughupdates.overlays.EquipmentOverlay; import io.github.moulberry.notenoughupdates.overlays.FuelBar; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; +import io.github.moulberry.notenoughupdates.recipes.KatRecipe; import io.github.moulberry.notenoughupdates.recipes.RecipeGenerator; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.SBInfo; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java index 5ee31aa9..69033345 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java @@ -19,17 +19,20 @@ package io.github.moulberry.notenoughupdates.commands.dev; +import com.google.gson.Gson; import io.github.moulberry.notenoughupdates.BuildFlags; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.core.config.GuiPositionEditor; import io.github.moulberry.notenoughupdates.core.util.MiscUtils; import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager; +import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.util.PronounDB; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.TabListUtils; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java index d9a00370..1e3dd7e0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/listener/ItemTooltipListener.java @@ -32,6 +32,7 @@ import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.PetLeveling; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiChest; @@ -553,7 +554,7 @@ public class ItemTooltipListener { if (event.toolTip.size() < 7) return; if (event.itemStack.getTagCompound().hasKey("NEUHIDEPETTOOLTIP")) return; if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) { - GuiProfileViewer.PetLevel petLevel; + PetLeveling.PetLevel petLevel; int xpLine = -1; for (int i = event.toolTip.size() - 1; i >= 0; i--) { @@ -581,9 +582,9 @@ public class ItemTooltipListener { event.toolTip.add( xpLine + 1, - EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petLevel.levelXp) + + EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petLevel.getExpInCurrentLevel()) + EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + - myFormatter.format(petLevel.currentLevelRequirement) + myFormatter.format(petLevel.getExpRequiredForNextLevel()) ); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java index 4fc63734..ee5eef9e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/ItemCooldowns.java @@ -104,7 +104,7 @@ public class ItemCooldowns { pet.petType.equalsIgnoreCase("monkey") && pet.rarity.equals(PetInfoOverlay.Rarity.LEGENDARY) ) { - return 2000 - (int) (2000 * (0.005 * (int) pet.petLevel.level)); + return 2000 - (int) (2000 * (0.005 * pet.petLevel.getCurrentLevel())); } } return 2000; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java index 20fa553f..61ebf7b5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscfeatures/PetInfoOverlay.java @@ -35,9 +35,9 @@ import io.github.moulberry.notenoughupdates.listener.RenderListener; import io.github.moulberry.notenoughupdates.options.NEUConfig; import io.github.moulberry.notenoughupdates.overlays.TextOverlay; import io.github.moulberry.notenoughupdates.overlays.TextOverlayStyle; -import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.PetLeveling; import io.github.moulberry.notenoughupdates.util.ProfileApiSyncer; import io.github.moulberry.notenoughupdates.util.Utils; import io.github.moulberry.notenoughupdates.util.XPInformation; @@ -125,24 +125,26 @@ public class PetInfoOverlay extends TextOverlay { } return COMMON; } - } - - public static class Pet { - public String petType; - public Rarity rarity; - public GuiProfileViewer.PetLevel petLevel; - public String petXpType; - public String petItem; - public String skin; - public int candyUsed; - public String getPetId(boolean withoutBoost) { - boolean shouldDecreaseRarity = withoutBoost && "PET_ITEM_TIER_BOOST".equals(petItem); - return petType + ";" + (shouldDecreaseRarity ? rarity.petId - 1 : rarity.petId); + public PetInfoOverlay.Rarity nextRarity() { + switch (this) { + case COMMON: + return PetInfoOverlay.Rarity.UNCOMMON; + case UNCOMMON: + return PetInfoOverlay.Rarity.RARE; + case RARE: + return PetInfoOverlay.Rarity.EPIC; + case EPIC: + return PetInfoOverlay.Rarity.LEGENDARY; + case LEGENDARY: + return PetInfoOverlay.Rarity.MYTHIC; + } + return null; } - } + private static final HashMap<Integer, Integer> removeMap = new HashMap<>(); + public static class PetConfig { public HashMap<Integer, Pet> petMap = new HashMap<>(); @@ -221,33 +223,7 @@ public class PetInfoOverlay extends TextOverlay { return config.petMap.get(config.selectedPet2); } - public float getLevelPercent(Pet pet) { - DecimalFormat df = new DecimalFormat("#.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); - if (pet == null) return 0; - try { - return Float.parseFloat(df.format(pet.petLevel.levelPercentage * 100f)); - } catch (Exception ignored) { - return 0; - } - } - - private static int getIdForPet(Pet pet) { - for (Map.Entry<Integer, Pet> entry : config.petMap.entrySet()) { - if (entry.getValue() == pet) { - return entry.getKey(); - } - } - return -1; - } - - private static int getClosestPetIndex(String petType, int petId, String petItem, float petLevel) { - Pet pet = getClosestPet(petType, petId, petItem, petLevel); - if (pet == null) { - return -1; - } else { - return getIdForPet(pet); - } - } + private final HashMap<String, Float> skillInfoMapLast = new HashMap<>(); private static Pet getClosestPet(String petType, int petId, String petItem, float petLevel) { Set<Pet> pets = config.petMap.values().stream().filter(pet -> pet.petType.equals(petType) && @@ -278,7 +254,7 @@ public class PetInfoOverlay extends TextOverlay { Pet closestPet = null; for (Pet pet : pets) { - float distXp = Math.abs(pet.petLevel.level - petLevel); + float distXp = Math.abs(pet.petLevel.getCurrentLevel() - petLevel); if (closestPet == null || distXp < closestXp) { closestXp = distXp; @@ -289,6 +265,24 @@ public class PetInfoOverlay extends TextOverlay { return closestPet; } + private static int getIdForPet(Pet pet) { + for (Map.Entry<Integer, Pet> entry : config.petMap.entrySet()) { + if (entry.getValue() == pet) { + return entry.getKey(); + } + } + return -1; + } + + private static int getClosestPetIndex(String petType, int petId, String petItem, float petLevel) { + Pet pet = getClosestPet(petType, petId, petItem, petLevel); + if (pet == null) { + return -1; + } else { + return getIdForPet(pet); + } + } + private static void getAndSetPet(ProfileViewer.Profile profile) { Map<String, ProfileViewer.Level> skyblockInfo = profile.getSkyblockInfo(profile.getLatestProfile()); JsonObject invInfo = profile.getInventoryInfo(profile.getLatestProfile()); @@ -401,21 +395,129 @@ public class PetInfoOverlay extends TextOverlay { return interp; } + public static Pet getPetFromStack(NBTTagCompound tag) { + if (Constants.PETS == null || Constants.PETS.get("pet_levels") == null || + Constants.PETS.get("pet_levels") instanceof JsonNull) { + Utils.showOutdatedRepoNotification(); + return null; + } + + String petType = null; + Rarity rarity = null; + String heldItem = null; + PetLeveling.PetLevel level = null; + String skin = null; + + if (tag != null && tag.hasKey("ExtraAttributes")) { + NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); + if (ea.hasKey("petInfo")) { + JsonObject petInfo = new JsonParser().parse(ea.getString("petInfo")).getAsJsonObject(); + petType = petInfo.get("type").getAsString(); + rarity = Rarity.valueOf(petInfo.get("tier").getAsString()); + // Should only default if from item list and repo missing exp: 0 + level = PetLeveling.getPetLevelingForPet(petType, rarity) + .getPetLevel(Utils.getElementAsFloat(petInfo.get("exp"), 0)); + if (petInfo.has("heldItem")) { + heldItem = petInfo.get("heldItem").getAsString(); + } + if (petInfo.has("skin")) { + skin = "PET_SKIN_" + petInfo.get("skin").getAsString(); + } + } + } + + if (petType == null) { + return null; + } + + Pet pet = new Pet(); + pet.petItem = heldItem; + pet.petLevel = level; + pet.rarity = rarity; + pet.petType = petType; + JsonObject petTypes = Constants.PETS.get("pet_types").getAsJsonObject(); + pet.petXpType = + petTypes.has(pet.petType) ? petTypes.get(pet.petType.toUpperCase()).getAsString().toLowerCase() : "unknown"; + pet.skin = skin; + + return pet; + } + + public static float getXpGain(Pet pet, float xp, String xpType) { + if (pet.petLevel.getCurrentLevel() >= pet.petLevel.getMaxLevel()) return 0; + + if (validXpTypes == null) + validXpTypes = Lists.newArrayList("mining", "foraging", "enchanting", "farming", "combat", "fishing", "alchemy"); + if (!validXpTypes.contains(xpType.toLowerCase())) return 0; + + float tamingPercent = 1.0f + (config.tamingLevel / 100f); + xp = xp * tamingPercent; + xp = xp + (xp * config.beastMultiplier / 100f); + if (pet.petXpType != null && !pet.petXpType.equalsIgnoreCase(xpType)) { + xp = xp / 3f; + + if (xpType.equalsIgnoreCase("alchemy") || xpType.equalsIgnoreCase("enchanting")) { + xp = xp / 4f; + } + } + if (xpType.equalsIgnoreCase("mining") || xpType.equalsIgnoreCase("fishing")) { + xp = xp * 1.5f; + } + if (pet.petItem != null) { + Matcher petItemMatcher = XP_BOOST_PATTERN.matcher(pet.petItem); + if ((petItemMatcher.matches() && petItemMatcher.group(1).equalsIgnoreCase(xpType)) + || pet.petItem.equalsIgnoreCase("ALL_SKILLS_SUPER_BOOST")) { + xp = xp * getBoostMultiplier(pet.petItem); + } + } + return xp; + } + + @Override + public void updateFrequent() { + Pet currentPet = getCurrentPet(); + if (!NotEnoughUpdates.INSTANCE.config.petOverlay.enablePetInfo || currentPet == null) { + overlayStrings = null; + } else { + overlayStrings = new ArrayList<>(); + + overlayStrings.addAll(createStringsForPet(currentPet, false)); + + Pet currentPet2 = getCurrentPet2(); + if (currentPet2 != null) { + overlayStrings.add(""); + overlayStrings.addAll(createStringsForPet(currentPet2, true)); + } + + } + } + + public float getLevelPercent(Pet pet) { + DecimalFormat df = new DecimalFormat("#.#", DecimalFormatSymbols.getInstance(Locale.ENGLISH)); + if (pet == null) return 0; + try { + return Float.parseFloat(df.format(pet.petLevel.getPercentageToNextLevel() * 100f)); + } catch (Exception ignored) { + return 0; + } + } + private List<String> createStringsForPet(Pet currentPet, boolean secondPet) { - float levelXp = currentPet.petLevel.levelXp; - if (!secondPet) levelXp = interp(currentPet.petLevel.levelXp, levelXpLast); + float levelXp = currentPet.petLevel.getExpInCurrentLevel(); + if (!secondPet) levelXp = interp(currentPet.petLevel.getExpInCurrentLevel(), levelXpLast); if (levelXp < 0) levelXp = 0; String petName = - EnumChatFormatting.GREEN + "[Lvl " + (int) currentPet.petLevel.level + "] " + currentPet.rarity.chatFormatting + + EnumChatFormatting.GREEN + "[Lvl " + currentPet.petLevel.getCurrentLevel() + "] " + + currentPet.rarity.chatFormatting + WordUtils.capitalizeFully(currentPet.petType.replace("_", " ")); String lvlStringShort = EnumChatFormatting.AQUA + "" + roundFloat(levelXp) + "/" + - roundFloat(currentPet.petLevel.currentLevelRequirement) + roundFloat(currentPet.petLevel.getExpRequiredForNextLevel()) + EnumChatFormatting.YELLOW + " (" + getLevelPercent(currentPet) + "%)"; String lvlString = EnumChatFormatting.AQUA + "" + Utils.shortNumberFormat(levelXp, 0) + "/" + - Utils.shortNumberFormat(currentPet.petLevel.currentLevelRequirement, 0) + Utils.shortNumberFormat(currentPet.petLevel.getExpRequiredForNextLevel(), 0) + EnumChatFormatting.YELLOW + " (" + getLevelPercent(currentPet) + "%)"; float xpGain; @@ -438,7 +540,8 @@ public class PetInfoOverlay extends TextOverlay { } String totalXpString = - EnumChatFormatting.AQUA + "Total XP: " + EnumChatFormatting.YELLOW + roundFloat(currentPet.petLevel.totalXp); + EnumChatFormatting.AQUA + "Total XP: " + EnumChatFormatting.YELLOW + + roundFloat(currentPet.petLevel.getExpTotal()); String petItemStr = EnumChatFormatting.AQUA + "Held Item: " + EnumChatFormatting.RED + "None"; if (currentPet.petItem != null) { @@ -451,27 +554,27 @@ public class PetInfoOverlay extends TextOverlay { String etaStr = null; String etaMaxStr = null; - if (currentPet.petLevel.level < currentPet.petLevel.maxLevel) { - float remaining = currentPet.petLevel.currentLevelRequirement - currentPet.petLevel.levelXp; + if (currentPet.petLevel.getCurrentLevel() < currentPet.petLevel.getMaxLevel()) { + float remaining = currentPet.petLevel.getExpRequiredForNextLevel() - currentPet.petLevel.getExpInCurrentLevel(); if (remaining > 0) { if (xpGain < 1000) { - etaStr = EnumChatFormatting.AQUA + "Until L" + (int) (currentPet.petLevel.level + 1) + ": " + + etaStr = EnumChatFormatting.AQUA + "Until L" + (currentPet.petLevel.getCurrentLevel() + 1) + ": " + EnumChatFormatting.YELLOW + "N/A"; } else { - etaStr = EnumChatFormatting.AQUA + "Until L" + (int) (currentPet.petLevel.level + 1) + ": " + + etaStr = EnumChatFormatting.AQUA + "Until L" + (currentPet.petLevel.getCurrentLevel() + 1) + ": " + EnumChatFormatting.YELLOW + Utils.prettyTime((long) (remaining) * 1000 * 60 * 60 / (long) xpGain); } } - if (currentPet.petLevel.level < (currentPet.petLevel.maxLevel - 1) || + if (currentPet.petLevel.getCurrentLevel() < (currentPet.petLevel.getMaxLevel() - 1) || !NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayText.contains(6)) { - float remainingMax = currentPet.petLevel.maxXP - currentPet.petLevel.totalXp; + float remainingMax = currentPet.petLevel.getExpRequiredForMaxLevel() - currentPet.petLevel.getExpTotal(); if (remaining > 0) { if (xpGain < 1000) { - etaMaxStr = EnumChatFormatting.AQUA + "Until L" + (int) currentPet.petLevel.maxLevel + ": " + + etaMaxStr = EnumChatFormatting.AQUA + "Until L" + currentPet.petLevel.getMaxLevel() + ": " + EnumChatFormatting.YELLOW + "N/A"; } else { - etaMaxStr = EnumChatFormatting.AQUA + "Until L" + (int) currentPet.petLevel.maxLevel + ": " + + etaMaxStr = EnumChatFormatting.AQUA + "Until L" + currentPet.petLevel.getMaxLevel() + ": " + EnumChatFormatting.YELLOW + Utils.prettyTime((long) (remainingMax) * 1000 * 60 * 60 / (long) xpGain); } } @@ -514,25 +617,6 @@ public class PetInfoOverlay extends TextOverlay { }}; } - @Override - public void updateFrequent() { - Pet currentPet = getCurrentPet(); - if (!NotEnoughUpdates.INSTANCE.config.petOverlay.enablePetInfo || currentPet == null) { - overlayStrings = null; - } else { - overlayStrings = new ArrayList<>(); - - overlayStrings.addAll(createStringsForPet(currentPet, false)); - - Pet currentPet2 = getCurrentPet2(); - if (currentPet2 != null) { - overlayStrings.add(""); - overlayStrings.addAll(createStringsForPet(currentPet2, true)); - } - - } - } - public void update() { if (!NotEnoughUpdates.INSTANCE.config.petOverlay.enablePetInfo && !NotEnoughUpdates.INSTANCE.config.itemOverlays.enableMonkeyCheck) { @@ -551,195 +635,11 @@ public class PetInfoOverlay extends TextOverlay { overlayStrings = null; } else { lastUpdate = System.currentTimeMillis(); - levelXpLast = currentPet.petLevel.levelXp; + levelXpLast = currentPet.petLevel.getExpInCurrentLevel(); updatePetLevels(); } } - public static Pet getPetFromStack(NBTTagCompound tag) { - if (Constants.PETS == null || Constants.PETS.get("pet_levels") == null || - Constants.PETS.get("pet_levels") instanceof JsonNull) { - Utils.showOutdatedRepoNotification(); - return null; - } - - String petType = null; - Rarity rarity = null; - String heldItem = null; - GuiProfileViewer.PetLevel level = null; - String skin = null; - - if (tag != null && tag.hasKey("ExtraAttributes")) { - NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); - if (ea.hasKey("petInfo")) { - JsonObject petInfo = new JsonParser().parse(ea.getString("petInfo")).getAsJsonObject(); - petType = petInfo.get("type").getAsString(); - rarity = Rarity.valueOf(petInfo.get("tier").getAsString()); - level = GuiProfileViewer.getPetLevel( - petType, - rarity.name(), - Utils.getElementAsFloat(petInfo.get("exp"), 0) // Should only default if from item list and repo missing exp:0 - ); - if (petInfo.has("heldItem")) { - heldItem = petInfo.get("heldItem").getAsString(); - } - if (petInfo.has("skin")) { - skin = "PET_SKIN_" + petInfo.get("skin").getAsString(); - } - } - } - - if (petType == null) { - return null; - } - - Pet pet = new Pet(); - pet.petItem = heldItem; - pet.petLevel = level; - pet.rarity = rarity; - pet.petType = petType; - JsonObject petTypes = Constants.PETS.get("pet_types").getAsJsonObject(); - pet.petXpType = - petTypes.has(pet.petType) ? petTypes.get(pet.petType.toUpperCase()).getAsString().toLowerCase() : "unknown"; - pet.skin = skin; - - return pet; - } - - private static final HashMap<Integer, Integer> removeMap = new HashMap<>(); - - @SubscribeEvent - public void onTick(TickEvent.ClientTickEvent event) { - if (Minecraft.getMinecraft().currentScreen instanceof GuiChest && RenderListener.inventoryLoaded) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest container = (ContainerChest) chest.inventorySlots; - IInventory lower = container.getLowerChestInventory(); - String containerName = lower.getDisplayName().getUnformattedText(); - - if (lower.getSizeInventory() >= 54) { - int page = 0; - int maxPage = 1; - boolean isPets = false; - - if (containerName.equals("Pets")) { - isPets = true; - } else { - Matcher matcher = PET_CONTAINER_PAGE.matcher(containerName); - if (matcher.matches()) { - try { - page = Integer.parseInt(matcher.group(1)) - 1; - maxPage = Integer.parseInt(matcher.group(2)); - isPets = true; - } catch (NumberFormatException ignored) { - } - } - } - if (isPets) { - boolean hasItem = false; - for (int i = 0; i < lower.getSizeInventory(); i++) { - if (lower.getStackInSlot(i) != null) { - hasItem = true; - break; - } - } - if (!hasItem) return; - - Set<Integer> clear = new HashSet<>(); - for (int i : config.petMap.keySet()) { - if (i >= maxPage * 28) { - clear.add(i); - } - } - config.petMap.keySet().removeAll(clear); - - Set<Integer> removeSet = new HashSet<>(); - long currentTime = System.currentTimeMillis(); - for (int index = 0; index < 28; index++) { - int petIndex = page * 28 + index; - int itemIndex = 10 + index + index / 7 * 2; - - ItemStack stack = lower.getStackInSlot(itemIndex); - - if (stack == null || !stack.hasTagCompound()) { - if (index < 27) { - int itemIndexNext = 10 + (index + 1) + (index + 1) / 7 * 2; - ItemStack stackNext = lower.getStackInSlot(itemIndexNext); - - if (stackNext == null || !stackNext.hasTagCompound()) { - int old = removeMap.getOrDefault(petIndex, 0); - if (old >= 20) { - config.petMap.remove(petIndex); - } else { - removeSet.add(petIndex); - removeMap.put(petIndex, old + 1); - } - } - } - } else { - String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound()); - Pet pet = getPetFromStack(stack.getTagCompound()); - if (pet != null) { - config.petMap.put(petIndex, pet); - - if (currentTime - lastPetSelect > 500) { - boolean foundDespawn = false; - for (String line : lore) { - if (line.startsWith("\u00a77\u00a7cClick to despawn")) { - config.selectedPet = petIndex; - foundDespawn = true; - break; - } - if (line.equals("\u00a77\u00a77Selected pet: \u00a7cNone")) { - clearPet(); - } - } - if (!foundDespawn && config.selectedPet == petIndex && currentTime - lastPetSelect > 500) { - clearPet(); - } - } - } - } - } - removeMap.keySet().retainAll(removeSet); - } else if (containerName.equals("Your Equipment")) { - ItemStack petStack = lower.getStackInSlot(47); - if (petStack != null && petStack.getItem() == Items.skull) { - NBTTagCompound tag = petStack.getTagCompound(); - - if (tag.hasKey("ExtraAttributes", 10)) { - NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); - if (ea.hasKey("petInfo")) { - JsonParser jsonParser = new JsonParser(); - - JsonObject petInfoObject = jsonParser.parse(ea.getString("petInfo")).getAsJsonObject(); - - JsonObject jsonStack = NotEnoughUpdates.INSTANCE.manager.getJsonForItem(petStack); - if (jsonStack == null || !jsonStack.has("lore") || !petInfoObject.has("exp")) { - return; - } - - int rarity = Utils.getRarityFromLore(jsonStack.get("lore").getAsJsonArray()); - String rarityString = Utils.getRarityFromInt(rarity); - - String name = StringUtils.cleanColour(petStack.getDisplayName()); - name = name.substring(name.indexOf(']') + 1).trim().replace(' ', '_').toUpperCase(); - - float petXp = petInfoObject.get("exp").getAsFloat(); - - double petLevel = GuiProfileViewer.getPetLevel(name, rarityString, petXp).level; - int index = getClosestPetIndex(name, rarity, "", (float) petLevel); - if (index != config.selectedPet) { - clearPet(); - setCurrentPet(index); - } - } - } - } - } - } - } - } - @Override protected Vector2f getSize(List<String> strings) { if (!NotEnoughUpdates.INSTANCE.config.petOverlay.petOverlayIcon) return super.getSize(strings); @@ -922,38 +822,140 @@ public class PetInfoOverlay extends TextOverlay { } } - public static float getXpGain(Pet pet, float xp, String xpType) { - if (pet.petLevel.level >= pet.petLevel.maxLevel) return 0; + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (Minecraft.getMinecraft().currentScreen instanceof GuiChest && RenderListener.inventoryLoaded) { + GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; + ContainerChest container = (ContainerChest) chest.inventorySlots; + IInventory lower = container.getLowerChestInventory(); + String containerName = lower.getDisplayName().getUnformattedText(); - if (validXpTypes == null) - validXpTypes = Lists.newArrayList("mining", "foraging", "enchanting", "farming", "combat", "fishing", "alchemy"); - if (!validXpTypes.contains(xpType.toLowerCase())) return 0; + if (lower.getSizeInventory() >= 54) { + int page = 0; + int maxPage = 1; + boolean isPets = false; - float tamingPercent = 1.0f + (config.tamingLevel / 100f); - xp = xp * tamingPercent; - xp = xp + (xp * config.beastMultiplier / 100f); - if (pet.petXpType != null && !pet.petXpType.equalsIgnoreCase(xpType)) { - xp = xp / 3f; + if (containerName.equals("Pets")) { + isPets = true; + } else { + Matcher matcher = PET_CONTAINER_PAGE.matcher(containerName); + if (matcher.matches()) { + try { + page = Integer.parseInt(matcher.group(1)) - 1; + maxPage = Integer.parseInt(matcher.group(2)); + isPets = true; + } catch (NumberFormatException ignored) { + } + } + } + if (isPets) { + boolean hasItem = false; + for (int i = 0; i < lower.getSizeInventory(); i++) { + if (lower.getStackInSlot(i) != null) { + hasItem = true; + break; + } + } + if (!hasItem) return; - if (xpType.equalsIgnoreCase("alchemy") || xpType.equalsIgnoreCase("enchanting")) { - xp = xp / 4f; - } - } - if (xpType.equalsIgnoreCase("mining") || xpType.equalsIgnoreCase("fishing")) { - xp = xp * 1.5f; - } - if (pet.petItem != null) { - Matcher petItemMatcher = XP_BOOST_PATTERN.matcher(pet.petItem); - if ((petItemMatcher.matches() && petItemMatcher.group(1).equalsIgnoreCase(xpType)) - || pet.petItem.equalsIgnoreCase("ALL_SKILLS_SUPER_BOOST")) { - xp = xp * getBoostMultiplier(pet.petItem); + Set<Integer> clear = new HashSet<>(); + for (int i : config.petMap.keySet()) { + if (i >= maxPage * 28) { + clear.add(i); + } + } + config.petMap.keySet().removeAll(clear); + + Set<Integer> removeSet = new HashSet<>(); + long currentTime = System.currentTimeMillis(); + for (int index = 0; index < 28; index++) { + int petIndex = page * 28 + index; + int itemIndex = 10 + index + index / 7 * 2; + + ItemStack stack = lower.getStackInSlot(itemIndex); + + if (stack == null || !stack.hasTagCompound()) { + if (index < 27) { + int itemIndexNext = 10 + (index + 1) + (index + 1) / 7 * 2; + ItemStack stackNext = lower.getStackInSlot(itemIndexNext); + + if (stackNext == null || !stackNext.hasTagCompound()) { + int old = removeMap.getOrDefault(petIndex, 0); + if (old >= 20) { + config.petMap.remove(petIndex); + } else { + removeSet.add(petIndex); + removeMap.put(petIndex, old + 1); + } + } + } + } else { + String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack.getTagCompound()); + Pet pet = getPetFromStack(stack.getTagCompound()); + if (pet != null) { + config.petMap.put(petIndex, pet); + + if (currentTime - lastPetSelect > 500) { + boolean foundDespawn = false; + for (String line : lore) { + if (line.startsWith("\u00a77\u00a7cClick to despawn")) { + config.selectedPet = petIndex; + foundDespawn = true; + break; + } + if (line.equals("\u00a77\u00a77Selected pet: \u00a7cNone")) { + clearPet(); + } + } + if (!foundDespawn && config.selectedPet == petIndex && currentTime - lastPetSelect > 500) { + clearPet(); + } + } + } + } + } + removeMap.keySet().retainAll(removeSet); + } else if (containerName.equals("Your Equipment")) { + ItemStack petStack = lower.getStackInSlot(47); + if (petStack != null && petStack.getItem() == Items.skull) { + NBTTagCompound tag = petStack.getTagCompound(); + + if (tag.hasKey("ExtraAttributes", 10)) { + NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); + if (ea.hasKey("petInfo")) { + JsonParser jsonParser = new JsonParser(); + + JsonObject petInfoObject = jsonParser.parse(ea.getString("petInfo")).getAsJsonObject(); + + JsonObject jsonStack = NotEnoughUpdates.INSTANCE.manager.getJsonForItem(petStack); + if (jsonStack == null || !jsonStack.has("lore") || !petInfoObject.has("exp")) { + return; + } + + int rarity = Utils.getRarityFromLore(jsonStack.get("lore").getAsJsonArray()); + String rarityString = Utils.getRarityFromInt(rarity); + + String name = StringUtils.cleanColour(petStack.getDisplayName()); + name = name.substring(name.indexOf(']') + 1).trim().replace(' ', '_').toUpperCase(); + + float petXp = petInfoObject.get("exp").getAsFloat(); + + double petLevel = PetLeveling.getPetLevelingForPet(name, Rarity.valueOf(rarityString)) + .getPetLevel(petXp) + .getCurrentLevel(); + int index = getClosestPetIndex(name, rarity, "", (float) petLevel); + if (index != config.selectedPet) { + clearPet(); + setCurrentPet(index); + } + } + } + } + } } } - return xp; } - private final HashMap<String, Float> skillInfoMapLast = new HashMap<>(); - public void updatePetLevels() { HashMap<String, XPInformation.SkillInfo> skillInfoMap = XPInformation.getInstance().getSkillInfoMap(); @@ -991,7 +993,7 @@ public class PetInfoOverlay extends TextOverlay { xpAddTimer--; } - currentPet.petLevel.totalXp += totalGain; + currentPet.petLevel.setExpTotal(totalGain + currentPet.petLevel.getExpTotal()); xpGainQueue.add(0, totalGain); while (xpGainQueue.size() > 30) { @@ -1012,12 +1014,25 @@ public class PetInfoOverlay extends TextOverlay { JsonObject petsJson = Constants.PETS; if (currentPet != null && petsJson != null) { - currentPet.petLevel = GuiProfileViewer.getPetLevel( - currentPet.petType, - currentPet.rarity.name(), - currentPet.petLevel.totalXp - ); + currentPet.petLevel = PetLeveling.getPetLevelingForPet(currentPet.petType, currentPet.rarity) + .getPetLevel(currentPet.petLevel.getExpTotal()); + } + } + + public static class Pet { + public String petType; + public Rarity rarity; + public PetLeveling.PetLevel petLevel; + public String petXpType; + public String petItem; + public String skin; + public int candyUsed; + + public String getPetId(boolean withoutBoost) { + boolean shouldDecreaseRarity = withoutBoost && "PET_ITEM_TIER_BOOST".equals(petItem); + return petType + ";" + (shouldDecreaseRarity ? rarity.petId - 1 : rarity.petId); } + } public String roundFloat(float f) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java index cc9f36fa..e4b4269d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java @@ -28,6 +28,7 @@ import io.github.moulberry.notenoughupdates.recipes.RecipeHistory; import io.github.moulberry.notenoughupdates.recipes.RecipeSlot; import io.github.moulberry.notenoughupdates.recipes.RecipeType; import io.github.moulberry.notenoughupdates.util.Utils; +import lombok.var; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiButton; @@ -314,7 +315,7 @@ public class GuiItemRecipe extends GuiScreen { TAB_SIZE_X, TAB_SIZE_Y )) { - changeRecipe(i, currentIndex); + changeRecipe(i, 0); Utils.playPressSound(); return; } @@ -336,6 +337,16 @@ public class GuiItemRecipe extends GuiScreen { currentRecipe.mouseClicked(this, mouseX, mouseY, mouseButton); } + @Override + public void handleMouseInput() throws IOException { + super.handleMouseInput(); + ScaledResolution scaledResolution = Utils.peekGuiScale(); + int mouseX = Mouse.getX() * scaledResolution.getScaledWidth() / Minecraft.getMinecraft().displayWidth; + int mouseY = scaledResolution.getScaledHeight() - + Mouse.getY() * scaledResolution.getScaledHeight() / Minecraft.getMinecraft().displayHeight - 1; + getCurrentRecipe().genericMouseInput(mouseX, mouseY); + } + public void arrowKeyboardInput() { ArrowPagesUtils.onPageSwitchKey(currentIndex, getCurrentRecipeList().size(), pageChange -> changeRecipe(currentTab, pageChange)); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/KatSitterOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/KatSitterOverlay.java index 62aba35b..288c3926 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/miscgui/KatSitterOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/miscgui/KatSitterOverlay.java @@ -21,8 +21,9 @@ package io.github.moulberry.notenoughupdates.miscgui; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer; -import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; +import io.github.moulberry.notenoughupdates.util.PetLeveling; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; @@ -63,14 +64,21 @@ public class KatSitterOverlay { if (petInfo == null || !petInfo.has("exp") || !petInfo.has("tier") || !petInfo.has("type")) return; String petId = petInfo.get("type").getAsString(); double xp = petInfo.get("exp").getAsDouble(); - String rarity = petInfo.get("tier").getAsString(); + PetInfoOverlay.Rarity rarity = PetInfoOverlay.Rarity.valueOf(petInfo.get("tier").getAsString()); Slot katSlot = container.getSlot(22); - String upgradedRarity = nextRarity(rarity); + PetInfoOverlay.Rarity upgradedRarity = rarity.nextRarity(); boolean nextRarityPresent = katSlot.getStack() != null && katSlot.getStack().getItem() != Item.getItemFromBlock( Blocks.barrier) && upgradedRarity != null; renderPetInformation( - (int) GuiProfileViewer.getPetLevel(petId, rarity, (float) xp).level, - nextRarityPresent ? (int) GuiProfileViewer.getPetLevel(petId, upgradedRarity, (float) xp).level : null, + PetLeveling + .getPetLevelingForPet(petId, rarity) + .getPetLevel(xp) + .getCurrentLevel(), + nextRarityPresent ? + PetLeveling + .getPetLevelingForPet(petId, rarity) + .getPetLevel(xp) + .getCurrentLevel() : null, gui ); } @@ -100,20 +108,6 @@ public class KatSitterOverlay { ); } - public String nextRarity(String currentRarity) { - switch (currentRarity.intern()) { - case "COMMON": - return "UNCOMMON"; - case "UNCOMMON": - return "RARE"; - case "RARE": - return "EPIC"; - case "EPIC": - return "LEGENDARY"; - case "LEGENDARY": - return "MYTHIC"; - } - return null; - } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java index b35f06dc..7edbee6b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/overlays/TimersOverlay.java @@ -358,7 +358,7 @@ public class TimersOverlay extends TextTabOverlay { String[] cleanSplit = clean.split(" "); hidden.cookieBuffRemaining = 0; - for (int i = 0; i < cleanSplit.length; i++) { + for (int i = 0; i + 1 < cleanSplit.length; i++) { if (i % 2 == 1) continue; String number = cleanSplit[i]; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java index cc13e820..63717093 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/GuiProfileViewer.java @@ -231,68 +231,6 @@ public class GuiProfileViewer extends GuiScreen { return xpTotal; } - public static PetLevel getPetLevel( - String petType, - String rarity, - float exp - ) { - int offset = PetInfoOverlay.Rarity.valueOf(rarity).petOffset; - int maxLevel = 100; - - JsonArray levels = new JsonArray(); - levels.addAll(Constants.PETS.get("pet_levels").getAsJsonArray()); - JsonElement customLevelingJson = Constants.PETS.get("custom_pet_leveling").getAsJsonObject().get(petType); - if (customLevelingJson != null) { - switch (Utils.getElementAsInt(Utils.getElement(customLevelingJson, "type"), 0)) { - case 1: - levels.addAll(customLevelingJson.getAsJsonObject().get("pet_levels").getAsJsonArray()); - break; - case 2: - levels = customLevelingJson.getAsJsonObject().get("pet_levels").getAsJsonArray(); - break; - } - maxLevel = Utils.getElementAsInt(Utils.getElement(customLevelingJson, "max_level"), 100); - } - - float maxXP = getMaxLevelXp(levels, offset, maxLevel); - boolean isMaxed = exp >= maxXP; - - int level = 1; - float currentLevelRequirement = 0; - float xpThisLevel = 0; - float pct = 0; - - if (isMaxed) { - level = maxLevel; - currentLevelRequirement = levels.get(offset + level - 2).getAsFloat(); - xpThisLevel = currentLevelRequirement; - pct = 1; - } else { - long totalExp = 0; - for (int i = offset; i < levels.size(); i++) { - currentLevelRequirement = levels.get(i).getAsLong(); - totalExp += currentLevelRequirement; - if (totalExp >= exp) { - xpThisLevel = currentLevelRequirement - (totalExp - exp); - level = Math.min(i - offset + 1, maxLevel); - break; - } - } - pct = currentLevelRequirement != 0 ? xpThisLevel / currentLevelRequirement : 0; - level += pct; - } - - GuiProfileViewer.PetLevel levelObj = new GuiProfileViewer.PetLevel(); - levelObj.level = level; - levelObj.maxLevel = maxLevel; - levelObj.currentLevelRequirement = currentLevelRequirement; - levelObj.maxXP = maxXP; - levelObj.levelPercentage = pct; - levelObj.levelXp = xpThisLevel; - levelObj.totalXp = exp; - return levelObj; - } - @Deprecated public static String shortNumberFormat(double n, int iteration) { return StringUtils.shortNumberFormat(n, iteration @@ -1352,15 +1290,4 @@ public class GuiProfileViewer extends GuiScreen { return Optional.ofNullable(stack); } } - - public static class PetLevel { - - public float level; - public float maxLevel; - public float currentLevelRequirement; - public float maxXP; - public float levelPercentage; - public float levelXp; - public float totalXp; - } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java index cb85bf79..098c252e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PetsPage.java @@ -26,6 +26,7 @@ import io.github.moulberry.notenoughupdates.core.util.StringUtils; import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.ItemUtils; +import io.github.moulberry.notenoughupdates.util.PetLeveling; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; @@ -118,19 +119,18 @@ public class PetsPage extends GuiProfileViewerPage { PetInfoOverlay.Pet parsedPet = new PetInfoOverlay.Pet(); parsedPet.petType = pet.get("type").getAsString(); parsedPet.rarity = PetInfoOverlay.Rarity.valueOf(pet.get("tier").getAsString()); - parsedPet.petLevel = GuiProfileViewer.getPetLevel( + parsedPet.petLevel = PetLeveling.getPetLevelingForPet( parsedPet.petType, - parsedPet.rarity.name(), - pet.get("exp").getAsFloat() - ); + parsedPet.rarity + ).getPetLevel(pet.get("exp").getAsFloat()); parsedPet.petXpType = "unknown"; parsedPet.petItem = Utils.getElementAsString(pet.get("heldItem"), null); parsedPet.skin = Utils.getElementAsString(pet.get("skin"), null); parsedPet.candyUsed = pet.get("candyUsed").getAsInt(); sortedPetsStack.add(ItemUtils.createPetItemstackFromPetInfo(parsedPet)); - pet.addProperty("level", parsedPet.petLevel.level); - pet.addProperty("currentLevelRequirement", parsedPet.petLevel.currentLevelRequirement); - pet.addProperty("maxXP", parsedPet.petLevel.maxXP); + pet.addProperty("level", parsedPet.petLevel.getCurrentLevel()); + pet.addProperty("currentLevelRequirement", parsedPet.petLevel.getExpRequiredForNextLevel()); + pet.addProperty("maxXP", parsedPet.petLevel.getExpRequiredForMaxLevel()); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java index c5a17aef..56ecd3a2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/profileviewer/PlayerStats.java @@ -24,9 +24,11 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; import io.github.moulberry.notenoughupdates.profileviewer.info.QuiverInfo; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.JsonUtils; +import io.github.moulberry.notenoughupdates.util.PetLeveling; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.JsonToNBT; @@ -491,11 +493,13 @@ public class PlayerStats { tierNum = "" + (Integer.parseInt(tierNum) + 1); } - GuiProfileViewer.PetLevel levelObj = GuiProfileViewer.getPetLevel(petname, tier, exp); - if (levelObj == null) return null; - float level = levelObj.level; - float currentLevelRequirement = levelObj.currentLevelRequirement; - float maxXP = levelObj.maxXP; + PetLeveling.PetLevel levelObj = PetLeveling.getPetLevelingForPet( + petname, + PetInfoOverlay.Rarity.valueOf(tier) + ).getPetLevel(exp); + float level = levelObj.getCurrentLevel(); + float currentLevelRequirement = levelObj.getExpRequiredForNextLevel(); + float maxXP = levelObj.getMaxLevel(); pet.addProperty("level", level); pet.addProperty("currentLevelRequirement", currentLevelRequirement); pet.addProperty("maxXP", maxXP); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java index a0090050..9f480085 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/NeuRecipe.java @@ -95,4 +95,6 @@ public interface NeuRecipe { } default void actionPerformed(GuiButton button) {} + + default void genericMouseInput(int mouseX, int mouseY) {} } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java index 087ec6c3..3ef8399f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/recipes/RecipeType.java @@ -31,7 +31,8 @@ public enum RecipeType { TRADE("trade", "Trading", VillagerTradeRecipe::parseStaticRecipe, new ItemStack(Items.emerald)), MOB_LOOT("drops", "Mob Loot", MobLootRecipe::parseRecipe, new ItemStack(Items.diamond_sword)), NPC_SHOP("npc_shop", "NPC Item Shop", ItemShopRecipe::parseItemRecipe, new ItemStack(Items.wheat_seeds)), - ESSENCE_UPGRADES("", "Essence Upgrades", null, new ItemStack(Items.nether_star)); + ESSENCE_UPGRADES("", "Essence Upgrades", null, new ItemStack(Items.nether_star)), + KAT_UPGRADE("katgrade", "Katsitting", KatRecipe::parseRecipe, new ItemStack(Blocks.red_flower)); private final String id; private final String label; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java index 3e2dd465..2ff9692d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/ItemUtils.java @@ -189,6 +189,16 @@ public class ItemUtils { } public static ItemStack createPetItemstackFromPetInfo(PetInfoOverlay.Pet currentPet) { + if (currentPet == null) { + ItemStack stack = ItemUtils.createQuestionMarkSkull(EnumChatFormatting.RED + "Unknown Pet"); + appendLore(stack, Arrays.asList( + "§cNull Pet", + "", + "§cIf you expected it to be there please send a message in", + "§c§l#neu-support §r§con §ldiscord.gg/moulberry" + )); + return stack; + } String petname = currentPet.petType; String tier = Utils.getRarityFromInt(currentPet.rarity.petId).toUpperCase(); String heldItem = currentPet.petItem; @@ -196,11 +206,13 @@ public class ItemUtils { JsonObject heldItemJson = heldItem == null ? null : NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( heldItem); String petId = currentPet.getPetId(false); - float exp = currentPet.petLevel.totalXp; + float exp = currentPet.petLevel.getExpTotal(); - GuiProfileViewer.PetLevel levelObj = GuiProfileViewer.getPetLevel(petname, tier, exp); + PetLeveling.PetLevel levelObj = PetLeveling + .getPetLevelingForPet(petname, PetInfoOverlay.Rarity.valueOf(tier)) + .getPetLevel(exp); - float level = levelObj.level; + int level = levelObj.getCurrentLevel(); ItemStack petItemstack = NotEnoughUpdates.INSTANCE.manager .createItemResolutionQuery() @@ -348,7 +360,7 @@ public class ItemUtils { if (Utils.cleanColour(lore.getStringTagAt(0)).matches(ItemTooltipListener.petToolTipRegex) && lore.tagCount() > 7) { - GuiProfileViewer.PetLevel petLevel; + PetLeveling.PetLevel petLevel; PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack( stack.getTagCompound() @@ -373,13 +385,13 @@ public class ItemUtils { for (int i = 0; i < lore.tagCount(); i++) { if (i == lore.tagCount() - 2) { newLore.appendTag(new NBTTagString("")); - if (petLevel.level >= maxLvl) { + if (petLevel.getCurrentLevel() >= maxLvl) { newLore.appendTag(new NBTTagString( EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + "MAX LEVEL")); } else { - double levelPercent = (Math.round(petLevel.levelPercentage * 1000) / 10.0); + double levelPercent = (Math.round(petLevel.getPercentageToNextLevel() * 1000) / 10.0); newLore.appendTag(new NBTTagString( - EnumChatFormatting.GRAY + "Progress to Level " + (int) (petLevel.level + 1) + ": " + + EnumChatFormatting.GRAY + "Progress to Level " + (petLevel.getCurrentLevel() + 1) + ": " + EnumChatFormatting.YELLOW + levelPercent + "%")); StringBuilder sb = new StringBuilder(); @@ -394,9 +406,9 @@ public class ItemUtils { newLore.appendTag(new NBTTagString(sb.toString())); newLore.appendTag(new NBTTagString( EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + - decimalFormatter.format(petLevel.levelXp) + + decimalFormatter.format(petLevel.getExpInCurrentLevel()) + EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + - decimalFormatter.format(petLevel.currentLevelRequirement) + decimalFormatter.format(petLevel.getExpRequiredForNextLevel()) )); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java index ecc03caf..a3f2296c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/util/Utils.java @@ -79,6 +79,7 @@ import java.nio.FloatBuffer; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.text.DecimalFormat; +import java.time.Duration; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -1766,6 +1767,10 @@ public class Utils { GlStateManager.enableTexture2D(); } + public static String prettyTime(Duration time) { + return prettyTime(time.toMillis()); + } + public static String prettyTime(long millis) { long seconds = millis / 1000 % 60; long minutes = (millis / 1000 / 60) % 60; diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/KatRecipe.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/KatRecipe.kt new file mode 100644 index 00000000..c4b64969 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/recipes/KatRecipe.kt @@ -0,0 +1,164 @@ +/* + * Copyright (C) 2022 Linnea Gräf + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ +package io.github.moulberry.notenoughupdates.recipes + +import com.google.gson.JsonObject +import com.google.gson.JsonPrimitive +import io.github.moulberry.notenoughupdates.NEUManager +import io.github.moulberry.notenoughupdates.core.util.GuiElementSlider +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay.Pet +import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe +import io.github.moulberry.notenoughupdates.util.ItemUtils +import io.github.moulberry.notenoughupdates.util.PetLeveling +import io.github.moulberry.notenoughupdates.util.Utils +import io.github.moulberry.notenoughupdates.util.toJsonArray +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.util.ResourceLocation +import java.time.Duration +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.roundToInt +import kotlin.math.sin + +data class KatRecipe( + val manager: NEUManager, + val inputPet: Ingredient, + val outputPet: Ingredient, + val items: List<Ingredient>, + val coins: Long, + val time: Duration, +) : NeuRecipe { + var inputLevel = 1 + val radius get() = 50 / 2 + val circleCenter get() = 33 + 110 / 2 to 19 + 110 / 2 + val textPosition get() = circleCenter.first to circleCenter.second + 90 / 2 + val sliderPos get() = 40 to 15 + val levelTextPos + get() = sliderPos.first - 4 - Minecraft.getMinecraft().fontRendererObj.getStringWidth("100") to + sliderPos.second + 16 / 2 - Minecraft.getMinecraft().fontRendererObj.FONT_HEIGHT / 2 + + val levelSlider = GuiElementSlider(0, 0, 100, 1F, 100F, 1F, inputLevel.toFloat()) { inputLevel = it.toInt() } + val coinsAdjustedForLevel: Int + get() = (coins.toInt() * (1 - 0.003F * (getOutputPetForCurrentLevel()?.petLevel?.currentLevel ?: 0))).toInt() + private val basicIngredients = items.toSet() + setOf(inputPet, Ingredient.coinIngredient(manager, coins.toInt())) + override fun getIngredients(): Set<Ingredient> = basicIngredients + + override fun getOutputs(): Set<Ingredient> { + return setOf(outputPet) + } + + fun getInputPetForCurrentLevel(): Pet? { + return PetInfoOverlay.getPetFromStack(inputPet.itemStack.tagCompound)?.also { + val petLeveling = PetLeveling.getPetLevelingForPet(it.petType, it.rarity) + it.petLevel = petLeveling.getPetLevel(petLeveling.getPetExpForLevel(inputLevel).toDouble()) + } + } + + fun getOutputPetForCurrentLevel(): Pet? { + return PetInfoOverlay.getPetFromStack(outputPet.itemStack.tagCompound)?.also { + val petLeveling = PetLeveling.getPetLevelingForPet(it.petType, it.rarity) + it.petLevel = petLeveling.getPetLevel(getInputPetForCurrentLevel()?.petLevel?.expTotal?.toDouble() ?: 0.0) + } + } + + private fun positionOnCircle(i: Int, max: Int): Pair<Int, Int> { + val radians = PI * 2 * i / max + val offsetX = cos(radians) * radius + val offsetY = sin(radians) * radius + return (circleCenter.first + offsetX).roundToInt() to (circleCenter.second + offsetY).roundToInt() + } + + override fun drawExtraInfo(gui: GuiItemRecipe, mouseX: Int, mouseY: Int) { + levelSlider.x = gui.guiLeft + sliderPos.first + levelSlider.y = gui.guiTop + sliderPos.second + levelSlider.render() + Minecraft.getMinecraft().fontRendererObj.drawString( + "$inputLevel", + gui.guiLeft + levelTextPos.first, + gui.guiTop + levelTextPos.second, + 0xFF0000 + ) + Utils.drawStringCentered( + Utils.prettyTime(time), + Minecraft.getMinecraft().fontRendererObj, + gui.guiLeft + textPosition.first.toFloat(), gui.guiTop + textPosition.second.toFloat(), + false, 0xff00ff + ) + GlStateManager.color(1F, 1F, 1F, 1F) + } + + override fun genericMouseInput(mouseX: Int, mouseY: Int) { + levelSlider.mouseInput(mouseX, mouseY) + } + + override fun getSlots(): List<RecipeSlot> { + val advancedIngredients = items.map { it.itemStack } + listOf( + ItemUtils.createPetItemstackFromPetInfo(getInputPetForCurrentLevel()), + Ingredient.coinIngredient( + manager, + coinsAdjustedForLevel + ).itemStack + ) + return advancedIngredients.mapIndexed { index, itemStack -> + val (x, y) = positionOnCircle(index, advancedIngredients.size) + RecipeSlot(x - 18 / 2, y - 18 / 2, itemStack) + } + listOf( + RecipeSlot( + circleCenter.first - 9, + circleCenter.second - 9, + ItemUtils.createPetItemstackFromPetInfo(getOutputPetForCurrentLevel()) + ) + ) + } + + override fun getType(): RecipeType = RecipeType.KAT_UPGRADE + + override fun hasVariableCost(): Boolean = false + + override fun serialize(): JsonObject { + return JsonObject().apply { + addProperty("type", type.id) + addProperty("coins", coins) + addProperty("input", inputPet.serialize()) + addProperty("output", outputPet.serialize()) + addProperty("time", time.seconds) + add("items", items.map { JsonPrimitive(it.serialize()) }.toJsonArray()) + } + } + + companion object { + @JvmStatic + fun parseRecipe(manager: NEUManager, recipe: JsonObject, output: JsonObject): NeuRecipe { + return KatRecipe( + manager, + Ingredient(manager, recipe["input"].asString), + Ingredient(manager, recipe["output"].asString), + recipe["items"]?.asJsonArray?.map { Ingredient(manager, it.asString) } ?: emptyList(), + recipe["coins"].asLong, + Duration.ofSeconds(recipe["time"].asLong) + ) + } + } + + override fun getBackground(): ResourceLocation { + return ResourceLocation("notenoughupdates:textures/gui/katting_tall.png") + } +} diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/KotlinJsonUtils.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/KotlinJsonUtils.kt new file mode 100644 index 00000000..95b6f1ac --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/KotlinJsonUtils.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.util + +import com.google.gson.JsonArray +import com.google.gson.JsonElement + + +fun Iterable<JsonElement>.toJsonArray(): JsonArray = JsonArray().also { + for (jsonElement in this) { + it.add(jsonElement) + } +} + diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt new file mode 100644 index 00000000..e7d29642 --- /dev/null +++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2022 Linnea Gräf + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.util + +import com.google.gson.JsonObject +import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay.Rarity +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object PetLeveling { + + data class ExpLadder( + val individualLevelCost: List<Long>, + ) { + val cumulativeLevelCost = individualLevelCost.runningFold(0F) { a, b -> a + b }.map { it.toLong() } + fun getPetLevel(currentExp: Double): PetLevel { + val currentOneIndexedLevel = cumulativeLevelCost.indexOfLast { it <= currentExp } + 1 + val expForNextLevel = if (currentOneIndexedLevel > individualLevelCost.size) { // Max leveled pet + individualLevelCost.last() + } else { + individualLevelCost[currentOneIndexedLevel - 1] + } + val expInCurrentLevel = + if (currentOneIndexedLevel >= cumulativeLevelCost.size) + currentExp.toFloat() - cumulativeLevelCost.last() + else + (expForNextLevel - (cumulativeLevelCost[currentOneIndexedLevel] - currentExp.toFloat())).coerceAtLeast(0F) + return PetLevel( + currentLevel = currentOneIndexedLevel, + maxLevel = cumulativeLevelCost.size, + expRequiredForNextLevel = expForNextLevel, + expRequiredForMaxLevel = cumulativeLevelCost.last(), + expInCurrentLevel = expInCurrentLevel, + expTotal = currentExp.toFloat() + ) + } + + fun getPetExpForLevel(level: Int): Long { + if (level < 2) return 0L + if (level >= cumulativeLevelCost.size) return cumulativeLevelCost.last() + return cumulativeLevelCost[level - 1] + } + } + + data class PetLevel( + val currentLevel: Int, + val maxLevel: Int, + val expRequiredForNextLevel: Long, + val expRequiredForMaxLevel: Long, + val expInCurrentLevel: Float, + var expTotal: Float, + ) { + val percentageToNextLevel: Float = expInCurrentLevel / expRequiredForNextLevel + } + + private data class Key(val petIdWithoutRarity: String, val rarity: Rarity) + + private val cache = mutableMapOf<Key, ExpLadder>() + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + cache.clear() + } + + var petConstants: JsonObject? = null + + @JvmStatic + fun getPetLevelingForPet(petIdWithoutRarity: String, rarity: Rarity): ExpLadder { + return cache.computeIfAbsent(Key(petIdWithoutRarity, rarity)) { + getPetLevelingForPet0( + petIdWithoutRarity, + rarity + ) + } + } + + internal fun getPetLevelingForPet0(petIdWithoutRarity: String, rarity: Rarity): ExpLadder { + val petConstants = this.petConstants ?: Constants.PETS + var levels = petConstants["pet_levels"].asJsonArray.map { it.asLong }.toMutableList() + val customLeveling = petConstants["custom_pet_leveling"].asJsonObject[petIdWithoutRarity] + val offset = petConstants["pet_rarity_offset"].asJsonObject[rarity.name].asInt + var maxLevel = 100 + if (customLeveling is JsonObject) { + val customLevels by lazy { customLeveling["pet_levels"].asJsonArray.map { it.asLong } } + when (customLeveling["type"]?.asInt ?: 0) { + 1 -> levels.addAll(customLevels) + 2 -> levels = customLevels.toMutableList() + } + maxLevel = customLeveling["max_level"]?.asInt ?: maxLevel + } + return ExpLadder(levels.drop(offset).take(maxLevel)) + } + +} diff --git a/src/main/resources/assets/notenoughupdates/textures/gui/katting_tall.png b/src/main/resources/assets/notenoughupdates/textures/gui/katting_tall.png Binary files differnew file mode 100644 index 00000000..f1dfe7e8 --- /dev/null +++ b/src/main/resources/assets/notenoughupdates/textures/gui/katting_tall.png diff --git a/src/test/kotlin/io/github/moulberry/notenoughupdates/util/PetLevelingTest.kt b/src/test/kotlin/io/github/moulberry/notenoughupdates/util/PetLevelingTest.kt new file mode 100644 index 00000000..43a0e3fd --- /dev/null +++ b/src/test/kotlin/io/github/moulberry/notenoughupdates/util/PetLevelingTest.kt @@ -0,0 +1,403 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>. + */ + +package io.github.moulberry.notenoughupdates.util + +import com.google.gson.Gson +import com.google.gson.JsonObject +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test + +internal class PetLevelingTest { + + val testJsonString = """ + { + "pet_rarity_offset": { + "COMMON": 0, + "UNCOMMON": 6, + "RARE": 11, + "EPIC": 16, + "LEGENDARY": 20, + "MYTHIC": 20 + }, + "pet_levels": [ + 100, + 110, + 120, + 130, + 145, + 160, + 175, + 190, + 210, + 230, + 250, + 275, + 300, + 330, + 360, + 400, + 440, + 490, + 540, + 600, + 660, + 730, + 800, + 880, + 960, + 1050, + 1150, + 1260, + 1380, + 1510, + 1650, + 1800, + 1960, + 2130, + 2310, + 2500, + 2700, + 2920, + 3160, + 3420, + 3700, + 4000, + 4350, + 4750, + 5200, + 5700, + 6300, + 7000, + 7800, + 8700, + 9700, + 10800, + 12000, + 13300, + 14700, + 16200, + 17800, + 19500, + 21300, + 23200, + 25200, + 27400, + 29800, + 32400, + 35200, + 38200, + 41400, + 44800, + 48400, + 52200, + 56200, + 60400, + 64800, + 69400, + 74200, + 79200, + 84700, + 90700, + 97200, + 104200, + 111700, + 119700, + 128200, + 137200, + 146700, + 156700, + 167700, + 179700, + 192700, + 206700, + 221700, + 237700, + 254700, + 272700, + 291700, + 311700, + 333700, + 357700, + 383700, + 411700, + 441700, + 476700, + 516700, + 561700, + 611700, + 666700, + 726700, + 791700, + 861700, + 936700, + 1016700, + 1101700, + 1191700, + 1286700, + 1386700, + 1496700, + 1616700, + 1746700, + 1886700 + ], + "custom_pet_leveling": { + "GOLDEN_DRAGON": { + "type": 1, + "pet_levels": [ + 0, + 5555, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700, + 1886700 + ], + "max_level": 200 + } + }, + "pet_types": { + "ROCK": "MINING", + "BAT": "MINING", + "MITHRIL_GOLEM": "MINING", + "WITHER_SKELETON": "MINING", + "SILVERFISH": "MINING", + "ENDERMITE": "MINING", + "BEE": "FARMING", + "CHICKEN": "FARMING", + "PIG": "FARMING", + "RABBIT": "FARMING", + "ELEPHANT": "FARMING", + "BLUE_WHALE": "FISHING", + "DOLPHIN": "FISHING", + "FLYING_FISH": "FISHING", + "BABY_YETI": "FISHING", + "MEGALODON": "FISHING", + "SQUID": "FISHING", + "JELLYFISH": "ALCHEMY", + "SHEEP": "ALCHEMY", + "PARROT": "ALCHEMY", + "MONKEY": "FORAGING", + "GIRAFFE": "FORAGING", + "LION": "FORAGING", + "OCELOT": "FORAGING", + "BLACK_CAT": "COMBAT", + "BLAZE": "COMBAT", + "ENDER_DRAGON": "COMBAT", + "ENDERMAN": "COMBAT", + "GHOUL": "COMBAT", + "GOLEM": "COMBAT", + "GRIFFIN": "COMBAT", + "HORSE": "COMBAT", + "HOUND": "COMBAT", + "JERRY": "COMBAT", + "MAGMA_CUBE": "COMBAT", + "PHOENIX": "COMBAT", + "PIGMAN": "COMBAT", + "SKELETON": "COMBAT", + "SKELETON_HORSE": "COMBAT", + "SNOWMAN": "COMBAT", + "SPIDER": "COMBAT", + "SPIRIT": "COMBAT", + "TARANTULA": "COMBAT", + "TURTLE": "COMBAT", + "TIGER": "COMBAT", + "ZOMBIE": "COMBAT", + "WOLF": "COMBAT", + "GUARDIAN": "ENCHANTING", + "GRANDMA_WOLF": "COMBAT", + "ARMADILLO": "MINING", + "BAL": "COMBAT", + "GOLDEN_DRAGON": "COMBAT", + "RAT": "COMBAT", + "SCATHA": "MINING", + "AMMONITE": "FISHING", + "SNAIL": "MINING", + "MOOSHROOM_COW": "FARMING", + "KUUDRA": "COMBAT" + } + } + """ + + val testJson = Gson().fromJson(testJsonString, JsonObject::class.java) + + @BeforeEach + fun setup() { + PetLeveling.petConstants = testJson + } + + @Test + fun testPetLevelGrandmaWolf() { + val leveling = PetLeveling.getPetLevelingForPet0("GRANDMA_WOLF", PetInfoOverlay.Rarity.LEGENDARY) + val level = leveling.getPetLevel(22_500_000.0) + Assertions.assertEquals(98, level.currentLevel) + Assertions.assertEquals(1746700, level.expRequiredForNextLevel) + Assertions.assertEquals(780170.0F, level.expInCurrentLevel, 0.5F) + } + + @Test + fun testPetLevelCommon() { + val leveling = PetLeveling.getPetLevelingForPet0("BEE", PetInfoOverlay.Rarity.COMMON) + val level = leveling.getPetLevel(197806.0385900295) + Assertions.assertEquals(58, level.currentLevel) + Assertions.assertEquals(19500, level.expRequiredForNextLevel) + Assertions.assertEquals(5321.0F, level.expInCurrentLevel, 0.5F) + } + + @Test + fun testGoldenDragon() { + val leveling = PetLeveling.getPetLevelingForPet0("GOLDEN_DRAGON", PetInfoOverlay.Rarity.LEGENDARY) + val level = leveling.getPetLevel(95179565.04472463) + Assertions.assertEquals(139, level.currentLevel) + Assertions.assertEquals(1886700, level.expRequiredForNextLevel) + Assertions.assertEquals(12828.0F, level.expInCurrentLevel, 0.5F) + } + + @Test + fun testEpicRabbit() { + val leveling = PetLeveling.getPetLevelingForPet0("RABBIT", PetInfoOverlay.Rarity.EPIC) + val level = leveling.getPetLevel(2864013.5452096704) + Assertions.assertEquals(74, level.currentLevel) + Assertions.assertEquals(206700, level.expRequiredForNextLevel) + Assertions.assertEquals(114713.0F, level.expInCurrentLevel, 0.5F) + } + + @Test + fun testPetLevelEndermite() { + val leveling = PetLeveling.getPetLevelingForPet0("ENDERMITE", PetInfoOverlay.Rarity.LEGENDARY) + val level = leveling.getPetLevel(1_206_848.0) + Assertions.assertEquals(59, level.currentLevel) + Assertions.assertEquals(97200, level.expRequiredForNextLevel) + Assertions.assertEquals(1318.0F, level.expInCurrentLevel, 0.5F) + } + @Test + fun testLevel109GoldenDragon() { + val leveling = PetLeveling.getPetLevelingForPet0("GOLDEN_DRAGON", PetInfoOverlay.Rarity.LEGENDARY) + val level = leveling.getPetLevel(3.947913361545298E7) + Assertions.assertEquals(109, level.currentLevel) + Assertions.assertEquals(913448.0F, level.expInCurrentLevel, 0.5F) + } + + @Test + fun testExpRequiredForLevel140() { + val leveling = PetLeveling.getPetLevelingForPet0("GOLDEN_DRAGON", PetInfoOverlay.Rarity.LEGENDARY) + val petExpForLevel = leveling.getPetExpForLevel(140) + val level = leveling.getPetLevel(petExpForLevel.toDouble()) + Assertions.assertEquals(97053440, petExpForLevel) + Assertions.assertEquals(140, level.currentLevel) + Assertions.assertEquals(0.0F, level.expInCurrentLevel, 1.0F) + Assertions.assertEquals(0.0F, level.percentageToNextLevel, 1.0F) + } + +} |