aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni
diff options
context:
space:
mode:
authorThunderblade73 <85900443+Thunderblade73@users.noreply.github.com>2024-06-05 15:39:55 +0200
committerGitHub <noreply@github.com>2024-06-05 15:39:55 +0200
commit5a04ad230cc4fb94884b34f795124d3b65af07ea (patch)
treecace8dcaad1c989be42a52bff4a6da233642279f /src/main/java/at/hannibal2/skyhanni
parenteb4ab6eaafa17581df58a53fb4111fa96933d230 (diff)
downloadskyhanni-5a04ad230cc4fb94884b34f795124d3b65af07ea.tar.gz
skyhanni-5a04ad230cc4fb94884b34f795124d3b65af07ea.tar.bz2
skyhanni-5a04ad230cc4fb94884b34f795124d3b65af07ea.zip
Improvement: Refactor of /ff for Improved Modularity and Code Reusability (#873)
Co-authored-by: Cal <cwolfson58@gmail.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni')
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt16
-rw-r--r--src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java8
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/TabComplete.kt2
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt25
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt3
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt5
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt169
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CarrolynTable.kt58
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt535
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFInfos.kt153
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt242
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingItems.kt186
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingReforges.kt1
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt81
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrade.kt10
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt24
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt122
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt430
-rw-r--r--src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt185
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt43
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt176
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt9
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/guide/GuideGUI.kt121
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/guide/GuidePage.kt15
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/guide/GuideRenderablePage.kt23
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/guide/GuideScrollPage.kt31
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/guide/GuideTab.kt67
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/guide/GuideTablePage.kt33
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt117
-rw-r--r--src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt11
31 files changed, 1553 insertions, 1350 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
index 4f5f0aa50..fdedfdbab 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/ConfigUpdaterMigrator.kt
@@ -12,7 +12,7 @@ import com.google.gson.JsonPrimitive
object ConfigUpdaterMigrator {
val logger = LorenzLogger("ConfigMigration")
- const val CONFIG_VERSION = 47
+ const val CONFIG_VERSION = 48
fun JsonElement.at(chain: List<String>, init: Boolean): JsonElement? {
if (chain.isEmpty()) return this
if (this !is JsonObject) return null
diff --git a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
index bd6cc8efe..89980d349 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
+++ b/src/main/java/at/hannibal2/skyhanni/config/commands/Commands.kt
@@ -371,17 +371,11 @@ object Commands {
"Disables/enables the rendering of all skyhanni guis."
) { SkyHanniDebugsAndTests.toggleRender() }
registerCommand(
- "shcarrot",
- "Toggles receiving the 12 fortune from carrots"
- ) { CaptureFarmingGear.reverseCarrotFortune() }
- registerCommand(
- "shpumpkin",
- "Toggles receiving the 12 fortune from pumpkins"
- ) { CaptureFarmingGear.reversePumpkinFortune() }
- registerCommand(
- "shcocoabeans",
- "Toggles receiving the 12 fortune from cocoa beans"
- ) { CaptureFarmingGear.reverseCocoaBeansFortune() }
+ "shcarrolyn",
+ "Toggels if the specified crops effect is active from carrolyn"
+ ) {
+ CaptureFarmingGear.handelCarrolyn(it)
+ }
registerCommand(
"shrepostatus",
"Shows the status of all the mods constants"
diff --git a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java
index d88ccb315..cbdc90978 100644
--- a/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java
+++ b/src/main/java/at/hannibal2/skyhanni/config/storage/ProfileSpecificStorage.java
@@ -373,13 +373,7 @@ public class ProfileSpecificStorage {
public long cakeExpiring = -1L;
@Expose
- public boolean carrotFortune = false;
-
- @Expose
- public boolean pumpkinFortune = false;
-
- @Expose
- public boolean cocoaBeansFortune = false;
+ public Map<CropType, Boolean> carrolyn = new HashMap<>();
@Expose
public Map<FarmingItems, ItemStack> farmingItems = new HashMap<>();
diff --git a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/TabComplete.kt b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/TabComplete.kt
index 49bde5993..87130298c 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/TabComplete.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/commands/tabcomplete/TabComplete.kt
@@ -3,6 +3,7 @@ package at.hannibal2.skyhanni.features.commands.tabcomplete
import at.hannibal2.skyhanni.events.TabCompletionEvent
import at.hannibal2.skyhanni.features.commands.PartyCommands
import at.hannibal2.skyhanni.features.commands.ViewRecipeCommand
+import at.hannibal2.skyhanni.features.garden.fortuneguide.CarrolynTable
import at.hannibal2.skyhanni.features.misc.CollectionTracker
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@@ -28,6 +29,7 @@ object TabComplete {
CollectionTracker.handleTabComplete(command)?.let { return it }
PartyCommands.customTabComplete(command)?.let { return it }
ViewRecipeCommand.customTabComplete(command)?.let { return it }
+ CarrolynTable.customTabComplete(command)?.let { return it }
return null
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
index b7480f259..3a661161e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/CropType.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.garden
+import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems
import net.minecraft.block.state.IBlockState
import net.minecraft.init.Blocks
import net.minecraft.init.Items
@@ -13,48 +14,49 @@ enum class CropType(
val baseDrops: Double,
iconSupplier: () -> ItemStack,
val simpleName: String,
+ val farmingItem: FarmingItems,
val replenish: Boolean = false,
) {
WHEAT(
"Wheat", "THEORETICAL_HOE_WHEAT", "CROPIE", 1.0,
- { ItemStack(Items.wheat) }, "wheat"
+ { ItemStack(Items.wheat) }, "wheat", FarmingItems.WHEAT
),
CARROT(
"Carrot", "THEORETICAL_HOE_CARROT", "CROPIE", 3.0,
- { ItemStack(Items.carrot) }, "carrot", replenish = true
+ { ItemStack(Items.carrot) }, "carrot", FarmingItems.CARROT, replenish = true
),
POTATO(
"Potato", "THEORETICAL_HOE_POTATO", "CROPIE", 3.0,
- { ItemStack(Items.potato) }, "potato", replenish = true
+ { ItemStack(Items.potato) }, "potato", FarmingItems.POTATO, replenish = true
),
NETHER_WART(
"Nether Wart", "THEORETICAL_HOE_WARTS", "FERMENTO", 2.5,
- { ItemStack(Items.nether_wart) }, "wart", replenish = true
+ { ItemStack(Items.nether_wart) }, "wart", FarmingItems.NETHER_WART, replenish = true
),
PUMPKIN(
"Pumpkin", "PUMPKIN_DICER", "SQUASH", 1.0,
- { ItemStack(Blocks.pumpkin) }, "pumpkin"
+ { ItemStack(Blocks.pumpkin) }, "pumpkin", FarmingItems.PUMPKIN
),
MELON(
"Melon", "MELON_DICER", "SQUASH", 5.0,
- { ItemStack(Items.melon) }, "melon"
+ { ItemStack(Items.melon) }, "melon", FarmingItems.MELON
),
COCOA_BEANS(
"Cocoa Beans", "COCO_CHOPPER", "SQUASH", 3.0,
- { ItemStack(Items.dye, 1, EnumDyeColor.BROWN.dyeDamage) }, "cocoa", replenish = true
+ { ItemStack(Items.dye, 1, EnumDyeColor.BROWN.dyeDamage) }, "cocoa", FarmingItems.COCOA_BEANS, replenish = true
),
SUGAR_CANE(
"Sugar Cane", "THEORETICAL_HOE_CANE", "FERMENTO", 2.0,
- { ItemStack(Items.reeds) }, "cane"
+ { ItemStack(Items.reeds) }, "cane", FarmingItems.SUGAR_CANE
),
CACTUS(
"Cactus", "CACTUS_KNIFE", "FERMENTO", 2.0,
- { ItemStack(Blocks.cactus) }, "cactus"
+ { ItemStack(Blocks.cactus) }, "cactus", FarmingItems.CACTUS
),
MUSHROOM(
"Mushroom", "FUNGI_CUTTER", "FERMENTO", 1.0,
- { ItemStack(Blocks.red_mushroom_block) }, "mushroom"
+ { ItemStack(Blocks.red_mushroom_block) }, "mushroom", FarmingItems.MUSHROOM
),
;
@@ -64,6 +66,9 @@ enum class CropType(
override fun toString(): String = cropName
+ val patternKeyName = name.lowercase().replace('_', '.')
+ val niceName = name.lowercase().replace('_', ' ')
+
companion object {
fun getByNameOrNull(itemName: String): CropType? {
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
index 0d75c9325..41ea1aa71 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/FarmingFortuneDisplay.kt
@@ -345,7 +345,8 @@ object FarmingFortuneDisplay {
// TODO code cleanup (after ff rework)
- for (line in tool?.getLore()!!) {
+ val lore = tool?.getLore() ?: return
+ for (line in lore) {
tooltipFortunePattern.matchMatcher(line) {
displayedFortune = group("display")?.toDouble() ?: 0.0
reforgeFortune = groupOrNull("reforge")?.toDouble() ?: 0.0
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
index 6f8523c34..0aac3e747 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/farming/FarmingWeightDisplay.kt
@@ -192,8 +192,9 @@ class FarmingWeightDisplay {
list.add(
Renderable.clickAndHover(
"§6Farming Weight§7: $weight$leaderboard",
- listOf("§eClick to open your Farming Profile."),
- onClick = { openWebsite(LorenzUtils.getPlayerName()) }
+ listOf("§eClick to open your Farming Profile."), onClick = {
+ openWebsite(LorenzUtils.getPlayerName())
+ }
)
)
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt
index 55e756780..158d1309e 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CaptureFarmingGear.kt
@@ -1,17 +1,21 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide
+import at.hannibal2.skyhanni.config.ConfigUpdaterMigrator
import at.hannibal2.skyhanni.config.storage.ProfileSpecificStorage
import at.hannibal2.skyhanni.data.PetAPI
import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.events.GardenToolChangeEvent
import at.hannibal2.skyhanni.events.InventoryFullyOpenedEvent
import at.hannibal2.skyhanni.events.LorenzChatEvent
+import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.GardenAPI.getCropType
import at.hannibal2.skyhanni.utils.ChatUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
+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.ItemUtils.getItemRarityOrNull
import at.hannibal2.skyhanni.utils.ItemUtils.getLore
import at.hannibal2.skyhanni.utils.LorenzUtils
@@ -29,7 +33,6 @@ import kotlin.math.round
import kotlin.time.Duration.Companion.days
object CaptureFarmingGear {
- private val farmingItems get() = GardenAPI.storage?.fortune?.farmingItems
private val outdatedItems get() = GardenAPI.storage?.fortune?.outdatedItems
private val patternGroup = RepoPattern.group("garden.fortuneguide.capture")
@@ -80,9 +83,24 @@ object CaptureFarmingGear {
"RANCHERS", "FARMER", "RABBIT"
)
+ init {
+ CarrolynTable.entries.forEach {
+ it.completeMessagePattern
+ it.thxMessagePattern
+ }
+ }
+
// TODO upadte armor on equpment/wardeobe update as well
fun captureFarmingGear() {
- val farmingItems = farmingItems ?: return
+ for (armor in InventoryUtils.getArmor()) {
+ if (armor == null) continue
+ val split = armor.getInternalName().asString().split("_")
+ if (split.first() in farmingSets) {
+ val category = armor.getItemCategoryOrNull() ?: continue
+ FarmingItems.getFromItemCategoryOne(category)?.setItem(armor)
+ }
+ }
+
val itemStack = InventoryUtils.getItemInHand() ?: return
val currentCrop = itemStack.getCropType()
@@ -91,22 +109,7 @@ object CaptureFarmingGear {
//todo better fall back items
//todo Daedalus axe
} else {
- for (item in FarmingItems.entries) {
- if (item.name == currentCrop.name) {
- farmingItems[item] = itemStack
- }
- }
- }
- for (armor in InventoryUtils.getArmor()) {
- if (armor == null) continue
- val split = armor.getInternalName().asString().split("_")
- if (split.first() in farmingSets) {
- for (item in FarmingItems.entries) {
- if (item.name == split.last()) {
- farmingItems[item] = armor
- }
- }
- }
+ currentCrop.farmingItem.setItem(itemStack)
}
TabListData.getTabList().matchFirst(strengthPattern) {
@@ -114,22 +117,13 @@ object CaptureFarmingGear {
}
}
- fun reverseCarrotFortune() {
- val storage = GardenAPI.storage?.fortune ?: return
- storage.carrotFortune = !storage.carrotFortune
- ChatUtils.chat("Toggled exportable carrot fortune to: ${storage.carrotFortune}")
- }
-
- fun reversePumpkinFortune() {
- val storage = GardenAPI.storage?.fortune ?: return
- storage.pumpkinFortune = !storage.pumpkinFortune
- ChatUtils.chat("Toggled expired pumpkin fortune to: ${storage.pumpkinFortune}")
- }
-
- fun reverseCocoaBeansFortune() {
- val storage = GardenAPI.storage?.fortune ?: return
- storage.cocoaBeansFortune = !storage.cocoaBeansFortune
- ChatUtils.chat("Toggled supreme chocolate bar fortune to: ${storage.cocoaBeansFortune}")
+ fun handelCarrolyn(input: Array<String>) {
+ val string = input.joinToString("_").uppercase()
+ val crop = CropType.entries.firstOrNull { it.name == string }
+ ?: ChatUtils.userError("Invalid Argument, no crop with the name: $string").run { return }
+ val carrolyn = CarrolynTable.getByCrop(crop)
+ ?: ChatUtils.userError("Invalid Argument, crop is not valid").run { return }
+ carrolyn.setVisibleActive(!carrolyn.get())
}
private fun getUniqueVisitorsForTier(tier: Int): Int {
@@ -151,15 +145,14 @@ object CaptureFarmingGear {
fun onInventoryOpen(event: InventoryFullyOpenedEvent) {
if (!LorenzUtils.inSkyBlock) return
val storage = GardenAPI.storage?.fortune ?: return
- val farmingItems = farmingItems ?: return
val outdatedItems = outdatedItems ?: return
val items = event.inventoryItems
if (PetAPI.isPetMenu(event.inventoryName)) {
- pets(farmingItems, items, outdatedItems)
+ pets(items, outdatedItems)
return
}
when (event.inventoryName) {
- "Your Equipment and Stats" -> equipmentAndStats(items, farmingItems, outdatedItems)
+ "Your Equipment and Stats" -> equipmentAndStats(items, outdatedItems)
"Your Skills" -> skills(items, storage)
"Community Shop" -> communityShop(items)
"Configure Plots" -> configurePlots(items, storage)
@@ -248,69 +241,54 @@ object CaptureFarmingGear {
}
private fun pets(
- farmingItems: MutableMap<FarmingItems, ItemStack>,
items: Map<Int, ItemStack>,
outdatedItems: MutableMap<FarmingItems, Boolean>,
) {
// If they've 2 of same pet, one will be overwritten
- // optimize
-
- for (pet in listOf(
- FarmingItems.ELEPHANT,
- FarmingItems.MOOSHROOM_COW,
- FarmingItems.RABBIT,
- FarmingItems.BEE
- )) {
- if (farmingItems[pet] == null) {
- farmingItems[pet] = FFGuideGUI.getFallbackItem(pet)
- }
- }
// setting to current saved level -1 to stop later pages saving low rarity pets
- var highestElephantRarity = (farmingItems[FarmingItems.ELEPHANT]?.getItemRarityOrNull()?.id ?: -1) - 1
- var highestMooshroomRarity = (farmingItems[FarmingItems.MOOSHROOM_COW]?.getItemRarityOrNull()?.id ?: -1) - 1
- var highestRabbitRarity = (farmingItems[FarmingItems.RABBIT]?.getItemRarityOrNull()?.id ?: -1) - 1
- var highestBeeRarity = (farmingItems[FarmingItems.BEE]?.getItemRarityOrNull()?.id ?: -1) - 1
+ var highestElephantRarity = (FarmingItems.ELEPHANT.getItemOrNull()?.getItemRarityOrNull()?.id ?: -1) - 1
+ var highestMooshroomRarity = (FarmingItems.MOOSHROOM_COW.getItemOrNull()?.getItemRarityOrNull()?.id ?: -1) - 1
+ var highestRabbitRarity = (FarmingItems.RABBIT.getItemOrNull()?.getItemRarityOrNull()?.id ?: -1) - 1
+ var highestBeeRarity = (FarmingItems.BEE.getItemOrNull()?.getItemRarityOrNull()?.id ?: -1) - 1
for ((_, item) in items) {
- val split = item.getInternalName().asString().split(";")
- if (split.first() == "ELEPHANT" && split.last().toInt() > highestElephantRarity) {
- farmingItems[FarmingItems.ELEPHANT] = item
+ if (item.getItemCategoryOrNull() != ItemCategory.PET) continue
+ val (name, rarity) = item.getInternalName().asString().split(";")
+ if (name == "ELEPHANT" && rarity.toInt() > highestElephantRarity) {
+ FarmingItems.ELEPHANT.setItem(item)
outdatedItems[FarmingItems.ELEPHANT] = false
- highestElephantRarity = split.last().toInt()
+ highestElephantRarity = rarity.toInt()
}
- if (split.first() == "MOOSHROOM_COW" && split.last().toInt() > highestMooshroomRarity) {
- farmingItems[FarmingItems.MOOSHROOM_COW] = item
+ if (name == "MOOSHROOM_COW" && rarity.toInt() > highestMooshroomRarity) {
+ FarmingItems.MOOSHROOM_COW.setItem(item)
outdatedItems[FarmingItems.MOOSHROOM_COW] = false
- highestMooshroomRarity = split.last().toInt()
+ highestMooshroomRarity = rarity.toInt()
}
- if (split.first() == "RABBIT" && split.last().toInt() > highestRabbitRarity) {
- farmingItems[FarmingItems.RABBIT] = item
+ if (name == "RABBIT" && rarity.toInt() > highestRabbitRarity) {
+ FarmingItems.RABBIT.setItem(item)
outdatedItems[FarmingItems.RABBIT] = false
- highestRabbitRarity = split.last().toInt()
+ highestRabbitRarity = rarity.toInt()
}
- if (split.first() == "BEE" && split.last().toInt() > highestBeeRarity) {
- farmingItems[FarmingItems.BEE] = item
+ if (name == "BEE" && rarity.toInt() > highestBeeRarity) {
+ FarmingItems.BEE.setItem(item)
outdatedItems[FarmingItems.BEE] = false
- highestBeeRarity = split.last().toInt()
+ highestBeeRarity = rarity.toInt()
}
}
}
private fun equipmentAndStats(
items: Map<Int, ItemStack>,
- farmingItems: MutableMap<FarmingItems, ItemStack>,
outdatedItems: MutableMap<FarmingItems, Boolean>,
) {
for ((_, slot) in items) {
val split = slot.getInternalName().asString().split("_")
+ val category = slot.getItemCategoryOrNull() ?: continue
if (split.first() == "LOTUS") {
- for (item in FarmingItems.entries) {
- if (item.name == split.last()) {
- farmingItems[item] = slot
- outdatedItems[item] = false
- }
- }
+ val item = FarmingItems.getFromItemCategoryOne(category) ?: continue
+ item.setItem(slot)
+ outdatedItems[item] = false
FarmingFortuneDisplay.loadFortuneLineData(slot, 0.0)
val enchantments = slot.getEnchantments() ?: emptyMap()
val greenThumbLvl = (enchantments["green_thumb"] ?: continue)
@@ -328,12 +306,15 @@ object CaptureFarmingGear {
val msg = event.message.removeColor().trim()
fortuneUpgradePattern.matchMatcher(msg) {
ProfileStorageData.playerSpecific?.gardenCommunityUpgrade = group("level").romanToDecimal()
+ return
}
farmingLevelUpPattern.matchMatcher(msg) {
storage.farmingLevel = group("level").romanToDecimalIfNecessary()
+ return
}
anitaBuffPattern.matchMatcher(msg) {
storage.anitaUpgrade = group("level").toInt() / 4
+ return
}
lotusUpgradePattern.matchMatcher(msg) {
val piece = group("piece").uppercase()
@@ -342,6 +323,7 @@ object CaptureFarmingGear {
outdatedItems[item] = true
}
}
+ return
}
petLevelUpPattern.matchMatcher(msg) {
val pet = group("pet").uppercase().replace("✦", "").trim().replace(" ", "_")
@@ -350,30 +332,29 @@ object CaptureFarmingGear {
outdatedItems[item] = true
}
}
+ return
}
cakePattern.matchMatcher(msg) {
storage.cakeExpiring = System.currentTimeMillis() + 2.days.inWholeMilliseconds
+ return
}
- if (msg == "CARROTS EXPORTATION COMPLETE!") {
- storage.carrotFortune = true
- }
- if (msg == "PUMPKINS EXPORTATION COMPLETE!") {
- storage.pumpkinFortune = true
- }
- if (msg == "CHOCOLATE BARS EXPORTATION COMPLETE!") {
- storage.cocoaBeansFortune = true
- }
- if (msg == "[NPC] Carrolyn: Thank you for the carrots.") {
- storage.carrotFortune = true
- ChatUtils.chat("§aYou have already given Carrolyn enough Exportable Carrots.")
- }
- if (msg == "[NPC] Carrolyn: Thank you for the pumpkins.") {
- storage.pumpkinFortune = true
- ChatUtils.chat("§aYou have already given Carrolyn enough Expired Pumpkins.")
- }
- if (msg == "[NPC] Carrolyn: Thank you for the chocolate.") {
- storage.cocoaBeansFortune = true
- ChatUtils.chat("§aYou have already given Carrolyn enough Supreme Chocolate Bars.")
+ CarrolynTable.entries.forEach {
+ it.completeMessagePattern.matchMatcher(msg) {
+ it.set(true)
+ return
+ }
+ it.thxMessagePattern.matchMatcher(msg) {
+ it.set(true)
+ ChatUtils.chat(it.thxResponse)
+ return
+ }
}
}
+
+ @SubscribeEvent
+ fun onConfigUpdaterMigratorConfigFix(event: ConfigUpdaterMigrator.ConfigFixEvent) {
+ event.move(48, "#profile.garden.fortune.carrotFortune", "#profile.garden.fortune.carrolyn.CARROT")
+ event.move(48, "#profile.garden.fortune.pumpkinFortune", "#profile.garden.fortune.carrolyn.PUMPKIN")
+ event.move(48, "#profile.garden.fortune.cocoaBeansFortune", "#profile.garden.fortune.carrolyn.COCOA_BEANS")
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CarrolynTable.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CarrolynTable.kt
new file mode 100644
index 000000000..b7163768b
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/CarrolynTable.kt
@@ -0,0 +1,58 @@
+package at.hannibal2.skyhanni.features.garden.fortuneguide
+
+import at.hannibal2.skyhanni.features.garden.CropType
+import at.hannibal2.skyhanni.features.garden.GardenAPI
+import at.hannibal2.skyhanni.utils.ChatUtils
+import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern
+
+enum class CarrolynTable(val crop: CropType, val label: String, completeMessage: String, thxMessage: String) {
+ EXPORTABLE_CARROTS(
+ CropType.CARROT,
+ "Exportable Carrots",
+ "CARROTS EXPORTATION COMPLETE!",
+ "[NPC] Carrolyn: Thank you for the carrots."
+ ),
+ EXPIRED_PUMPKIN(
+ CropType.PUMPKIN,
+ "Expired Pumpkin",
+ "PUMPKINS EXPORTATION COMPLETE!",
+ "[NPC] Carrolyn: Thank you for the pumpkins."
+ ),
+ SUPREME_CHOCOLATE_BAR(
+ CropType.COCOA_BEANS,
+ "Supreme Chocolate Bar",
+ "CHOCOLATE BARS EXPORTATION COMPLETE!",
+ "[NPC] Carrolyn: Thank you for the chocolate."
+ ),
+ ;
+
+ val completeMessagePattern by RepoPattern.pattern(
+ "garden.ff.carrolyn.complete.${crop.patternKeyName}", completeMessage
+ )
+ val thxMessagePattern by RepoPattern.pattern(
+ "garden.ff.carrolyn.thx.${crop.patternKeyName}", thxMessage
+ )
+
+ val thxResponse = "§aYou have already given Carrolyn enough $label."
+
+ fun get() = GardenAPI.storage?.fortune?.carrolyn?.get(crop) ?: false
+ fun set(value: Boolean) = GardenAPI.storage?.fortune?.carrolyn?.set(crop, value)
+
+ fun setVisibleActive(value: Boolean) {
+ set(value)
+ ChatUtils.chat("Toggled $label fortune to: ${get()}")
+ }
+
+ companion object {
+ fun getByCrop(crop: CropType?) = if (crop == null) null else entries.firstOrNull { it.crop == crop }
+
+ fun isCarrolynCrop(crop: CropType): Boolean = CarrolynTable.getByCrop(crop) != null
+ fun customTabComplete(command: String): List<String>? {
+ if (command == "shcarrolyn") {
+ return entries.map { it.crop.name }
+ }
+
+ return null
+ }
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt
index 0cafabd1c..ff81cae6d 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFGuideGUI.kt
@@ -2,528 +2,95 @@ package at.hannibal2.skyhanni.features.garden.fortuneguide
import at.hannibal2.skyhanni.SkyHanniMod
import at.hannibal2.skyhanni.features.garden.CropType
-import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.fortuneguide.pages.CropPage
import at.hannibal2.skyhanni.features.garden.fortuneguide.pages.OverviewPage
import at.hannibal2.skyhanni.features.garden.fortuneguide.pages.UpgradePage
-import at.hannibal2.skyhanni.utils.ChatUtils
-import at.hannibal2.skyhanni.utils.GuiRenderUtils
-import at.hannibal2.skyhanni.utils.ItemUtils.name
-import at.hannibal2.skyhanni.utils.LorenzUtils
-import at.hannibal2.skyhanni.utils.OSUtils
-import at.hannibal2.skyhanni.utils.SoundUtils
+import at.hannibal2.skyhanni.utils.guide.GuideGUI
+import at.hannibal2.skyhanni.utils.guide.GuideTab
+import at.hannibal2.skyhanni.utils.renderables.Renderable
import net.minecraft.client.Minecraft
-import net.minecraft.client.gui.GuiScreen
-import net.minecraft.client.renderer.GlStateManager
import net.minecraft.init.Blocks
import net.minecraft.init.Items
import net.minecraft.item.ItemStack
-import org.lwjgl.input.Mouse
-import java.io.IOException
-open class FFGuideGUI : GuiScreen() {
- companion object {
-
- private var firefoxTrials = 0
-
- fun open() {
- if (LorenzUtils.isAprilFoolsDay) {
- when (firefoxTrials) {
- 0 -> {
- ChatUtils.chat("Are you looking for the FF browser?", prefix = false)
- }
-
- 1 -> {
- ChatUtils.chat("Quickly, download Firefox! NOW!", prefix = false)
- OSUtils.openBrowser("https://www.mozilla.org/en-US/firefox/new/")
- }
-
- 2 -> {
- ChatUtils.chat("Have you tried Firefix from Mozilla already?", prefix = false)
- }
-
- 10 -> {
- ChatUtils.chat("Firefox is simply the best!", prefix = false)
- }
-
- 20 -> {
- ChatUtils.chat(
- "What do you mean with \"farming fortune\"? This is a web browser!",
- prefix = false
- )
- }
-
- 30 -> {
- ChatUtils.chat("What are you still doing here? get Firefox!", prefix = false)
- }
-
- else -> {
- CaptureFarmingGear.captureFarmingGear()
- SkyHanniMod.screenToOpen = FFGuideGUI()
- }
- }
- firefoxTrials++
- } else {
- CaptureFarmingGear.captureFarmingGear()
- SkyHanniMod.screenToOpen = FFGuideGUI()
- }
- }
-
- val pages = mutableMapOf<FortuneGuidePage, FFGuidePage>()
-
- var guiLeft = 0
- var guiTop = 0
- var screenHeight = 0
-
- const val sizeX = 360
- const val sizeY = 180
+class FFGuideGUI : GuideGUI<FFGuideGUI.FortuneGuidePage>(FortuneGuidePage.OVERVIEW) {
- var selectedPage = FortuneGuidePage.OVERVIEW
- var currentCrop: CropType? = null
+ override val sizeX = 360
+ override val sizeY = 180
- // todo set this to what they have equip
- var currentPet = FarmingItems.ELEPHANT
- var currentArmor = 0
- var currentEquipment = 0
-
- var mouseX = 0
- var mouseY = 0
- var lastMouseScroll = 0
- var noMouseScrollFrames = 0
- var lastClickedHeight = 0
-
- var tooltipToDisplay = mutableListOf<String>()
+ companion object {
fun isInGui() = Minecraft.getMinecraft().currentScreen is FFGuideGUI
- fun FarmingItems.getItem(): ItemStack {
- val fortune = GardenAPI.storage?.fortune ?: return getFallbackItem(this)
-
- val farmingItems = fortune.farmingItems
- farmingItems[this]?.let { return it }
-
- val fallbackItem = getFallbackItem(this)
- farmingItems[this] = fallbackItem
- return fallbackItem
+ fun open() {
+ CaptureFarmingGear.captureFarmingGear()
+ SkyHanniMod.screenToOpen = FFGuideGUI()
}
- private val fallbackItems = mutableMapOf<FarmingItems, ItemStack>()
-
- fun getFallbackItem(item: FarmingItems) = fallbackItems.getOrPut(item) {
- val name = "§cNo saved ${item.name.lowercase().replace("_", " ")}"
- ItemStack(Blocks.barrier).setStackDisplayName(name)
+ fun updateDisplay() {
+ with(Minecraft.getMinecraft().currentScreen) {
+ if (this !is FFGuideGUI) return
+ this.refreshPage()
+ }
}
-
- fun isFallbackItem(item: ItemStack) = item.name.startsWith("§cNo saved ")
}
+ /** Value for which crop page is active */
+ private var currentCrop: CropType? = null
+
init {
FFStats.loadFFData()
FortuneUpgrades.generateGenericUpgrades()
- pages[FortuneGuidePage.OVERVIEW] = OverviewPage()
- pages[FortuneGuidePage.CROP] = CropPage()
- pages[FortuneGuidePage.UPGRADES] = UpgradePage()
+ FarmingItems.setDefaultPet()
- if (currentCrop != null) {
- for (item in FarmingItems.entries) {
- if (item.name == currentCrop?.name) {
- FFStats.getCropStats(currentCrop!!, item.getItem())
+ pageList = mapOf(
+ FortuneGuidePage.OVERVIEW to OverviewPage(sizeX, sizeY),
+ FortuneGuidePage.CROP to CropPage({ currentCrop!! }, sizeX, sizeY),
+ FortuneGuidePage.UPGRADES to UpgradePage({ currentCrop }, sizeX, sizeY - 2),
+ )
+ verticalTabs = listOf(
+ vTab(ItemStack(Items.gold_ingot), Renderable.string("§eBreakdown")) {
+ currentPage = if (currentCrop == null) FortuneGuidePage.OVERVIEW else FortuneGuidePage.CROP
+ },
+ vTab(ItemStack(Items.map), Renderable.string("§eUpgrades")) {
+ currentPage = FortuneGuidePage.UPGRADES
+ })
+ horizontalTabs = buildList {
+ add(
+ hTab(ItemStack(Blocks.grass), Renderable.string("§eOverview")) {
+ currentCrop = null
+
+ it.pageSwitchHorizontal()
}
- }
- }
- }
-
- override fun drawScreen(unusedX: Int, unusedY: Int, partialTicks: Float) {
- super.drawScreen(unusedX, unusedY, partialTicks)
- drawDefaultBackground()
- screenHeight = height
- guiLeft = (width - sizeX) / 2
- guiTop = (height - sizeY) / 2
-
- mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth
- mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1
-
- GlStateManager.pushMatrix()
- drawRect(guiLeft, guiTop, guiLeft + sizeX, guiTop + sizeY, 0x50000000)
- renderTabs()
-
- if (selectedPage == FortuneGuidePage.UPGRADES) {
- //
- } else {
- GuiRenderUtils.drawStringCentered("§7SkyHanni", guiLeft + 325, guiTop + 170)
- if (currentCrop == null) {
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.HELMET.getItem(), guiLeft + 142, guiTop + 5, mouseX, mouseY,
- if (currentArmor == 1) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.CHESTPLATE.getItem(), guiLeft + 162, guiTop + 5, mouseX, mouseY,
- if (currentArmor == 2) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.LEGGINGS.getItem(), guiLeft + 182, guiTop + 5, mouseX, mouseY,
- if (currentArmor == 3) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.BOOTS.getItem(), guiLeft + 202, guiTop + 5, mouseX, mouseY,
- if (currentArmor == 4) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
+ )
+ for (crop in CropType.entries) {
+ add(
+ hTab(crop.icon, Renderable.string("§e${crop.cropName}")) {
+ currentCrop = crop
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.NECKLACE.getItem(), guiLeft + 262, guiTop + 5, mouseX, mouseY,
- if (currentEquipment == 1) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.CLOAK.getItem(), guiLeft + 282, guiTop + 5, mouseX, mouseY,
- if (currentEquipment == 2) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.BELT.getItem(), guiLeft + 302, guiTop + 5, mouseX, mouseY,
- if (currentEquipment == 3) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.BRACELET.getItem(), guiLeft + 322, guiTop + 5, mouseX, mouseY,
- if (currentEquipment == 4) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
-
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.ELEPHANT.getItem(), guiLeft + 142, guiTop + 130, mouseX, mouseY,
- if (currentPet == FarmingItems.ELEPHANT) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.MOOSHROOM_COW.getItem(), guiLeft + 162, guiTop + 130, mouseX, mouseY,
- if (currentPet == FarmingItems.MOOSHROOM_COW) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.RABBIT.getItem(), guiLeft + 182, guiTop + 130, mouseX, mouseY,
- if (currentPet == FarmingItems.RABBIT) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.BEE.getItem(), guiLeft + 202, guiTop + 130, mouseX, mouseY,
- if (currentPet == FarmingItems.BEE) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- } else {
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.ELEPHANT.getItem(), guiLeft + 142, guiTop + 160, mouseX, mouseY,
- if (currentPet == FarmingItems.ELEPHANT) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.MOOSHROOM_COW.getItem(), guiLeft + 162, guiTop + 160, mouseX, mouseY,
- if (currentPet == FarmingItems.MOOSHROOM_COW) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.RABBIT.getItem(), guiLeft + 182, guiTop + 160, mouseX, mouseY,
- if (currentPet == FarmingItems.RABBIT) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.BEE.getItem(), guiLeft + 202, guiTop + 160, mouseX, mouseY,
- if (currentPet == FarmingItems.BEE) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
- )
-
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.HELMET.getItem(), guiLeft + 162, guiTop + 80, mouseX, mouseY
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.CHESTPLATE.getItem(), guiLeft + 162, guiTop + 100, mouseX, mouseY
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.LEGGINGS.getItem(), guiLeft + 162, guiTop + 120, mouseX, mouseY
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.BOOTS.getItem(), guiLeft + 162, guiTop + 140, mouseX, mouseY
- )
-
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.NECKLACE.getItem(), guiLeft + 182, guiTop + 80, mouseX, mouseY
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.CLOAK.getItem(), guiLeft + 182, guiTop + 100, mouseX, mouseY
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.BELT.getItem(), guiLeft + 182, guiTop + 120, mouseX, mouseY
- )
- GuiRenderUtils.renderItemAndTip(
- tooltipToDisplay,
- FarmingItems.BRACELET.getItem(), guiLeft + 182, guiTop + 140, mouseX, mouseY
+ it.pageSwitchHorizontal()
+ }
)
}
}
- pages[selectedPage]?.drawPage(mouseX, mouseY, partialTicks)
+ horizontalTabs.firstOrNull()?.fakeClick()
+ verticalTabs.firstOrNull()?.fakeClick()
- GlStateManager.popMatrix()
-
- if (tooltipToDisplay.isNotEmpty()) {
- GuiRenderUtils.drawTooltip(tooltipToDisplay, mouseX, mouseY, height)
- tooltipToDisplay.clear()
- }
}
- override fun handleMouseInput() {
- super.handleMouseInput()
-
- if (Mouse.getEventButtonState()) {
- mouseClickEvent()
- }
- if (!Mouse.getEventButtonState() && Mouse.getEventDWheel() != 0) {
- lastMouseScroll = Mouse.getEventDWheel()
- noMouseScrollFrames = 0
- }
- }
-
- @Throws(IOException::class)
- fun mouseClickEvent() {
- var x = guiLeft + 15
- var y = guiTop - 28
- if (isMouseIn(x, y, 25, 28)) {
- SoundUtils.playClickSound()
- if (currentCrop != null) {
- currentCrop = null
- if (selectedPage != FortuneGuidePage.UPGRADES) {
- selectedPage = FortuneGuidePage.OVERVIEW
- }
- } else {
- if (selectedPage == FortuneGuidePage.UPGRADES) {
- selectedPage = FortuneGuidePage.OVERVIEW
- } else {
- selectedPage = FortuneGuidePage.UPGRADES
- }
- }
- }
- for (crop in CropType.entries) {
- x += 30
- if (isMouseIn(x, y, 25, 28)) {
- SoundUtils.playClickSound()
- if (currentCrop != crop) {
- currentCrop = crop
- if (selectedPage == FortuneGuidePage.OVERVIEW) {
- selectedPage = FortuneGuidePage.CROP
- }
- for (item in FarmingItems.entries) {
- if (item.name == crop.name) {
- FFStats.getCropStats(crop, item.getItem())
- FortuneUpgrades.getCropSpecific(item.getItem())
- }
- }
- } else {
- if (selectedPage == FortuneGuidePage.CROP) {
- selectedPage = FortuneGuidePage.UPGRADES
- for (item in FarmingItems.entries) {
- if (item.name == crop.name) {
- FortuneUpgrades.getCropSpecific(item.getItem())
- }
- }
- } else {
- selectedPage = FortuneGuidePage.CROP
- for (item in FarmingItems.entries) {
- if (item.name == crop.name) {
- FFStats.getCropStats(crop, item.getItem())
- }
- }
- }
- }
- }
- }
-
- x = guiLeft - 28
- y = guiTop + 15
- if (isMouseIn(x, y, 28, 25) &&
- selectedPage != FortuneGuidePage.CROP && selectedPage != FortuneGuidePage.OVERVIEW
- ) {
- SoundUtils.playClickSound()
- selectedPage = if (currentCrop == null) {
- FortuneGuidePage.OVERVIEW
- } else {
- FortuneGuidePage.CROP
- }
- }
- y += 30
- if (isMouseIn(x, y, 28, 25) && selectedPage != FortuneGuidePage.UPGRADES) {
- selectedPage = FortuneGuidePage.UPGRADES
- SoundUtils.playClickSound()
- }
-
- if (selectedPage != FortuneGuidePage.UPGRADES) {
- if (currentCrop == null) {
- when {
- isMouseInRect(guiLeft + 142, guiTop + 130) && currentPet != FarmingItems.ELEPHANT -> {
- SoundUtils.playClickSound()
- currentPet = FarmingItems.ELEPHANT
- FFStats.getTotalFF()
- }
-
- isMouseInRect(guiLeft + 162, guiTop + 130) && currentPet != FarmingItems.MOOSHROOM_COW -> {
- SoundUtils.playClickSound()
- currentPet = FarmingItems.MOOSHROOM_COW
- FFStats.getTotalFF()
- }
-
- isMouseInRect(guiLeft + 182, guiTop + 130) && currentPet != FarmingItems.RABBIT -> {
- SoundUtils.playClickSound()
- currentPet = FarmingItems.RABBIT
- FFStats.getTotalFF()
- }
-
- isMouseInRect(guiLeft + 202, guiTop + 130) && currentPet != FarmingItems.BEE -> {
- SoundUtils.playClickSound()
- currentPet = FarmingItems.BEE
- FFStats.getTotalFF()
- }
-
- isMouseInRect(guiLeft + 142, guiTop + 5) -> {
- SoundUtils.playClickSound()
- currentArmor = if (currentArmor == 1) 0 else 1
- }
-
- isMouseInRect(guiLeft + 162, guiTop + 5) -> {
- SoundUtils.playClickSound()
- currentArmor = if (currentArmor == 2) 0 else 2
- }
-
- isMouseInRect(guiLeft + 182, guiTop + 5) -> {
- SoundUtils.playClickSound()
- currentArmor = if (currentArmor == 3) 0 else 3
- }
-
- isMouseInRect(guiLeft + 202, guiTop + 5) -> {
- SoundUtils.playClickSound()
- currentArmor = if (currentArmor == 4) 0 else 4
- }
-
- isMouseInRect(guiLeft + 262, guiTop + 5) -> {
- SoundUtils.playClickSound()
- currentEquipment = if (currentEquipment == 1) 0 else 1
- }
-
- isMouseInRect(guiLeft + 282, guiTop + 5) -> {
- SoundUtils.playClickSound()
- currentEquipment = if (currentEquipment == 2) 0 else 2
- }
-
- isMouseInRect(guiLeft + 302, guiTop + 5) -> {
- SoundUtils.playClickSound()
- currentEquipment = if (currentEquipment == 3) 0 else 3
- }
-
- isMouseInRect(guiLeft + 322, guiTop + 5) -> {
- SoundUtils.playClickSound()
- currentEquipment = if (currentEquipment == 4) 0 else 4
- }
- }
- } else {
- when {
- isMouseInRect(guiLeft + 142, guiTop + 160) && currentPet != FarmingItems.ELEPHANT -> {
- SoundUtils.playClickSound()
- currentPet = FarmingItems.ELEPHANT
- FFStats.getTotalFF()
- }
-
- isMouseInRect(guiLeft + 162, guiTop + 160) && currentPet != FarmingItems.MOOSHROOM_COW -> {
- SoundUtils.playClickSound()
- currentPet = FarmingItems.MOOSHROOM_COW
- FFStats.getTotalFF()
- }
-
- isMouseInRect(guiLeft + 182, guiTop + 160) && currentPet != FarmingItems.RABBIT -> {
- SoundUtils.playClickSound()
- currentPet = FarmingItems.RABBIT
- FFStats.getTotalFF()
- }
-
- isMouseInRect(guiLeft + 202, guiTop + 160) && currentPet != FarmingItems.BEE -> {
- SoundUtils.playClickSound()
- currentPet = FarmingItems.BEE
- FFStats.getTotalFF()
- }
- }
- }
+ private fun GuideTab.pageSwitchHorizontal() {
+ if (isSelected()) {
+ verticalTabs.first { it != lastVerticalTabWrapper.tab }.fakeClick() // Double Click Logic
} else {
- if (isMouseIn(guiLeft, guiTop, sizeX, sizeY)) {
- lastClickedHeight = mouseY
- }
- }
- }
-
- private fun isMouseInRect(left: Int, top: Int) = isMouseIn(left, top, 16, 16)
-
- private fun isMouseIn(x: Int, y: Int, width: Int, height: Int) =
- GuiRenderUtils.isPointInRect(mouseX, mouseY, x, y, width, height)
-
- private fun renderTabs() {
- var x = guiLeft + 15
- var y = guiTop - 28
- val selectedColor = 0x50000000
- val notSelectedColor = 0x50303030
- drawRect(x, y, x + 25, y + 28, if (currentCrop == null) selectedColor else notSelectedColor)
- GuiRenderUtils.renderItemStack(ItemStack(Blocks.grass), x + 5, y + 5)
- if (isMouseIn(x, y, 25, 28)) {
- tooltipToDisplay.add("§eOverview")
- }
-
- for (crop in CropType.entries) {
- x += 30
- drawRect(x, y, x + 25, y + 28, if (currentCrop == crop) selectedColor else notSelectedColor)
- GuiRenderUtils.renderItemStack(crop.icon, x + 5, y + 5)
- if (isMouseIn(x, y, 25, 28)) {
- tooltipToDisplay.add("§e${crop.cropName}")
- }
- }
-
- x = guiLeft - 28
- y = guiTop + 15
-
- drawRect(
- x, y,
- x + 28, y + 25,
- if (selectedPage != FortuneGuidePage.UPGRADES) selectedColor else notSelectedColor
- )
- GuiRenderUtils.renderItemStack(ItemStack(Items.gold_ingot), x + 5, y + 5)
- if (isMouseIn(x, y, 28, 25)) {
- tooltipToDisplay.add("§eBreakdown")
- }
- y += 30
- drawRect(
- x, y,
- x + 28, y + 25,
- if (selectedPage == FortuneGuidePage.UPGRADES) selectedColor else notSelectedColor
- )
- GuiRenderUtils.renderItemStack(ItemStack(Items.map), x + 5, y + 5)
- if (isMouseIn(x, y, 28, 25)) {
- tooltipToDisplay.add("§eUpgrades")
+ lastVerticalTabWrapper.tab?.fakeClick() // First Click Logic
}
}
enum class FortuneGuidePage {
OVERVIEW,
CROP,
- UPGRADES
- }
-
- abstract class FFGuidePage {
+ UPGRADES,
- abstract fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float)
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFInfos.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFInfos.kt
new file mode 100644
index 000000000..19597e6db
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFInfos.kt
@@ -0,0 +1,153 @@
+package at.hannibal2.skyhanni.features.garden.fortuneguide
+
+import at.hannibal2.skyhanni.utils.GuiRenderUtils
+
+internal enum class FFInfos(
+ val sumTo: FFInfos?,
+ private val currentF: () -> Number,
+ private val maxF: (FFInfos) -> Number,
+) {
+ UNIVERSAL(null, { FFStats.totalBaseFF }, FFTypes.TOTAL, {
+ val backupArmor = FarmingItems.currentArmor
+ val backupEquip = FarmingItems.currentEquip
+ FarmingItems.currentArmor = null
+ FarmingItems.currentEquip = null
+ val total = maxSumToThis(it) + 100
+ FarmingItems.currentArmor = backupArmor
+ FarmingItems.currentEquip = backupEquip
+ total
+ }),
+ ANITA_BUFF(UNIVERSAL, { FFStats.baseFF }, FFTypes.ANITA, 60),
+ FARMING_LEVEL(UNIVERSAL, { FFStats.baseFF }, FFTypes.FARMING_LVL, 240),
+ COMMUNITY_SHOP(UNIVERSAL, { FFStats.baseFF }, FFTypes.COMMUNITY_SHOP, 40),
+ GARDEN_PLOTS(UNIVERSAL, { FFStats.baseFF }, FFTypes.PLOTS, 72),
+ CAKE_BUFF(UNIVERSAL, { FFStats.baseFF }, FFTypes.CAKE, 5),
+ TOTAL_ARMOR(UNIVERSAL, { FarmingItems.currentArmor?.getFFData() ?: FFStats.armorTotalFF }, FFTypes.TOTAL),
+ BASE_ARMOR(TOTAL_ARMOR, { FarmingItems.currentArmor?.getFFData() ?: FFStats.armorTotalFF }, FFTypes.BASE, {
+ when (FarmingItems.currentArmor) {
+ FarmingItems.HELMET -> 30
+ FarmingItems.CHESTPLATE, FarmingItems.LEGGINGS -> 35
+ FarmingItems.BOOTS -> if (FFStats.usingSpeedBoots) 60 else 30
+ else -> if (FFStats.usingSpeedBoots) 160 else 130
+ }
+ }),
+ ABILITY_ARMOR(TOTAL_ARMOR, { FarmingItems.currentArmor?.getFFData() ?: FFStats.armorTotalFF }, FFTypes.ABILITY, {
+ when (FarmingItems.currentArmor) {
+ FarmingItems.HELMET, FarmingItems.CHESTPLATE, FarmingItems.LEGGINGS -> if (FFStats.usingSpeedBoots) 16.667 else 18.75
+ FarmingItems.BOOTS -> if (FFStats.usingSpeedBoots) 0 else 18.75
+ else -> if (FFStats.usingSpeedBoots) 50 else 75
+ }
+ }),
+ REFORGE_ARMOR(TOTAL_ARMOR, { FarmingItems.currentArmor?.getFFData() ?: FFStats.armorTotalFF }, FFTypes.REFORGE, {
+ when (FarmingItems.currentArmor) {
+ FarmingItems.HELMET, FarmingItems.CHESTPLATE, FarmingItems.LEGGINGS -> 30
+ FarmingItems.BOOTS -> if (FFStats.usingSpeedBoots) 25 else 30
+ else -> if (FFStats.usingSpeedBoots) 115 else 120
+ }
+ }),
+ ENCHANT_ARMOR(
+ sumTo = TOTAL_ARMOR,
+ from = { FarmingItems.currentArmor?.getFFData() ?: FFStats.armorTotalFF },
+ what = FFTypes.PESTERMINATOR,
+ x4 = { FarmingItems.currentArmor == null },
+ max = 5
+ ),
+ GEMSTONE_ARMOR(TOTAL_ARMOR, { FarmingItems.currentArmor?.getFFData() ?: FFStats.armorTotalFF }, FFTypes.GEMSTONE, {
+ when (FarmingItems.currentArmor) {
+ FarmingItems.HELMET, FarmingItems.CHESTPLATE, FarmingItems.LEGGINGS -> 20
+ FarmingItems.BOOTS -> if (FFStats.usingSpeedBoots) 16 else 20
+ else -> if (FFStats.usingSpeedBoots) 76 else 80
+ }
+ }),
+ TOTAL_PET(UNIVERSAL, { FarmingItems.currentPet.getFFData() }, FFTypes.TOTAL),
+ PET_BASE(TOTAL_PET, { FarmingItems.currentPet.getFFData() }, FFTypes.BASE, {
+ when (FarmingItems.currentPet) {
+ FarmingItems.ELEPHANT -> 150
+ FarmingItems.MOOSHROOM_COW -> 157
+ FarmingItems.BEE -> 30
+ else -> 0
+ }
+ }),
+ PET_ITEM(TOTAL_PET, { FarmingItems.currentPet.getFFData() }, FFTypes.PET_ITEM, 60),
+ TOTAL_EQUIP(
+ sumTo = UNIVERSAL,
+ from = { FarmingItems.currentEquip?.getFFData() ?: FFStats.equipmentTotalFF },
+ what = FFTypes.TOTAL
+ ),
+ BASE_EQUIP(
+ sumTo = TOTAL_EQUIP,
+ from = { FarmingItems.currentEquip?.getFFData() ?: FFStats.equipmentTotalFF },
+ what = FFTypes.BASE,
+ x4 = { FarmingItems.currentEquip == null },
+ max = 5.0
+ ),
+ ABILITY_EQUIP(
+ sumTo = TOTAL_EQUIP,
+ from = { FarmingItems.currentEquip?.getFFData() ?: FFStats.equipmentTotalFF },
+ what = FFTypes.ABILITY,
+ x4 = { FarmingItems.currentEquip == null },
+ max = 15.0
+ ),
+ REFORGE_EQUIP(
+ sumTo = TOTAL_EQUIP,
+ from = { FarmingItems.currentEquip?.getFFData() ?: FFStats.equipmentTotalFF },
+ what = FFTypes.REFORGE,
+ x4 = { FarmingItems.currentEquip == null },
+ max = 15.0
+ ),
+ ENCHANT_EQUIP(
+ sumTo = TOTAL_EQUIP,
+ from = { FarmingItems.currentEquip?.getFFData() ?: FFStats.equipmentTotalFF },
+ what = FFTypes.GREEN_THUMB,
+ x4 = { FarmingItems.currentEquip == null },
+ max = { at.hannibal2.skyhanni.features.garden.GardenAPI.totalAmountVisitorsExisting.toDouble() / 4.0 }
+ ),
+ ;
+
+ val current get() = currentF().toDouble()
+ val max get() = maxF(this).toDouble()
+
+ fun bar(label: String, tooltip: String) = GuiRenderUtils.getFarmingBar(label, tooltip, current, max, 90)
+
+ constructor(sumTo: FFInfos?, current: () -> Number, max: Number) : this(sumTo, current, { max })
+ constructor(sumTo: FFInfos?, from: () -> Map<FFTypes, Double>, what: FFTypes, max: Number) : this(sumTo, {
+ from()[what] ?: 0.0
+ }, { max }
+ )
+
+ constructor(
+ sumTo: FFInfos?,
+ from: () -> Map<FFTypes, Double>,
+ what: FFTypes,
+ x4: () -> Boolean,
+ max: Number,
+ ) : this(sumTo, { from()[what] ?: 0.0 }, { if (x4()) max.toDouble() * 4 else max }
+ )
+
+ constructor(
+ sumTo: FFInfos?,
+ from: () -> Map<FFTypes, Double>,
+ what: FFTypes,
+ x4: () -> Boolean,
+ max: () -> Number,
+ ) : this(sumTo, { from()[what] ?: 0.0 }, { if (x4()) max().toDouble() * 4 else max() }
+ )
+
+ constructor(
+ sumTo: FFInfos?,
+ from: () -> Map<FFTypes, Double>,
+ what: FFTypes,
+ max: (FFInfos) -> Number,
+ ) : this(
+ sumTo, { from()[what] ?: 0.0 }, max
+ )
+
+ constructor(
+ sumTo: FFInfos?,
+ from: () -> Map<FFTypes, Double>,
+ what: FFTypes,
+ ) : this(sumTo, { from()[what] ?: 0.0 }, ::maxSumToThis)
+
+}
+
+private fun maxSumToThis(self: FFInfos): Double = FFInfos.entries.filter { it.sumTo == self }.sumOf { it.max }
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt
index 2f1ce1860..772177c82 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FFStats.kt
@@ -6,8 +6,8 @@ import at.hannibal2.skyhanni.data.ProfileStorageData
import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay
import at.hannibal2.skyhanni.features.garden.GardenAPI
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.getItem
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
+import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getFarmingForDummiesCount
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetItem
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getPetLevel
@@ -16,225 +16,166 @@ import kotlin.math.floor
object FFStats {
- private val mathCrops =
+ private val mathCrops by lazy {
listOf(CropType.WHEAT, CropType.CARROT, CropType.POTATO, CropType.SUGAR_CANE, CropType.NETHER_WART)
- private val dicerCrops = listOf(CropType.PUMPKIN, CropType.MELON)
+ }
+ private val dicerCrops by lazy { listOf(CropType.PUMPKIN, CropType.MELON) }
private val farmingBoots = arrayListOf("RANCHERS_BOOTS", "FARMER_BOOTS")
- var cakeExpireTime = 0L
+ var cakeExpireTime = SimpleTimeMark.farPast()
- val necklaceFF = mutableMapOf<FFTypes, Double>()
- val cloakFF = mutableMapOf<FFTypes, Double>()
- val beltFF = mutableMapOf<FFTypes, Double>()
- val braceletFF = mutableMapOf<FFTypes, Double>()
- var equipmentTotalFF = mutableMapOf<FFTypes, Double>()
+ var equipmentTotalFF = mapOf<FFTypes, Double>()
- val helmetFF = mutableMapOf<FFTypes, Double>()
- val chestplateFF = mutableMapOf<FFTypes, Double>()
- val leggingsFF = mutableMapOf<FFTypes, Double>()
- val bootsFF = mutableMapOf<FFTypes, Double>()
- var armorTotalFF = mutableMapOf<FFTypes, Double>()
+ var armorTotalFF = mapOf<FFTypes, Double>()
var usingSpeedBoots = false
- val elephantFF = mutableMapOf<FFTypes, Double>()
- val mooshroomFF = mutableMapOf<FFTypes, Double>()
- val rabbitFF = mutableMapOf<FFTypes, Double>()
- val beeFF = mutableMapOf<FFTypes, Double>()
var currentPetItem = ""
- var baseFF = mutableMapOf<FFTypes, Double>()
-
- var totalBaseFF = mutableMapOf<FFTypes, Double>()
+ var baseFF = mapOf<FFTypes, Double>()
- val cropPage = mutableMapOf<FortuneStats, Pair<Double, Double>>()
+ var totalBaseFF = mapOf<FFTypes, Double>()
fun loadFFData() {
- cakeExpireTime = GardenAPI.storage?.fortune?.cakeExpiring ?: -1L
-
- getEquipmentFFData(FarmingItems.NECKLACE.getItem(), necklaceFF)
- getEquipmentFFData(FarmingItems.CLOAK.getItem(), cloakFF)
- getEquipmentFFData(FarmingItems.BELT.getItem(), beltFF)
- getEquipmentFFData(FarmingItems.BRACELET.getItem(), braceletFF)
+ cakeExpireTime = SimpleTimeMark(GardenAPI.storage?.fortune?.cakeExpiring ?: -1L)
- equipmentTotalFF =
- (necklaceFF.toList() + cloakFF.toList() + beltFF.toList() + braceletFF.toList()).groupBy({ it.first },
- { it.second }).map { (key, values) -> key to values.sum() }
- .toMap() as MutableMap<FFTypes, Double>
+ FarmingItems.resetFFData()
- getArmorFFData(FarmingItems.HELMET.getItem(), helmetFF)
- getArmorFFData(FarmingItems.CHESTPLATE.getItem(), chestplateFF)
- getArmorFFData(FarmingItems.LEGGINGS.getItem(), leggingsFF)
- getArmorFFData(FarmingItems.BOOTS.getItem(), bootsFF)
+ equipmentTotalFF = FarmingItems.equip.getFFData()
- armorTotalFF =
- (helmetFF.toList() + chestplateFF.toList() + leggingsFF.toList() + bootsFF.toList()).groupBy({ it.first },
- { it.second }).map { (key, values) -> key to values.sum() }
- .toMap() as MutableMap<FFTypes, Double>
+ armorTotalFF = FarmingItems.armor.getFFData()
- usingSpeedBoots = FarmingItems.BOOTS.getItem().getInternalName().asString() in farmingBoots
+ usingSpeedBoots = FarmingItems.BOOTS.getItem()?.getInternalName()?.asString() in farmingBoots
- getPetFFData(FarmingItems.ELEPHANT.getItem(), elephantFF)
- getPetFFData(FarmingItems.MOOSHROOM_COW.getItem(), mooshroomFF)
- getPetFFData(FarmingItems.RABBIT.getItem(), rabbitFF)
- getPetFFData(FarmingItems.BEE.getItem(), beeFF)
-
- getGenericFF(baseFF)
+ baseFF = getGenericFF()
getTotalFF()
}
- fun getCropStats(crop: CropType, tool: ItemStack) {
- cropPage.clear()
- cropPage[FortuneStats.BASE] = Pair(totalBaseFF[FFTypes.TOTAL] ?: 100.0, if (usingSpeedBoots) 1373.0 else 1377.0)
- cropPage[FortuneStats.CROP_UPGRADE] = Pair((crop.getUpgradeLevel()?.toDouble() ?: 0.0) * 5.0, 45.0)
- cropPage[FortuneStats.ACCESSORY] = Pair(CropAccessoryData.cropAccessory.getFortune(crop), 30.0)
- cropPage[FortuneStats.FFD] = Pair((tool.getFarmingForDummiesCount() ?: 0).toDouble(), 5.0)
- cropPage[FortuneStats.TURBO] = Pair(FarmingFortuneDisplay.getTurboCropFortune(tool, crop), 25.0)
- cropPage[FortuneStats.DEDICATION] = Pair(FarmingFortuneDisplay.getDedicationFortune(tool, crop), 92.0)
- cropPage[FortuneStats.CULTIVATING] = Pair(FarmingFortuneDisplay.getCultivatingFortune(tool), 20.0)
+ fun getCropStats(crop: CropType, tool: ItemStack?) {
+ FortuneStats.reset()
+
+ FortuneStats.BASE.set(FFInfos.UNIVERSAL.current, FFInfos.UNIVERSAL.max)
+ FortuneStats.CROP_UPGRADE.set((crop.getUpgradeLevel()?.toDouble() ?: 0.0) * 5.0, 45.0)
+ FortuneStats.ACCESSORY.set(CropAccessoryData.cropAccessory.getFortune(crop), 30.0)
+ FortuneStats.FFD.set((tool?.getFarmingForDummiesCount() ?: 0).toDouble(), 5.0)
+ FortuneStats.TURBO.set(FarmingFortuneDisplay.getTurboCropFortune(tool, crop), 25.0)
+ FortuneStats.DEDICATION.set(FarmingFortuneDisplay.getDedicationFortune(tool, crop), 92.0)
+ FortuneStats.CULTIVATING.set(FarmingFortuneDisplay.getCultivatingFortune(tool), 20.0)
FarmingFortuneDisplay.loadFortuneLineData(tool, 0.0)
when (crop) {
in mathCrops -> {
- cropPage[FortuneStats.BASE_TOOL] = Pair(FarmingFortuneDisplay.getToolFortune(tool), 50.0)
- cropPage[FortuneStats.COUNTER] = Pair(FarmingFortuneDisplay.getCounterFortune(tool), 96.0)
- cropPage[FortuneStats.HARVESTING] = Pair(FarmingFortuneDisplay.getHarvestingFortune(tool), 75.0)
- cropPage[FortuneStats.COLLECTION] = Pair(FarmingFortuneDisplay.getCollectionFortune(tool), 48.0)
- cropPage[FortuneStats.REFORGE] = Pair(FarmingFortuneDisplay.reforgeFortune, 20.0)
- cropPage[FortuneStats.GEMSTONE] = Pair(FarmingFortuneDisplay.gemstoneFortune, 30.0)
+ FortuneStats.BASE_TOOL.set(FarmingFortuneDisplay.getToolFortune(tool), 50.0)
+ FortuneStats.COUNTER.set(FarmingFortuneDisplay.getCounterFortune(tool), 96.0)
+ FortuneStats.HARVESTING.set(FarmingFortuneDisplay.getHarvestingFortune(tool), 75.0)
+ FortuneStats.COLLECTION.set(FarmingFortuneDisplay.getCollectionFortune(tool), 48.0)
+ FortuneStats.REFORGE.set(FarmingFortuneDisplay.reforgeFortune, 20.0)
+ FortuneStats.GEMSTONE.set(FarmingFortuneDisplay.gemstoneFortune, 30.0)
}
in dicerCrops -> {
- cropPage[FortuneStats.SUNDER] = Pair(FarmingFortuneDisplay.getSunderFortune(tool), 75.0)
- cropPage[FortuneStats.REFORGE] = Pair(FarmingFortuneDisplay.reforgeFortune, 20.0)
- cropPage[FortuneStats.GEMSTONE] = Pair(FarmingFortuneDisplay.gemstoneFortune, 20.0)
+ FortuneStats.SUNDER.set(FarmingFortuneDisplay.getSunderFortune(tool), 75.0)
+ FortuneStats.REFORGE.set(FarmingFortuneDisplay.reforgeFortune, 20.0)
+ FortuneStats.GEMSTONE.set(FarmingFortuneDisplay.gemstoneFortune, 20.0)
}
CropType.MUSHROOM -> {
- cropPage[FortuneStats.BASE_TOOL] = Pair(FarmingFortuneDisplay.getToolFortune(tool), 30.0)
- cropPage[FortuneStats.HARVESTING] = Pair(FarmingFortuneDisplay.getHarvestingFortune(tool), 75.0)
- cropPage[FortuneStats.REFORGE] = Pair(FarmingFortuneDisplay.reforgeFortune, 16.0)
- cropPage[FortuneStats.GEMSTONE] = Pair(FarmingFortuneDisplay.gemstoneFortune, 16.0)
+ FortuneStats.BASE_TOOL.set(FarmingFortuneDisplay.getToolFortune(tool), 30.0)
+ FortuneStats.HARVESTING.set(FarmingFortuneDisplay.getHarvestingFortune(tool), 75.0)
+ FortuneStats.REFORGE.set(FarmingFortuneDisplay.reforgeFortune, 16.0)
+ FortuneStats.GEMSTONE.set(FarmingFortuneDisplay.gemstoneFortune, 16.0)
}
CropType.COCOA_BEANS -> {
- cropPage[FortuneStats.BASE_TOOL] = Pair(FarmingFortuneDisplay.getToolFortune(tool), 20.0)
- cropPage[FortuneStats.SUNDER] = Pair(FarmingFortuneDisplay.getSunderFortune(tool), 75.0)
- cropPage[FortuneStats.REFORGE] = Pair(FarmingFortuneDisplay.reforgeFortune, 16.0)
- cropPage[FortuneStats.GEMSTONE] = Pair(FarmingFortuneDisplay.gemstoneFortune, 16.0)
+ FortuneStats.BASE_TOOL.set(FarmingFortuneDisplay.getToolFortune(tool), 20.0)
+ FortuneStats.SUNDER.set(FarmingFortuneDisplay.getSunderFortune(tool), 75.0)
+ FortuneStats.REFORGE.set(FarmingFortuneDisplay.reforgeFortune, 16.0)
+ FortuneStats.GEMSTONE.set(FarmingFortuneDisplay.gemstoneFortune, 16.0)
}
CropType.CACTUS -> {
- cropPage[FortuneStats.HARVESTING] = Pair(FarmingFortuneDisplay.getHarvestingFortune(tool), 75.0)
- cropPage[FortuneStats.REFORGE] = Pair(FarmingFortuneDisplay.reforgeFortune, 16.0)
- cropPage[FortuneStats.GEMSTONE] = Pair(FarmingFortuneDisplay.gemstoneFortune, 16.0)
+ FortuneStats.HARVESTING.set(FarmingFortuneDisplay.getHarvestingFortune(tool), 75.0)
+ FortuneStats.REFORGE.set(FarmingFortuneDisplay.reforgeFortune, 16.0)
+ FortuneStats.GEMSTONE.set(FarmingFortuneDisplay.gemstoneFortune, 16.0)
}
else -> {}
}
- if (crop == CropType.CARROT) {
- val storage = GardenAPI.storage?.fortune ?: return
- val carrotFortune = if (storage.carrotFortune) 12.0 else 0.0
- cropPage[FortuneStats.EXPORTED_CARROT] = Pair(carrotFortune, 12.0)
- }
- if (crop == CropType.PUMPKIN) {
- val storage = GardenAPI.storage?.fortune ?: return
- val pumpkinFortune = if (storage.pumpkinFortune) 12.0 else 0.0
- cropPage[FortuneStats.EXPIRED_PUMPKIN] = Pair(pumpkinFortune, 12.0)
- }
- if (crop == CropType.COCOA_BEANS) {
- val storage = GardenAPI.storage?.fortune ?: return
- val cocoaBeansFortune = if (storage.cocoaBeansFortune) 12.0 else 0.0
- cropPage[FortuneStats.SUPREME_CHOCOLATE_BAR] = Pair(cocoaBeansFortune, 12.0)
+ CarrolynTable.getByCrop(crop)?.let {
+ val ff = if (it.get()) 12.0 else 0.0
+ FortuneStats.CARROLYN.set(ff, 12.0)
}
- cropPage[FortuneStats.CROP_TOTAL] = Pair(
- cropPage.toList().sumOf { it.second.first },
- cropPage.toList().sumOf { it.second.second })
+ FortuneStats.CROP_TOTAL.set(FortuneStats.getTotal())
}
- private fun getEquipmentFFData(item: ItemStack, out: MutableMap<FFTypes, Double>) {
+ fun getEquipmentFFData(item: ItemStack?): Map<FFTypes, Double> = buildMap {
FarmingFortuneDisplay.loadFortuneLineData(item, 0.0)
- out[FFTypes.TOTAL] = 0.0
- out[FFTypes.BASE] = FarmingFortuneDisplay.itemBaseFortune
- out[FFTypes.REFORGE] = FarmingFortuneDisplay.reforgeFortune
- out[FFTypes.GREEN_THUMB] = FarmingFortuneDisplay.greenThumbFortune
- out[FFTypes.ABILITY] = FarmingFortuneDisplay.getAbilityFortune(item)
- out[FFTypes.TOTAL] = out.values.sum()
+ this[FFTypes.BASE] = FarmingFortuneDisplay.itemBaseFortune
+ this[FFTypes.REFORGE] = FarmingFortuneDisplay.reforgeFortune
+ this[FFTypes.GREEN_THUMB] = FarmingFortuneDisplay.greenThumbFortune
+ this[FFTypes.ABILITY] = FarmingFortuneDisplay.getAbilityFortune(item)
+ this[FFTypes.TOTAL] = this.values.sum()
}
- private fun getArmorFFData(item: ItemStack, out: MutableMap<FFTypes, Double>) {
+ fun getArmorFFData(item: ItemStack?): Map<FFTypes, Double> = buildMap {
FarmingFortuneDisplay.loadFortuneLineData(item, 0.0)
- out[FFTypes.TOTAL] = 0.0
- out[FFTypes.BASE] = FarmingFortuneDisplay.itemBaseFortune
- out[FFTypes.REFORGE] = FarmingFortuneDisplay.reforgeFortune
- out[FFTypes.GEMSTONE] = FarmingFortuneDisplay.gemstoneFortune
- out[FFTypes.PESTERMINATOR] = FarmingFortuneDisplay.pesterminatorFortune
- out[FFTypes.ABILITY] = FarmingFortuneDisplay.getAbilityFortune(item)
- out[FFTypes.TOTAL] = out.values.sum()
+ this[FFTypes.BASE] = FarmingFortuneDisplay.itemBaseFortune
+ this[FFTypes.REFORGE] = FarmingFortuneDisplay.reforgeFortune
+ this[FFTypes.GEMSTONE] = FarmingFortuneDisplay.gemstoneFortune
+ this[FFTypes.PESTERMINATOR] = FarmingFortuneDisplay.pesterminatorFortune
+ this[FFTypes.ABILITY] = FarmingFortuneDisplay.getAbilityFortune(item)
+ this[FFTypes.TOTAL] = this.values.sum()
}
- private fun getPetFFData(item: ItemStack, out: MutableMap<FFTypes, Double>) {
+ fun getPetFFData(item: ItemStack?): Map<FFTypes, Double> = buildMap {
val gardenLvl = GardenAPI.getGardenLevel(overflow = false)
- out[FFTypes.TOTAL] = 0.0
- out[FFTypes.BASE] = getPetFF(item)
- out[FFTypes.PET_ITEM] = when (item.getPetItem()) {
+ this[FFTypes.BASE] = getPetFF(item)
+ this[FFTypes.PET_ITEM] = when (item?.getPetItem()) {
"GREEN_BANDANA" -> 4.0 * gardenLvl
"YELLOW_BANDANA" -> 30.0
- "MINOS_RELIC" -> (out[FFTypes.BASE] ?: 0.0) * .33
+ "MINOS_RELIC" -> (this[FFTypes.BASE] ?: 0.0) * .33
else -> 0.0
}
- out[FFTypes.TOTAL] = out.values.sum()
+ this[FFTypes.TOTAL] = this.values.sum()
}
- private fun getGenericFF(out: MutableMap<FFTypes, Double>) {
- val storage = GardenAPI.storage?.fortune ?: return
- out[FFTypes.TOTAL] = 0.0
- out[FFTypes.BASE_FF] = 100.0
- out[FFTypes.FARMING_LVL] = storage.farmingLevel.toDouble() * 4
- out[FFTypes.COMMUNITY_SHOP] = (ProfileStorageData.playerSpecific?.gardenCommunityUpgrade ?: -1).toDouble() * 4
- out[FFTypes.PLOTS] = storage.plotsUnlocked.toDouble() * 3
- out[FFTypes.ANITA] = storage.anitaUpgrade.toDouble() * 4
- if (cakeExpireTime - System.currentTimeMillis() > 0 || cakeExpireTime == -1L) {
- out[FFTypes.CAKE] = 5.0
+ private fun getGenericFF(): Map<FFTypes, Double> = buildMap {
+ val storage = GardenAPI.storage?.fortune ?: return emptyMap()
+ this[FFTypes.BASE_FF] = 100.0
+ this[FFTypes.FARMING_LVL] = storage.farmingLevel.toDouble() * 4
+ this[FFTypes.COMMUNITY_SHOP] = (ProfileStorageData.playerSpecific?.gardenCommunityUpgrade ?: -1).toDouble() * 4
+ this[FFTypes.PLOTS] = storage.plotsUnlocked.toDouble() * 3
+ this[FFTypes.ANITA] = storage.anitaUpgrade.toDouble() * 4
+ if (cakeExpireTime.isInPast() || cakeExpireTime.isFarPast()) {
+ this[FFTypes.CAKE] = 5.0
} else {
- out[FFTypes.CAKE] = 0.0
+ this[FFTypes.CAKE] = 0.0
}
- out[FFTypes.TOTAL] = out.values.sum()
+ this[FFTypes.TOTAL] = this.values.sum()
}
fun getTotalFF() {
- var petList = mutableMapOf<FFTypes, Double>()
- when (FFGuideGUI.currentPet) {
- FarmingItems.ELEPHANT -> {
- petList = elephantFF
- }
- FarmingItems.MOOSHROOM_COW -> {
- petList = mooshroomFF
- }
+ currentPetItem = FarmingItems.currentPet.getItem()?.getPetItem().toString()
- FarmingItems.RABBIT -> {
- petList = rabbitFF
- }
-
- FarmingItems.BEE -> {
- petList = beeFF
- }
+ totalBaseFF = combineFFData(
+ baseFF, armorTotalFF, equipmentTotalFF, FarmingItems.currentPet.getFFData()
+ )
+ FFGuideGUI.updateDisplay()
+ }
- else -> {}
- }
- currentPetItem = FFGuideGUI.currentPet.getItem().getPetItem().toString()
+ fun List<FarmingItems>.getFFData(): Map<FFTypes, Double> = combineFFData(this.map { it.getFFData() })
- totalBaseFF =
- (baseFF.toList() + armorTotalFF.toList() + equipmentTotalFF.toList() + petList.toList()).groupBy({ it.first },
- { it.second }).map { (key, values) -> key to values.sum() }
- .toMap() as MutableMap<FFTypes, Double>
- }
+ fun combineFFData(vararg value: Map<FFTypes, Double>) = combineFFData(value.toList())
+ fun combineFFData(value: List<Map<FFTypes, Double>>) =
+ value.map { it.toList() }.flatten().groupBy({ it.first }, { it.second })
+ .mapValues { (_, values) -> values.sum() }
- private fun getPetFF(pet: ItemStack): Double {
+ private fun getPetFF(pet: ItemStack?): Double {
+ if (pet == null) return 0.0
val petLevel = pet.getPetLevel()
val strength = (GardenAPI.storage?.fortune?.farmingStrength)
if (strength != null) {
@@ -253,4 +194,5 @@ object FFStats {
}
return 0.0
}
+
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingItems.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingItems.kt
index f2bd6b360..46b5d1e07 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingItems.kt
@@ -1,26 +1,166 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide
-enum class FarmingItems {
- WHEAT,
- CARROT,
- POTATO,
- NETHER_WART,
- PUMPKIN,
- MELON,
- COCOA_BEANS,
- SUGAR_CANE,
- CACTUS,
- MUSHROOM,
- HELMET,
- CHESTPLATE,
- LEGGINGS,
- BOOTS,
- NECKLACE,
- CLOAK,
- BELT,
- BRACELET,
- ELEPHANT,
- MOOSHROOM_COW,
- RABBIT,
- BEE,
+import at.hannibal2.skyhanni.data.ProfileStorageData
+import at.hannibal2.skyhanni.utils.ItemCategory
+import at.hannibal2.skyhanni.utils.RenderUtils
+import at.hannibal2.skyhanni.utils.SoundUtils
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import net.minecraft.client.gui.GuiScreen
+import net.minecraft.init.Blocks
+import net.minecraft.item.ItemStack
+
+enum class FarmingItems(
+ val itemCategory: ItemCategory,
+ private val ffCalculation: (ItemStack?) -> Map<FFTypes, Double> = { emptyMap() },
+) {
+ WHEAT(ItemCategory.HOE),
+ CARROT(ItemCategory.HOE),
+ POTATO(ItemCategory.HOE),
+ NETHER_WART(ItemCategory.HOE),
+ PUMPKIN(ItemCategory.AXE),
+ MELON(ItemCategory.AXE),
+ COCOA_BEANS(ItemCategory.AXE),
+ SUGAR_CANE(ItemCategory.HOE),
+ CACTUS(ItemCategory.HOE),
+ MUSHROOM(ItemCategory.HOE),
+ HELMET(ItemCategory.HELMET, FFStats::getArmorFFData),
+ CHESTPLATE(ItemCategory.CHESTPLATE, FFStats::getArmorFFData),
+ LEGGINGS(ItemCategory.LEGGINGS, FFStats::getArmorFFData),
+ BOOTS(ItemCategory.BOOTS, FFStats::getArmorFFData),
+ NECKLACE(ItemCategory.NECKLACE, FFStats::getEquipmentFFData),
+ CLOAK(ItemCategory.CLOAK, FFStats::getEquipmentFFData),
+ BELT(ItemCategory.BELT, FFStats::getEquipmentFFData),
+ BRACELET(ItemCategory.BRACELET, FFStats::getEquipmentFFData),
+ ELEPHANT(ItemCategory.PET, FFStats::getPetFFData),
+ MOOSHROOM_COW(ItemCategory.PET, FFStats::getPetFFData),
+ RABBIT(ItemCategory.PET, FFStats::getPetFFData),
+ BEE(ItemCategory.PET, FFStats::getPetFFData),
+ ;
+
+ var selectedState = false
+
+ fun getItem() = getItemOrNull() ?: fallbackItem
+
+ private val fallbackItem: ItemStack by lazy {
+ val name = "§cNo saved ${name.lowercase().replace("_", " ")}"
+ ItemStack(Blocks.barrier).setStackDisplayName(name)
+ }
+
+ fun getItemOrNull() = ProfileStorageData.profileSpecific?.garden?.fortune?.farmingItems?.get(this)
+ fun setItem(value: ItemStack) = ProfileStorageData.profileSpecific?.garden?.fortune?.farmingItems?.set(this, value)
+
+ private fun onClick(): () -> Unit = when (this) {
+ in armor -> {
+ {
+ SoundUtils.playClickSound()
+ currentArmor = if (selectedState) null else this
+ armor.forEach {
+ it.selectedState = it == currentArmor
+ }
+ FFGuideGUI.updateDisplay()
+ }
+ }
+
+ in equip -> {
+ {
+ SoundUtils.playClickSound()
+ currentEquip = if (selectedState) null else this
+ equip.forEach {
+ it.selectedState = it == currentEquip
+ }
+ FFGuideGUI.updateDisplay()
+ }
+ }
+
+ in pets -> {
+ {
+ val prev = currentPet
+ currentPet = if (selectedState) lastEquippedPet else this
+ if (prev != currentPet) {
+ SoundUtils.playClickSound()
+ }
+ pets.forEach {
+ it.selectedState = it == currentPet
+ }
+ FFStats.getTotalFF()
+ }
+ }
+
+ else -> {
+ {}
+ }
+ }
+
+ fun getDisplay(clickEnabled: Boolean = false) = object : Renderable {
+
+ val content = Renderable.clickable(
+ Renderable.itemStackWithTip(
+ getItem(), 1.0, 0, 0, false
+ ),
+ onClick = onClick(),
+ condition = { clickEnabled })
+
+ override val width = content.width
+ override val height = content.height
+ override val horizontalAlign = RenderUtils.HorizontalAlignment.CENTER
+ override val verticalAlign = RenderUtils.VerticalAlignment.CENTER
+
+ override fun render(posX: Int, posY: Int) {
+ GuiScreen.drawRect(
+ 0,
+ 0,
+ width,
+ height,
+ if (this@FarmingItems.selectedState) 0xFFB3FFB3.toInt() else 0xFF43464B.toInt()
+ )
+ content.render(posX, posY)
+ }
+ }
+
+ private var ffData: Map<FFTypes, Double>? = null
+
+ fun getFFData() = ffData ?: run {
+ val data = ffCalculation(getItemOrNull())
+ ffData = data
+ data
+ }
+
+ companion object {
+
+ // TODO
+ var lastEquippedPet = ELEPHANT
+
+ var currentPet: FarmingItems = lastEquippedPet
+ var currentArmor: FarmingItems? = null
+ var currentEquip: FarmingItems? = null
+
+ val armor = listOf(HELMET, CHESTPLATE, LEGGINGS, BOOTS)
+ val equip = listOf(NECKLACE, CLOAK, BELT, BRACELET)
+ val pets = listOf(ELEPHANT, MOOSHROOM_COW, RABBIT, BEE)
+
+ fun getArmorDisplay(clickEnabled: Boolean = false): List<Renderable> = armor.map { it.getDisplay(clickEnabled) }
+
+ fun getEquipmentDisplay(clickEnabled: Boolean = false): List<Renderable> =
+ equip.map { it.getDisplay(clickEnabled) }
+
+ fun getPetsDisplay(clickEnabled: Boolean = false): List<Renderable> = pets.map { it.getDisplay(clickEnabled) }
+ fun resetClickState() {
+ entries.filterNot { pets.contains(it) }.forEach { it.selectedState = false }
+ }
+
+ fun resetFFData() {
+ entries.forEach { it.ffData = null }
+ }
+
+ fun setDefaultPet(): FarmingItems {
+ currentPet = lastEquippedPet
+ pets.forEach {
+ it.selectedState = it == currentPet
+ }
+ return lastEquippedPet
+ }
+
+ fun getFromItemCategory(category: ItemCategory) = entries.filter { it.itemCategory == category }
+ fun getFromItemCategoryOne(category: ItemCategory) = entries.firstOrNull { it.itemCategory == category }
+ }
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingReforges.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingReforges.kt
index 1e911688a..6ac7171fb 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingReforges.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FarmingReforges.kt
@@ -1,5 +1,6 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide
+// TODO replace with ReforgeAPI
enum class FarmingReforges(
val reforgeName: String,
val reforgeItem: String,
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt
index 863bc9518..b5558b638 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneStats.kt
@@ -1,12 +1,21 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide
-enum class FortuneStats(val label: String, val tooltip: String) {
+import at.hannibal2.skyhanni.features.garden.CropType
+import at.hannibal2.skyhanni.utils.CollectionUtils.sumOfPair
+import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase
+
+enum class FortuneStats(
+ private val label0: (CropType) -> String,
+ private val tooltip0: (CropType) -> String,
+ val onClick: (CropType) -> Unit = {},
+) {
BASE(
"§2Universal Farming Fortune",
- "§7§2Farming fortune in that is\n§2applied to every crop\n§eNot the same as tab FF\n" +
- "§eSee on the grass block page"
+ "§7§2Farming fortune in that is\n§2applied to every crop\n§eNot the same as tab FF\n" + "§eSee on the grass block page"
),
- CROP_TOTAL("§6Crop Farming Fortune", "§7§2Farming fortune for this crop"),
+ CROP_TOTAL(
+ { crop -> "§6${crop.niceName.firstLetterUppercase()} Farming Fortune" },
+ { "§7§2Farming fortune for this crop" }),
ACCESSORY("§2Talisman Bonus", "§7§2Fortune from your talisman\n§2You get 10☘ per talisman tier"),
CROP_UPGRADE("§2Crop Upgrade", "§7§2Fortune from Desk crop upgrades\n§2You get 5☘ per level"),
BASE_TOOL("§2Base tool fortune", "§7§2Crop specific fortune from your tool"),
@@ -20,19 +29,53 @@ enum class FortuneStats(val label: String, val tooltip: String) {
CULTIVATING("§2Cultivating Enchantment", "§7§2Fortune for each enchantment level\n§2You get 2☘ per level"),
TURBO("§2Turbo-Crop Enchantment", "§7§2Fortune for each enchantment level\n§2You get 5☘ per level"),
DEDICATION("§2Dedication Enchantment", "§7§2Fortune for each enchantment level\n§2and crop milestone"),
- EXPORTED_CARROT(
- "§2Exportable Carrots",
- "§7§2Gain 12☘ from giving 3,000 to Carrolyn in Scarleton!\n" +
- "§eRun /shcarrot to toggle the stat"
- ),
- EXPIRED_PUMPKIN(
- "§2Expired Pumpkin",
- "§7§2Gain 12☘ from giving 3,000 to Carrolyn in Scarleton!\n" +
- "§eRun /shpumpkin to toggle the stat"
- ),
- SUPREME_CHOCOLATE_BAR(
- "§2Supreme Chocolate Bar",
- "§7§2Gain 12☘ from giving 3,000 to Carrolyn in Scarleton!\n" +
- "§eRun /shcocoabeans to toggle the stat"
- ),
+ CARROLYN(::carrolynLabel, ::carrolynToolTip, ::carrolynOnClick),
+ ;
+
+ constructor(label: String, tooltip: String) : this({ label }, { tooltip })
+
+ var current: Double = 0.0
+ var max: Double = -1.0
+
+ fun label(crop: CropType) = label0(crop)
+ fun tooltip(crop: CropType) = tooltip0(crop)
+
+ fun reset() {
+ current = 0.0
+ max = -1.0
+ }
+
+ fun set(value: Pair<Double, Double>) {
+ current = value.first
+ max = value.second
+ }
+
+ fun set(current: Double, max: Double) {
+ this.current = current
+ this.max = max
+ }
+
+ fun isActive() = max != -1.0
+
+ companion object {
+
+ fun getTotal(): Pair<Double, Double> = entries.filter { it.isActive() }.sumOfPair { it.current to it.max }
+
+ fun reset() = entries.forEach { it.reset() }
+ }
}
+
+private fun carrolynLabel(crop: CropType): String =
+ CarrolynTable.getByCrop(crop)?.label?.let { "§2$it" } ?: "§cError"
+
+private fun carrolynToolTip(crop: CropType): String =
+ "§7§2Gain 12☘ from giving 3,000\n§2 to Carrolyn in Scarleton!\n §e`Run /shcarrolyn ${
+ crop.niceName
+ }` to toggle the stat\n §eor click the value"
+
+private fun carrolynOnClick(crop: CropType) =
+ CarrolynTable.getByCrop(crop)?.let {
+ it.setVisibleActive(!it.get())
+ FFGuideGUI.updateDisplay()
+ }
+
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrade.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrade.kt
index 43b0c37d3..769253538 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrade.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrade.kt
@@ -1,12 +1,16 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide
+import at.hannibal2.skyhanni.utils.NEUInternalName
+import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
+
data class FortuneUpgrade(
val description: String,
val costCopper: Int?,
- //todo make into NEUInternalName
- val requiredItem: String,
+ private val requiredItemName: String,
val itemQuantity: Int,
val fortuneIncrease: Double,
var cost: Int? = null,
var costPerFF: Int? = null, // also the same as time to repay
-)
+) {
+ val requiredItem: NEUInternalName = requiredItemName.asInternalName()
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt
index 191b9b7e5..43289dc62 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/FortuneUpgrades.kt
@@ -9,12 +9,9 @@ import at.hannibal2.skyhanni.features.garden.CropType.Companion.getTurboCrop
import at.hannibal2.skyhanni.features.garden.FarmingFortuneDisplay
import at.hannibal2.skyhanni.features.garden.GardenAPI
import at.hannibal2.skyhanni.features.garden.GardenAPI.getCropType
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.currentPet
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.getItem
import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName
import at.hannibal2.skyhanni.utils.ItemUtils.getItemRarityOrCommon
import at.hannibal2.skyhanni.utils.ItemUtils.itemName
-import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.NEUItems.getPrice
import at.hannibal2.skyhanni.utils.NumberUtil.addSuffix
import at.hannibal2.skyhanni.utils.SkyBlockItemModifierUtils.getEnchantments
@@ -25,8 +22,6 @@ import net.minecraft.item.ItemStack
object FortuneUpgrades {
- private val equipment = listOf(FarmingItems.NECKLACE, FarmingItems.CLOAK, FarmingItems.BELT, FarmingItems.BRACELET)
- private val armor = listOf(FarmingItems.HELMET, FarmingItems.CHESTPLATE, FarmingItems.LEGGINGS, FarmingItems.BOOTS)
private val axeCrops = listOf(CropType.MELON, CropType.PUMPKIN, CropType.COCOA_BEANS)
val genericUpgrades = mutableListOf<FortuneUpgrade>()
@@ -64,7 +59,7 @@ object FortuneUpgrades {
// todo fix NEU price data not being loaded if run too early
private fun MutableList<FortuneUpgrade>.populateAndSort(style: Int) {
this.map { upgrade ->
- val cost = (upgrade.requiredItem.asInternalName().getPrice() * upgrade.itemQuantity).toInt()
+ val cost = (upgrade.requiredItem.getPrice() * upgrade.itemQuantity).toInt()
upgrade.cost = cost
upgrade.costPerFF = (cost / upgrade.fortuneIncrease).toInt()
}
@@ -94,8 +89,8 @@ object FortuneUpgrades {
private fun getEquipmentUpgrades() {
val visitors = GardenAPI.storage?.uniqueVisitors?.toDouble() ?: 0.0
- for (piece in equipment) {
- val item = piece.getItem()
+ for (piece in FarmingItems.equip) {
+ val item = piece.getItem() ?: return
// todo tell them to buy the missing item
if (!item.getInternalName().contains("LOTUS")) return
val enchantments = item.getEnchantments() ?: emptyMap()
@@ -124,11 +119,8 @@ object FortuneUpgrades {
// todo adding armor tier upgrades later
private fun getArmorUpgrades() {
- for (piece in armor) {
- val item = piece.getItem()
- // todo skip if it doesnt exist -> tell them to buy it later
-
- if (FFGuideGUI.isFallbackItem(item)) return
+ for (piece in FarmingItems.armor) {
+ val item = piece.getItemOrNull() ?: return // todo tell them to buy it later
recombobulateItem(item, genericUpgrades)
when (item.getReforgeName()) {
@@ -146,7 +138,7 @@ object FortuneUpgrades {
// todo needs to be called when switching pets
private fun getPetUpgrades() {
- if (currentPet.getItem().getInternalName().contains(";")) {
+ if (FarmingItems.currentPet.getItemOrNull()?.getInternalName()?.contains(";") == true) {
when (FFStats.currentPetItem) {
"GREEN_BANDANA" -> {}
"YELLOW_BANDANA" -> {
@@ -160,11 +152,11 @@ object FortuneUpgrades {
}
}
- fun getCropSpecific(tool: ItemStack) {
+ fun getCropSpecific(tool: ItemStack?) {
cropSpecificUpgrades.clear()
cropSpecificUpgrades.addAll(genericUpgrades)
// todo tell them to get the tool if it is missing
- val crop = tool.getCropType() ?: return
+ val crop = tool?.getCropType() ?: return
val enchantments = tool.getEnchantments() ?: emptyMap()
val turboCropLvl = enchantments[crop.getTurboCrop()] ?: 0
val dedicationLvl = enchantments["dedication"] ?: 0
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt
index d9558cd2f..ca813a4ae 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/CropPage.kt
@@ -1,53 +1,87 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide.pages
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.getItem
+import at.hannibal2.skyhanni.features.garden.CropType
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFStats
import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems
import at.hannibal2.skyhanni.features.garden.fortuneguide.FortuneStats
+import at.hannibal2.skyhanni.utils.CollectionUtils.split
import at.hannibal2.skyhanni.utils.GuiRenderUtils
-import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase
-
-class CropPage : FFGuideGUI.FFGuidePage() {
-
- override fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float) {
- for (item in FarmingItems.entries) {
- if (item.name == FFGuideGUI.currentCrop?.name) {
- GuiRenderUtils.renderItemAndTip(
- FFGuideGUI.tooltipToDisplay,
- item.getItem(),
- FFGuideGUI.guiLeft + 172,
- FFGuideGUI.guiTop + 60,
- mouseX,
- mouseY
- )
- }
- }
-
- var x: Int
- var y = FFGuideGUI.guiTop - 20
- var i = 0
- FFStats.cropPage.forEach { (key, value) ->
- if (key == FortuneStats.CROP_TOTAL) {
- val newLine =
- key.label.replace("Crop", FFGuideGUI.currentCrop?.name?.replace("_", " ")?.firstLetterUppercase()!!)
- GuiRenderUtils.drawFarmingBar(
- newLine, key.tooltip, value.first, value.second, FFGuideGUI.guiLeft + 135,
- FFGuideGUI.guiTop + 5, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
- )
- } else {
- if (i % 2 == 0) {
- x = FFGuideGUI.guiLeft + 15
- y += 25
- } else {
- x = FFGuideGUI.guiLeft + 255
- }
- i++
- GuiRenderUtils.drawFarmingBar(
- key.label, key.tooltip, value.first, value.second, x, y,
- 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+import at.hannibal2.skyhanni.utils.RenderUtils
+import at.hannibal2.skyhanni.utils.guide.GuideTablePage
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+
+class CropPage(val crop0: () -> CropType, sizeX: Int, sizeY: Int, paddingX: Int = 15, paddingY: Int = 7) :
+ GuideTablePage(
+ sizeX,
+ sizeY,
+ paddingX,
+ paddingY
+ ) {
+
+ val crop get() = crop0()
+
+ override fun onEnter() {
+ val item = crop.farmingItem
+ FFStats.getCropStats(crop, item.getItemOrNull())
+
+ FarmingItems.resetClickState()
+ val toolLines = toolLines().split().map { Renderable.verticalContainer(it, 2) }
+ update(
+ listOf(
+ header(),
+ listOf(
+ toolLines[0],
+ equipDisplay(),
+ toolLines[1],
)
- }
- }
+ ),
+ emptyList()
+ )
+ }
+
+ private fun header(): List<Renderable> = buildList {
+ add(FortuneStats.BASE.getFarmingBar())
+
+ add(
+ FortuneStats.CROP_TOTAL.getFarmingBar(110)
+ )
+
+ add(FortuneStats.CROP_UPGRADE.getFarmingBar())
+ }
+
+ private fun FortuneStats.getFarmingBar(
+ width: Int = 90,
+ ) = Renderable.clickable(
+ GuiRenderUtils.getFarmingBar(label(crop), tooltip(crop), current, max, width),
+ { onClick(crop) })
+
+ private fun toolLines(): List<Renderable> =
+ FortuneStats.entries.filter { it.isActive() && it !in headers }.map { it.getFarmingBar() }
+
+ private fun equipDisplay(): Renderable =
+ Renderable.fixedSizeCollum(
+ Renderable.verticalContainer(
+ listOf(
+ crop.farmingItem.getDisplay(),
+ Renderable.horizontalContainer(
+ listOf(
+ Renderable.verticalContainer(FarmingItems.getArmorDisplay(), 2),
+ Renderable.verticalContainer(FarmingItems.getEquipmentDisplay(), 2)
+ ),
+ 2,
+ horizontalAlign = RenderUtils.HorizontalAlignment.CENTER
+ ),
+ Renderable.horizontalContainer(FarmingItems.getPetsDisplay(true), 2)
+ ),
+ 2,
+ verticalAlign = RenderUtils.VerticalAlignment.BOTTOM
+ ),
+ 144,
+ horizontalAlign = RenderUtils.HorizontalAlignment.CENTER,
+ verticalAlign = RenderUtils.VerticalAlignment.BOTTOM
+ )
+
+ companion object {
+ private val headers = setOf(FortuneStats.BASE, FortuneStats.CROP_TOTAL, FortuneStats.CROP_UPGRADE)
}
}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt
index 605081e4e..577020cfb 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/OverviewPage.kt
@@ -1,272 +1,234 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide.pages
-import at.hannibal2.skyhanni.features.garden.GardenAPI
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.currentArmor
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.currentEquipment
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI.Companion.getItem
+import at.hannibal2.skyhanni.features.garden.fortuneguide.FFInfos
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFStats
import at.hannibal2.skyhanni.features.garden.fortuneguide.FFTypes
import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems
-import at.hannibal2.skyhanni.utils.GuiRenderUtils
-import at.hannibal2.skyhanni.utils.TimeUtils
-
-class OverviewPage : FFGuideGUI.FFGuidePage() {
-
- private var equipmentFF = mutableMapOf<FFTypes, Double>()
- private var armorFF = mutableMapOf<FFTypes, Double>()
+import at.hannibal2.skyhanni.utils.CollectionUtils.getOrNull
+import at.hannibal2.skyhanni.utils.RenderUtils
+import at.hannibal2.skyhanni.utils.TimeUnit
+import at.hannibal2.skyhanni.utils.TimeUtils.format
+import at.hannibal2.skyhanni.utils.guide.GuideTablePage
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+
+class OverviewPage(sizeX: Int, sizeY: Int, paddingX: Int = 15, paddingY: Int = 7, footerSpacing: Int = 6) :
+ GuideTablePage(
+ sizeX, sizeY, paddingX, paddingY, footerSpacing
+ ) {
+
+ override fun onEnter() {
+ val (content, footer) = getPage()
+ update(content, footer)
+ }
// TODO display armor stats for gemstones and pesterminator
- override fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float) {
- val timeUntilCakes = TimeUtils.formatDuration(FFStats.cakeExpireTime - System.currentTimeMillis())
-
- GuiRenderUtils.drawFarmingBar(
- "§6Universal Farming Fortune",
- "§7§2Farming fortune in that is\n§2applied to every crop\n§eNot the same as tab FF\n" +
- "§eSee on the grass block page", FFStats.totalBaseFF[FFTypes.TOTAL] ?: 0, if (FFStats.usingSpeedBoots) 1373 else 1377,
- FFGuideGUI.guiLeft + 15, FFGuideGUI.guiTop + 5, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
- )
+ // TODO display pest bestiary
+ fun getPage(): Pair<List<List<Renderable>>, List<Renderable>> {
+ val content = mutableListOf<MutableList<Renderable>>()
+ val footer = mutableListOf<Renderable>()
+ val timeUntilCakes = FFStats.cakeExpireTime.passedSince().format(TimeUnit.HOUR, false, false, -1)
- var line = if (FFTypes.ANITA.notSaved()) "§cAnita buff not saved\n§eVisit Anita to set it!"
- else "§7§2Fortune for levelling your Anita extra crops\n§2You get 4☘ per buff level"
- GuiRenderUtils.drawFarmingBar(
- "§2Anita Buff", line, FFStats.baseFF[FFTypes.ANITA] ?: 0.0, 60, FFGuideGUI.guiLeft + 15,
- FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 0,
+ FFInfos.UNIVERSAL.bar(
+ "§6Universal Farming Fortune",
+ "§7§2Farming fortune in that is\n§2applied to every crop\n§eNot the same as tab FF\n" +
+ "§eSee on the grass block page"
+ )
+ )
+
+ content.addTable(
+ 1,
+ FFInfos.ANITA_BUFF.bar(
+ "§2Anita Buff", if (FFTypes.ANITA.notSaved()) "§cAnita buff not saved\n§eVisit Anita to set it!"
+ else "§7§2Fortune for levelling your Anita extra crops\n§2You get 4☘ per buff level"
+ )
)
- line = if (FFTypes.FARMING_LVL.notSaved()) "§cFarming level not saved\n§eOpen /skills to set it!"
- else "§7§2Fortune for levelling your farming skill\n§2You get 4☘ per farming level"
- GuiRenderUtils.drawFarmingBar(
- "§2Farming Level", line, FFStats.baseFF[FFTypes.FARMING_LVL] ?: 0.0, 240, FFGuideGUI.guiLeft + 15,
- FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 2,
+ FFInfos.FARMING_LEVEL.bar(
+ "§2Farming Level",
+ if (FFTypes.FARMING_LVL.notSaved()) "§cFarming level not saved\n§eOpen /skills to set it!"
+ else "§7§2Fortune for levelling your farming skill\n§2You get 4☘ per farming level"
+ )
)
- line =
- if (FFTypes.COMMUNITY_SHOP.notSaved()) "§cCommunity upgrade level not saved\n§eVisit Elizabeth to set it!"
- else "§7§2Fortune for community shop upgrades\n§2You get 4☘ per upgrade tier"
- GuiRenderUtils.drawFarmingBar(
- "§2Community upgrades", line, FFStats.baseFF[FFTypes.COMMUNITY_SHOP] ?: 0.0,
- 40, FFGuideGUI.guiLeft + 15, FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 3,
+ FFInfos.COMMUNITY_SHOP.bar(
+ "§2Community upgrades",
+ if (FFTypes.COMMUNITY_SHOP.notSaved()) "§cCommunity upgrade level not saved\n§eVisit Elizabeth to set it!"
+ else "§7§2Fortune for community shop upgrades\n§2You get 4☘ per upgrade tier"
+ )
)
- line =
- if (FFTypes.PLOTS.notSaved()) "§cUnlocked plot count not saved\n§eOpen /desk and view your plots to set it!"
- else "§7§2Fortune for unlocking garden plots\n§2You get 3☘ per plot unlocked"
- GuiRenderUtils.drawFarmingBar(
- "§2Garden Plots", line, FFStats.baseFF[FFTypes.PLOTS] ?: 0.0, 72, FFGuideGUI.guiLeft + 15,
- FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 4,
+ FFInfos.GARDEN_PLOTS.bar(
+ "§2Garden Plots",
+ if (FFTypes.PLOTS.notSaved()) "§cUnlocked plot count not saved\n§eOpen /desk and view your plots to set it!"
+ else "§7§2Fortune for unlocking garden plots\n§2You get 3☘ per plot unlocked"
+ )
)
- line = when (FFStats.cakeExpireTime) {
- -1L -> "§eYou have not eaten a cake since\n§edownloading this update, assuming the\n§ebuff is active!"
- else -> "§7§2Fortune for eating cake\n§2You get 5☘ for eating cake\n§2Time until cake buff runs out: $timeUntilCakes"
- }
- if (FFStats.cakeExpireTime - System.currentTimeMillis() < 0 && FFStats.cakeExpireTime != -1L) {
- line = "§cYour cake buff has run out\nGo eat some cake!"
- }
- GuiRenderUtils.drawFarmingBar(
- "§2Cake Buff", line, FFStats.baseFF[FFTypes.CAKE] ?: 0.0, 5, FFGuideGUI.guiLeft + 15,
- FFGuideGUI.guiTop + 130, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
- )
+ content.addTable(
+ 5,
+ FFInfos.CAKE_BUFF.bar(
+ "§2Cake Buff", when {
+ FFStats.cakeExpireTime.isFarPast() -> "§eYou have not eaten a cake since\n§edownloading this update, assuming the\n§ebuff is active!"
+ FFStats.cakeExpireTime.isInPast() -> "§cYour cake buff has run out\nGo eat some cake!"
+ else -> "§7§2Fortune for eating cake\n§2You get 5☘ for eating cake\n§2Time until cake buff runs out: $timeUntilCakes"
+ }
+ )
+ )
+
+ val armorName = FarmingItems.currentArmor?.getItem()?.displayName ?: ""
+
+ val wordArmor = if (FarmingItems.currentArmor == null) "Armor" else "Piece"
+
+
+ content.addTable(
+ 1,
+ FFInfos.TOTAL_ARMOR.bar(
+ "§2Total $wordArmor Fortune",
+ if (FarmingItems.currentArmor == null) "§7§2Total fortune from your armor\n§2Select a piece for more info"
+ else "§7§2Total fortune from your\n$armorName"
+ )
+ )
+
+ content.addTable(
+ 2,
+ FFInfos.BASE_ARMOR.bar(
+ "§2Base $wordArmor Fortune",
+ if (FarmingItems.currentArmor == null) "§7§2The base fortune from your armor\n§2Select a piece for more info"
+ else "§7§2Base fortune from your\n$armorName"
+ )
+ )
+
+ content.addTable(
+ 3,
+ FFInfos.ABILITY_ARMOR.bar(
+ "§2$wordArmor Ability",
+ if (FarmingItems.currentArmor == null) "§7§2The fortune from your armor's ability\n§2Select a piece for more info"
+ else "§7§2Ability fortune from your\n$armorName"
+ )
+ )
+
+ content.addTable(
+ 4,
+ FFInfos.REFORGE_ARMOR.bar(
+ "§2$wordArmor Reforge",
+ if (FarmingItems.currentArmor == null) "§7§2The fortune from your armor's reforge\n§2Select a piece for more info"
+ else "§7§2Total fortune from your\n$armorName}"
+ )
+ )
+
+ footer.add(
+ FFInfos.TOTAL_PET.bar("§2Total Pet Fortune", "§7§2The total fortune from your pet and its item")
+ )
- val armorItem = when (currentArmor) {
- 1 -> FarmingItems.HELMET
- 2 -> FarmingItems.CHESTPLATE
- 3 -> FarmingItems.LEGGINGS
- else -> FarmingItems.BOOTS
- }
-
- armorFF = when (currentArmor) {
- 1 -> FFStats.helmetFF
- 2 -> FFStats.chestplateFF
- 3 -> FFStats.leggingsFF
- 4 -> FFStats.bootsFF
- else -> FFStats.armorTotalFF
- }
-
- var word = if (currentArmor == 0) "Armor" else "Piece"
-
- line = if (currentArmor == 0) "§7§2Total fortune from your armor\n§2Select a piece for more info"
- else "§7§2Total fortune from your\n${armorItem.getItem().displayName}"
- var value = if (FFStats.usingSpeedBoots) {
- when (currentArmor) {
- 0 -> 421
- 1 -> 101.67
- 2, 3 -> 106.67
- 4 -> 106
- else -> 0
- }
- } else {
- when (currentArmor) {
- 0 -> 425
- 1, 4 -> 103.75
- 2, 3 -> 108.75
- else -> 0
- }
- }
- GuiRenderUtils.drawFarmingBar(
- "§2Total $word Fortune", line, armorFF[FFTypes.TOTAL] ?: 0, value,
- FFGuideGUI.guiLeft + 135, FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
- )
+ footer.add(
+ FFInfos.PET_ITEM.bar(
+ "§2Pet Item", when (FFStats.currentPetItem) {
+ "GREEN_BANDANA" -> "§7§2The fortune from your pet's item\n§2Grants 4☘ per garden level"
+ "YELLOW_BANDANA" -> "§7§2The fortune from your pet's item"
+ "MINOS_RELIC" -> "§cGreen Bandana is better for fortune than minos relic!"
+ else -> "No fortune boosting pet item"
+ }
+ )
+ )
+
+ val wordEquip = if (FarmingItems.currentEquip == null) "Equipment" else "Piece"
- line = if (currentArmor == 0) "§7§2The base fortune from your armor\n§2Select a piece for more info"
- else "§7§2Base fortune from your\n${armorItem.getItem().displayName}"
- value = when (currentArmor) {
- 0 -> if (FFStats.usingSpeedBoots) 160 else 130
- 1 -> 30
- 2 -> 35
- 3 -> 35
- else -> if (FFStats.usingSpeedBoots) 60 else 30
- }
- GuiRenderUtils.drawFarmingBar(
- "§2Base $word Fortune", line, armorFF[FFTypes.BASE] ?: 0,
- value, FFGuideGUI.guiLeft + 135,
- FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
- )
+ val equipmentName = FarmingItems.currentEquip?.getItem()?.displayName ?: ""
- line = if (currentArmor == 0) "§7§2The fortune from your armor's ability\n§2Select a piece for more info"
- else "§7§2Ability fortune from your\n${armorItem.getItem().displayName}"
- value = if (FFStats.usingSpeedBoots) {
- when (currentArmor) {
- 0 -> 50
- 4 -> 0
- else -> 16.667
- }
- } else {
- when (currentArmor) {
- 0 -> 75
- else -> 18.75
- }
- }
-
- GuiRenderUtils.drawFarmingBar(
- "§2$word Ability", line, armorFF[FFTypes.ABILITY] ?: 0,
- value, FFGuideGUI.guiLeft + 135,
- FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 1,
+ FFInfos.TOTAL_EQUIP.bar(
+ "§2Total $wordEquip Fortune",
+ if (FarmingItems.currentEquip == null) "§7§2Total fortune from all your equipment\n§2Select a piece for more info"
+ else "§7§2Total fortune from your\n$equipmentName"
+ )
)
- line = if (currentArmor == 0) "§7§2The fortune from your armor's reforge\n§2Select a piece for more info"
- else "§7§2Total fortune from your\n${armorItem.getItem().displayName}"
- value = if (currentArmor == 0) {
- if (FFStats.usingSpeedBoots) 115 else 120
- } else if (currentArmor == 4) {
- if (FFStats.usingSpeedBoots) 25 else 30
- } else 30
- GuiRenderUtils.drawFarmingBar(
- "§2$word Reforge", line, armorFF[FFTypes.REFORGE] ?: 0,
- value, FFGuideGUI.guiLeft + 135,
- FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
- )
- var currentPet = FFStats.rabbitFF
- var petMaxFF = 60
- when (FFGuideGUI.currentPet) {
- FarmingItems.ELEPHANT -> {
- currentPet = FFStats.elephantFF
- petMaxFF = 210
- }
-
- FarmingItems.MOOSHROOM_COW -> {
- currentPet = FFStats.mooshroomFF
- petMaxFF = 217
- }
-
- FarmingItems.BEE -> {
- currentPet = FFStats.beeFF
- petMaxFF = 90
- }
-
- else -> {}
- }
-
- GuiRenderUtils.drawFarmingBar(
- "§2Total Pet Fortune", "§7§2The total fortune from your pet and its item",
- currentPet[FFTypes.TOTAL] ?: 0, petMaxFF, FFGuideGUI.guiLeft + 105,
- FFGuideGUI.guiTop + 155, 70, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 2,
+ FFInfos.BASE_EQUIP.bar(
+ "§2$wordEquip Base Fortune",
+ if (FarmingItems.currentEquip == null) "§7§2The base fortune from all your equipment\n§2Select a piece for more info"
+ else "§7§2Total base fortune from your\n$equipmentName"
+ )
)
- line = when (FFStats.currentPetItem) {
- "GREEN_BANDANA" -> "§7§2The fortune from your pet's item\n§2Grants 4☘ per garden level"
- "YELLOW_BANDANA" -> "§7§2The fortune from your pet's item"
- "MINOS_RELIC" -> "§cGreen Bandana is better for fortune than minos relic!"
- else -> "No fortune boosting pet item"
- }
- GuiRenderUtils.drawFarmingBar(
- "§2Pet Item", line, currentPet[FFTypes.PET_ITEM] ?: 0, 60, FFGuideGUI.guiLeft + 185,
- FFGuideGUI.guiTop + 155, 70, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 3,
+ FFInfos.ABILITY_EQUIP.bar(
+ "§2$wordEquip Ability",
+ if (FarmingItems.currentEquip == null) "§7§2The fortune from all of your equipment's abilities\n§2Select a piece for more info"
+ else "§7§2Total ability fortune from your\n$equipmentName"
+ )
)
- word = if (currentEquipment == 0) "Equipment" else "Piece"
-
- val equipmentItem = when (currentEquipment) {
- 1 -> FarmingItems.NECKLACE
- 2 -> FarmingItems.CLOAK
- 3 -> FarmingItems.BELT
- else -> FarmingItems.BRACELET
- }
-
- equipmentFF = when (currentEquipment) {
- 1 -> FFStats.necklaceFF
- 2 -> FFStats.cloakFF
- 3 -> FFStats.beltFF
- 4 -> FFStats.braceletFF
- else -> FFStats.equipmentTotalFF
- }
-
- val maxEquipmentBaseFortune = 5.0
- val maxEquipmentAbilityFortune = 15.0
- val maxEquipmentReforgeFortune = 15.0
- val maxGreenThumbFortune = GardenAPI.totalAmountVisitorsExisting.toDouble() / 4
-
- val maxFortunePerPiece =
- maxEquipmentBaseFortune + maxEquipmentAbilityFortune + maxEquipmentReforgeFortune + maxGreenThumbFortune
-
- line = if (currentEquipment == 0) "§7§2Total fortune from all your equipment\n§2Select a piece for more info"
- else "§7§2Total fortune from your\n${equipmentItem.getItem().displayName}"
- GuiRenderUtils.drawFarmingBar(
- "§2Total $word Fortune", line, equipmentFF[FFTypes.TOTAL] ?: 0,
- if (currentEquipment == 0) maxFortunePerPiece * 4 else maxFortunePerPiece,
-
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 30, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 4,
+ FFInfos.REFORGE_EQUIP.bar(
+ "§2$wordEquip Reforge",
+ if (FarmingItems.currentEquip == null) "§7§2The fortune from all of your equipment's reforges\n§2Select a piece for more info"
+ else "§7§2Total reforge fortune from your\n$equipmentName"
+ )
)
- line = if (currentEquipment == 0) "§7§2The base fortune from all your equipment\n§2Select a piece for more info"
- else "§7§2Total base fortune from your\n${equipmentItem.getItem().displayName}"
- GuiRenderUtils.drawFarmingBar(
- "§2$word Base Fortune", line, equipmentFF[FFTypes.BASE] ?: 0,
- if (currentEquipment == 0) maxEquipmentBaseFortune * 4 else maxEquipmentBaseFortune,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 55, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
- )
+ content.addTable(
+ 5,
+ Renderable.horizontalContainer(
+ FarmingItems.getPetsDisplay(true),
+ 4,
+ horizontalAlign = RenderUtils.HorizontalAlignment.CENTER,
+ verticalAlign = RenderUtils.VerticalAlignment.CENTER
+ )
+ )
+
+ content.addTable(
+ 5,
+ FFInfos.ENCHANT_EQUIP.bar(
+ "§2$wordEquip Enchantment",
+ if (FarmingItems.currentEquip == null) "§7§2The fortune from all of your equipment's enchantments\n§2Select a piece for more info"
+ else "§7§2Total enchantment fortune from your\n${FarmingItems.currentEquip!!.getItem().displayName}"
+ )
+ )
+
+ // Displays
- line =
- if (currentEquipment == 0) "§7§2The fortune from all of your equipment's abilities\n§2Select a piece for more info"
- else "§7§2Total ability fortune from your\n${equipmentItem.getItem().displayName}"
- GuiRenderUtils.drawFarmingBar(
- "§2$word Ability", line, equipmentFF[FFTypes.ABILITY] ?: 0,
- if (currentEquipment == 0) maxEquipmentAbilityFortune * 4 else maxEquipmentAbilityFortune,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 80, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 0,
+ Renderable.horizontalContainer(
+ FarmingItems.getArmorDisplay(true),
+ 4,
+ horizontalAlign = RenderUtils.HorizontalAlignment.CENTER,
+ verticalAlign = RenderUtils.VerticalAlignment.CENTER
+ )
)
-
- line =
- if (currentEquipment == 0) "§7§2The fortune from all of your equipment's reforges\n§2Select a piece for more info"
- else "§7§2Total reforge fortune from your\n${equipmentItem.getItem().displayName}"
- GuiRenderUtils.drawFarmingBar(
- "§2$word Reforge", line, equipmentFF[FFTypes.REFORGE] ?: 0,
- if (currentEquipment == 0) maxEquipmentReforgeFortune * 4 else maxEquipmentReforgeFortune,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 105, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
+ content.addTable(
+ 0,
+ Renderable.horizontalContainer(
+ FarmingItems.getEquipmentDisplay(true),
+ 4,
+ horizontalAlign = RenderUtils.HorizontalAlignment.CENTER,
+ verticalAlign = RenderUtils.VerticalAlignment.CENTER
+ )
)
- line =
- if (currentEquipment == 0) "§7§2The fortune from all of your equipment's enchantments\n§2Select a piece for more info"
- else "§7§2Total enchantment fortune from your\n${equipmentItem.getItem().displayName}"
- GuiRenderUtils.drawFarmingBar(
- "§2$word Enchantment", line, equipmentFF[FFTypes.GREEN_THUMB] ?: 0,
- if (currentEquipment == 0) maxGreenThumbFortune * 4 else maxGreenThumbFortune,
- FFGuideGUI.guiLeft + 255, FFGuideGUI.guiTop + 130, 90, mouseX, mouseY, FFGuideGUI.tooltipToDisplay
- )
+
+ return content to footer
}
private fun FFTypes.notSaved(): Boolean = FFStats.baseFF[this]?.let {
it < 0.0
} ?: true
}
+
+private fun MutableList<MutableList<Renderable>>.addTable(row: Int, r: Renderable) {
+ this.getOrNull(row)?.add(r) ?: mutableListOf(r).let { this.add(row, it) }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt
index e8134a337..2323b5e30 100644
--- a/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt
+++ b/src/main/java/at/hannibal2/skyhanni/features/garden/fortuneguide/pages/UpgradePage.kt
@@ -1,126 +1,103 @@
package at.hannibal2.skyhanni.features.garden.fortuneguide.pages
-import at.hannibal2.skyhanni.features.garden.fortuneguide.FFGuideGUI
+import at.hannibal2.skyhanni.features.garden.CropType
+import at.hannibal2.skyhanni.features.garden.fortuneguide.FarmingItems
+import at.hannibal2.skyhanni.features.garden.fortuneguide.FortuneUpgrade
import at.hannibal2.skyhanni.features.garden.fortuneguide.FortuneUpgrades
-import at.hannibal2.skyhanni.features.inventory.bazaar.BazaarApi
-import at.hannibal2.skyhanni.utils.GuiRenderUtils
import at.hannibal2.skyhanni.utils.ItemUtils.itemName
-import at.hannibal2.skyhanni.utils.NEUInternalName.Companion.asInternalName
import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
import at.hannibal2.skyhanni.utils.NumberUtil
-import net.minecraft.client.renderer.GlStateManager
-import net.minecraft.util.MathHelper
+import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment
+import at.hannibal2.skyhanni.utils.RenderUtils.VerticalAlignment
+import at.hannibal2.skyhanni.utils.guide.GuideScrollPage
+import at.hannibal2.skyhanni.utils.renderables.Renderable
import java.text.DecimalFormat
-class UpgradePage : FFGuideGUI.FFGuidePage() {
+class UpgradePage(val crop0: () -> CropType?, sizeX: Int, sizeY: Int, paddingX: Int = 15, paddingY: Int = 7) :
+ GuideScrollPage(
+ sizeX,
+ sizeY,
+ paddingX,
+ paddingY,
+ marginY = 10,
+ hasHeader = true,
+ ) {
- private var pageScroll = 0
- private var scrollVelocity = 0.0
- private val maxNoInputFrames = 100
- private var listLength = 0
+ val crop get() = crop0()
- override fun drawPage(mouseX: Int, mouseY: Int, partialTicks: Float) {
- val adjustedY = FFGuideGUI.guiTop + 20 + pageScroll
- val inverseScale = 1 / 0.75f
+ override fun onEnter() {
+ crop?.let {
+ FortuneUpgrades.getCropSpecific(it.farmingItem.getItemOrNull())
+ } ?: {
+ FortuneUpgrades.getCropSpecific(null) // TODO
+ }
- // TODO fix duplicate drawString lines, add guiLeft, guiTop and inverseScale
- GlStateManager.scale(0.75f, 0.75f, 1f)
- GuiRenderUtils.drawString(
- "Upgrade",
- (FFGuideGUI.guiLeft + 45) * inverseScale,
- (FFGuideGUI.guiTop + 5) * inverseScale
- )
- GuiRenderUtils.drawString(
- "Item",
- (FFGuideGUI.guiLeft + 190) * inverseScale,
- (FFGuideGUI.guiTop + 5) * inverseScale
- )
- GuiRenderUtils.drawString(
- "FF increase",
- (FFGuideGUI.guiLeft + 240) * inverseScale,
- (FFGuideGUI.guiTop + 5) * inverseScale
- )
- GuiRenderUtils.drawString(
- "Cost/FF",
- (FFGuideGUI.guiLeft + 290) * inverseScale,
- (FFGuideGUI.guiTop + 5) * inverseScale
+ FarmingItems.resetClickState()
+ update(
+ content = buildList {
+ add(header())
+ val upgradeList = if (crop == null)
+ FortuneUpgrades.genericUpgrades
+ else
+ FortuneUpgrades.cropSpecificUpgrades
+ addAll(upgradeList.map { upgrade -> upgrade.print() })
+ }
)
- GuiRenderUtils.drawString(
- "Total",
- (FFGuideGUI.guiLeft + 330) * inverseScale,
- (FFGuideGUI.guiTop + 5) * inverseScale
+ }
+
+ private fun header() = listOf("Upgrade", "", "Item", "FF", "Cost/FF", "Total").map {
+ Renderable.string(
+ it,
+ 0.9,
+ horizontalAlign = HorizontalAlignment.CENTER
)
+ }
- val upgradeList =
- if (FFGuideGUI.currentCrop == null) FortuneUpgrades.genericUpgrades else FortuneUpgrades.cropSpecificUpgrades
- listLength = upgradeList.size
- for ((index, upgrade) in upgradeList.withIndex()) {
- if (adjustedY + 25 * index < FFGuideGUI.guiTop + 20) continue
- if (adjustedY + 25 * index > FFGuideGUI.guiTop + 160) continue
- val upgradeItem = upgrade.requiredItem.asInternalName().getItemStack()
- var formattedUpgrade = upgradeItem.itemName
- if (adjustedY + 25 * index - 5 < FFGuideGUI.lastClickedHeight && FFGuideGUI.lastClickedHeight < adjustedY + 25 * index + 10) {
- FFGuideGUI.lastClickedHeight = 0
- BazaarApi.searchForBazaarItem(formattedUpgrade, upgrade.itemQuantity)
- }
- if (upgrade.itemQuantity != 1) {
- formattedUpgrade = "$formattedUpgrade §fx${upgrade.itemQuantity}"
- }
- GuiRenderUtils.drawTwoLineString(
- upgrade.description,
- (FFGuideGUI.guiLeft + 15) * inverseScale,
- (adjustedY + 25 * index) * inverseScale
+ private fun FortuneUpgrade.print() = buildList {
+ add(
+ Renderable.wrappedString(
+ description,
+ 136,
+ 0.75,
+ verticalAlign = VerticalAlignment.CENTER
)
- GuiRenderUtils.renderItemAndTip(
- FFGuideGUI.tooltipToDisplay,
- upgradeItem,
- (FFGuideGUI.guiLeft + 155) * inverseScale,
- (adjustedY + 25 * index - 5) * inverseScale,
- mouseX * inverseScale,
- mouseY * inverseScale,
- 0x00FFFFFF
+ )
+ add(
+ Renderable.itemStackWithTip(
+ requiredItem.getItemStack(),
+ 8.0 / 9.0,
+ verticalAlign = VerticalAlignment.CENTER
)
- GuiRenderUtils.drawString(
- formattedUpgrade,
- (FFGuideGUI.guiLeft + 180) * inverseScale,
- (adjustedY + 25 * index) * inverseScale
+ )
+ add(
+ Renderable.wrappedString(
+ requiredItem.itemName.let { if (itemQuantity == 1) it else "$it §fx$itemQuantity" }, // TODO wtf
+ 70,
+ 0.75,
+ verticalAlign = VerticalAlignment.CENTER
)
- GuiRenderUtils.drawString(
- "§a${DecimalFormat("0.##").format(upgrade.fortuneIncrease)}",
- (FFGuideGUI.guiLeft + 270) * inverseScale,
- (adjustedY + 25 * index) * inverseScale
+ )
+ add(
+ Renderable.string(
+ "§a${DecimalFormat("0.##").format(fortuneIncrease)}",
+ horizontalAlign = HorizontalAlignment.CENTER,
+ verticalAlign = VerticalAlignment.CENTER
)
- GuiRenderUtils.drawString(
- "§6" + upgrade.costPerFF?.let { NumberUtil.format(it) },
- (FFGuideGUI.guiLeft + 300) * inverseScale,
- (adjustedY + 25 * index) * inverseScale
+ ) // TODO cleaner formating
+ add(
+ Renderable.string(
+ "§6" + costPerFF?.let { NumberUtil.format(it) },
+ horizontalAlign = HorizontalAlignment.CENTER,
+ verticalAlign = VerticalAlignment.CENTER
)
- GuiRenderUtils.drawString(
- ("§6" + upgrade.cost?.let { NumberUtil.format(it) }),
- (FFGuideGUI.guiLeft + 335) * inverseScale,
- (adjustedY + 25 * index) * inverseScale
+ )
+ add(
+ Renderable.string(
+ "§6" + cost?.let { NumberUtil.format(it) },
+ horizontalAlign = HorizontalAlignment.CENTER,
+ verticalAlign = VerticalAlignment.CENTER
)
- }
- GlStateManager.scale(inverseScale, inverseScale, 1f)
- scrollScreen()
- }
-
- private fun scrollScreen() {
- scrollVelocity += FFGuideGUI.lastMouseScroll / 48.0
- scrollVelocity *= 0.95
- pageScroll += scrollVelocity.toInt() + FFGuideGUI.lastMouseScroll / 24
-
- FFGuideGUI.noMouseScrollFrames++
-
- if (FFGuideGUI.noMouseScrollFrames >= maxNoInputFrames) {
- scrollVelocity *= 0.75
- }
-
- if (pageScroll > 0) {
- pageScroll = 0
- }
-
- pageScroll = MathHelper.clamp_int(pageScroll, -(listLength * 15 - 15), 0)
- FFGuideGUI.lastMouseScroll = 0
+ )
}
}
+
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
index 2e1237fe8..48cf1ccb2 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/CollectionUtils.kt
@@ -2,11 +2,13 @@ package at.hannibal2.skyhanni.utils
import at.hannibal2.skyhanni.utils.NEUItems.getItemStack
import at.hannibal2.skyhanni.utils.renderables.Renderable
+import at.hannibal2.skyhanni.utils.renderables.RenderableUtils
import net.minecraft.enchantment.Enchantment
import net.minecraft.item.ItemStack
import java.util.Collections
import java.util.Queue
import java.util.WeakHashMap
+import kotlin.math.ceil
object CollectionUtils {
@@ -279,6 +281,38 @@ object CollectionUtils {
}))
}
+ fun Collection<Collection<Renderable>>.tableStretchXPadding(xSpace: Int): Int {
+ if (this.isEmpty()) return xSpace
+ val off = RenderableUtils.calculateTableXOffsets(this as List<List<Renderable?>>, 0)
+ val xLength = off.size - 1
+ val emptySpace = xSpace - off.last()
+ if (emptySpace < 0) {
+ // throw IllegalArgumentException("Not enough space for content")
+ }
+ return emptySpace / (xLength - 1)
+ }
+
+ fun Collection<Collection<Renderable>>.tableStretchYPadding(ySpace: Int): Int {
+ if (this.isEmpty()) return ySpace
+ val off = RenderableUtils.calculateTableYOffsets(this as List<List<Renderable?>>, 0)
+ val yLength = off.size - 1
+ val emptySpace = ySpace - off.last()
+ if (emptySpace < 0) {
+ // throw IllegalArgumentException("Not enough space for content")
+ }
+ return emptySpace / (yLength - 1)
+ }
+
+ /** Splits the input into equal sized lists. If the list can't get divided clean by [subs] then the last entry gets reduced. e.g. 13/4 = [4,4,4,1]*/
+ fun <T> Collection<T>.split(subs: Int = 2): List<List<T>> {
+ if (this.isEmpty()) return listOf(emptyList())
+ val list = this.chunked(ceil(this.size.toDouble() / subs.toDouble()).toInt()).toMutableList()
+ while (list.size < subs) {
+ list.add(emptyList())
+ }
+ return list
+ }
+
inline fun <K, V, R : Any> Map<K, V>.mapKeysNotNull(transform: (Map.Entry<K, V>) -> R?): Map<R, V> {
val destination = LinkedHashMap<R, V>()
for (element in this) {
@@ -290,6 +324,15 @@ object CollectionUtils {
return destination
}
+ inline fun <T, C : Number, D : Number> Iterable<T>.sumOfPair(selector: (T) -> Pair<C, D>): Pair<Double, Double> {
+ var sum = Pair(0.0, 0.0)
+ for (element in this) {
+ val add = selector(element)
+ sum = sum.first + add.first.toDouble() to sum.second + add.second.toDouble()
+ }
+ return sum
+ }
+
inline fun <T, R> Iterable<T>.zipWithNext3(transform: (a: T, b: T, c: T) -> R): List<R> {
val iterator = iterator()
if (!iterator.hasNext()) return emptyList()
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
index e68af00ca..403484fcd 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/GuiRenderUtils.kt
@@ -3,6 +3,10 @@ package at.hannibal2.skyhanni.utils
import at.hannibal2.skyhanni.config.features.skillprogress.SkillProgressBarConfig
import at.hannibal2.skyhanni.features.chroma.ChromaShaderManager
import at.hannibal2.skyhanni.features.chroma.ChromaType
+import at.hannibal2.skyhanni.utils.LorenzUtils.round
+import at.hannibal2.skyhanni.utils.NumberUtil.fractionOf
+import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment
+import at.hannibal2.skyhanni.utils.renderables.Renderable
import io.github.moulberry.notenoughupdates.util.Utils
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.FontRenderer
@@ -17,11 +21,11 @@ import java.awt.Color
import java.text.DecimalFormat
import kotlin.math.ceil
import kotlin.math.min
-import kotlin.math.roundToInt
/**
* Some functions taken from NotEnoughUpdates
*/
+// TODO cleanup of redundant functions
object GuiRenderUtils {
fun drawStringCentered(str: String?, fr: FontRenderer, x: Float, y: Float, shadow: Boolean, colour: Int) {
@@ -71,12 +75,7 @@ object GuiRenderUtils {
fun drawStringCentered(str: String?, x: Int, y: Int) {
drawStringCentered(
- str,
- Minecraft.getMinecraft().fontRendererObj,
- x.toFloat(),
- y.toFloat(),
- true,
- 0xffffff
+ str, Minecraft.getMinecraft().fontRendererObj, x.toFloat(), y.toFloat(), true, 0xffffff
)
}
@@ -126,30 +125,33 @@ object GuiRenderUtils {
if (tooltipY + tooltipHeight + 6 > screenHeight) tooltipY = screenHeight - tooltipHeight - 6
// main background
GuiScreen.drawRect(
- tooltipX - 3, tooltipY - 3,
- tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, -0xfeffff0
+ tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, -0xfeffff0
)
// borders
GuiScreen.drawRect(
- tooltipX - 3, tooltipY - 3 + 1,
- tooltipX - 3 + 1, tooltipY + tooltipHeight + 3 - 1, borderColor
+ tooltipX - 3, tooltipY - 3 + 1, tooltipX - 3 + 1, tooltipY + tooltipHeight + 3 - 1, borderColor
)
GuiScreen.drawRect(
- tooltipX + tooltipTextWidth + 2, tooltipY - 3 + 1,
- tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3 - 1, borderColor
+ tooltipX + tooltipTextWidth + 2,
+ tooltipY - 3 + 1,
+ tooltipX + tooltipTextWidth + 3,
+ tooltipY + tooltipHeight + 3 - 1,
+ borderColor
)
GuiScreen.drawRect(
- tooltipX - 3, tooltipY - 3,
- tooltipX + tooltipTextWidth + 3, tooltipY - 3 + 1, borderColor
+ tooltipX - 3, tooltipY - 3, tooltipX + tooltipTextWidth + 3, tooltipY - 3 + 1, borderColor
)
GuiScreen.drawRect(
- tooltipX - 3, tooltipY + tooltipHeight + 2,
- tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, borderColor
+ tooltipX - 3,
+ tooltipY + tooltipHeight + 2,
+ tooltipX + tooltipTextWidth + 3,
+ tooltipY + tooltipHeight + 3,
+ borderColor
)
GlStateManager.translate(0f, 0f, -100f)
GlStateManager.disableDepth()
@@ -175,109 +177,38 @@ object GuiRenderUtils {
fun isPointInRect(x: Int, y: Int, left: Int, top: Int, width: Int, height: Int) =
left <= x && x < left + width && top <= y && y < top + height
- fun drawProgressBar(x: Int, y: Int, barWidth: Int, progress: Float) {
- GuiScreen.drawRect(x, y, x + barWidth, y + 6, 0xFF43464B.toInt())
- val width = barWidth * progress
- GuiScreen.drawRect(x + 1, y + 1, (x + width).toInt() + 1, y + 5, 0xFF00FF00.toInt())
- if (progress != 1f) GuiScreen.drawRect(
- (x + width).toInt() + 1,
- y + 1,
- x + barWidth - 1,
- y + 5,
- 0xFF013220.toInt()
- )
- }
-
- fun renderItemAndTip(
- list: MutableList<String>,
- item: ItemStack?,
- x: Int,
- y: Int,
- mouseX: Int,
- mouseY: Int,
- color: Int = 0xFF43464B.toInt(),
- ) {
- GuiScreen.drawRect(x, y, x + 16, y + 16, color)
- if (item != null) {
- renderItemStack(item, x, y)
- if (isPointInRect(mouseX, mouseY, x, y, 16, 16)) {
- val tt: List<String> = item.getTooltip(Minecraft.getMinecraft().thePlayer, false)
- list.addAll(tt)
- }
- }
- }
-
- fun renderItemAndTip(
- list: MutableList<String>,
- item: ItemStack?,
- x: Float,
- y: Float,
- mouseX: Float,
- mouseY: Float,
- color: Int = 0xFF43464B.toInt(),
- ) {
- renderItemAndTip(list, item, x.toInt(), y.toInt(), mouseX.toInt(), mouseY.toInt(), color)
- }
-
- // assuming 70% font size
- fun drawFarmingBar(
+ fun getFarmingBar(
label: String,
tooltip: String,
currentValue: Number,
maxValue: Number,
- xPos: Int,
- yPos: Int,
width: Int,
- mouseX: Int,
- mouseY: Int,
- output: MutableList<String>,
textScale: Float = .7f,
- ) {
- var currentVal = currentValue.toDouble()
- currentVal = if (currentVal < 0) 0.0 else currentVal
-
- var barProgress = currentVal / maxValue.toFloat()
- if (maxValue == 0) barProgress = 1.0
- barProgress = when {
- barProgress > 1 -> 1.0
- barProgress < 0 -> 0.0
- else -> barProgress
- }
-
- val filledWidth = (width * barProgress).toInt()
- val current = DecimalFormat("0.##").format(currentVal)
- val progressPercentage = (barProgress * 10000).roundToInt() / 100
- val inverseScale = 1 / textScale
- val textWidth: Int = Minecraft.getMinecraft().fontRendererObj.getStringWidth("$progressPercentage%")
- val barColor = barColorGradient(barProgress)
-
- GlStateManager.scale(textScale, textScale, 1f)
- drawString(label, xPos * inverseScale, yPos * inverseScale)
- drawString(
- "§2$current / ${DecimalFormat("0.##").format(maxValue)}☘",
- xPos * inverseScale,
- (yPos + 8) * inverseScale
- )
- drawString(
- "§2$progressPercentage%",
- (xPos + width - textWidth * textScale) * inverseScale,
- (yPos + 8) * inverseScale
- )
- GlStateManager.scale(inverseScale, inverseScale, 1f)
-
- GuiScreen.drawRect(xPos, yPos + 16, xPos + width, yPos + 20, 0xFF43464B.toInt())
- GuiScreen.drawRect(xPos + 1, yPos + 17, xPos + width - 1, yPos + 19, barColor.darkenColor())
- GuiScreen.drawRect(
- xPos + 1, yPos + 17,
- if (filledWidth < 2) xPos + 1 else xPos + filledWidth - 1, yPos + 19, barColor
- )
-
- if (tooltip != "" && isPointInRect(mouseX, mouseY, xPos - 2, yPos - 2, width + 4, 20 + 4)) {
- val split = tooltip.split("\n")
- for (line in split) {
- output.add(line)
- }
- }
+ ): Renderable {
+ val current = currentValue.toDouble().coerceAtLeast(0.0)
+ val percent = current.fractionOf(maxValue)
+ val scale = textScale.toDouble()
+ return Renderable.hoverTips(Renderable.verticalContainer(
+ listOf(
+ Renderable.string(label, scale = scale),
+ Renderable.fixedSizeLine(
+ listOf(
+ Renderable.string(
+ "§2${DecimalFormat("0.##").format(current)} / ${
+ DecimalFormat(
+ "0.##"
+ ).format(maxValue)
+ }☘", scale = scale, horizontalAlign = HorizontalAlignment.LEFT
+ ),
+ Renderable.string(
+ "§2${(percent * 100).round(1)}%",
+ scale = scale,
+ horizontalAlign = HorizontalAlignment.RIGHT
+ ),
+ ), width
+ ), Renderable.progressBar(percent, width = width)
+ )
+ ), tooltip.split('\n').map { Renderable.string(it) })
}
private fun barColorGradient(double: Double): Int {
@@ -293,8 +224,11 @@ object GuiRenderUtils {
fun drawScaledRec(left: Int, top: Int, right: Int, bottom: Int, colour: Int, inverseScale: Float) {
GuiScreen.drawRect(
- (left * inverseScale).toInt(), (top * inverseScale).toInt(),
- (right * inverseScale).toInt(), (bottom * inverseScale).toInt(), colour
+ (left * inverseScale).toInt(),
+ (top * inverseScale).toInt(),
+ (right * inverseScale).toInt(),
+ (bottom * inverseScale).toInt(),
+ colour
)
}
@@ -339,15 +273,7 @@ object GuiRenderUtils {
Utils.drawTexturedRect(x, y, w_2.toFloat(), height, 0f, w_2 / xSize, vMinEmpty, vMaxEmpty, GL11.GL_NEAREST)
Utils.drawTexturedRect(
- x + w_2,
- y,
- w_2.toFloat(),
- height,
- 1 - w_2 / xSize,
- 1f,
- vMinEmpty,
- vMaxEmpty,
- GL11.GL_NEAREST
+ x + w_2, y, w_2.toFloat(), height, 1 - w_2 / xSize, 1f, vMinEmpty, vMaxEmpty, GL11.GL_NEAREST
)
if (useChroma) {
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
index 297a40585..cd75e9cf4 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/NEUItems.kt
@@ -217,9 +217,14 @@ object NEUItems {
const val itemFontSize = 2.0 / 3.0
- fun ItemStack.renderOnScreen(x: Float, y: Float, scaleMultiplier: Double = itemFontSize) {
+ fun ItemStack.renderOnScreen(
+ x: Float,
+ y: Float,
+ scaleMultiplier: Double = itemFontSize,
+ rescaleSkulls: Boolean = true
+ ) {
val item = checkBlinkItem()
- val isSkull = item.item === Items.skull
+ val isSkull = rescaleSkulls && item.item === Items.skull
val baseScale = (if (isSkull) 4f / 3f else 1f)
val finalScale = baseScale * scaleMultiplier
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideGUI.kt b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideGUI.kt
new file mode 100644
index 000000000..944a3201a
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideGUI.kt
@@ -0,0 +1,121 @@
+package at.hannibal2.skyhanni.utils.guide
+
+import at.hannibal2.skyhanni.test.command.ErrorManager
+import at.hannibal2.skyhanni.utils.RenderUtils
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXYAligned
+import net.minecraft.client.gui.GuiScreen
+import net.minecraft.client.renderer.GlStateManager
+import net.minecraft.item.ItemStack
+
+const val selectedColor = 0x50000000
+const val notSelectedColor = 0x50303030
+const val tabSpacing = 5
+const val tabShortSide = 25
+const val tabLongSide = 28
+
+abstract class GuideGUI<pageEnum : Enum<*>>(defaultScreen: pageEnum) : GuiScreen() {
+
+ abstract val sizeX: Int
+ abstract val sizeY: Int
+ lateinit var pageList: Map<pageEnum, GuidePage>
+ lateinit var horizontalTabs: List<GuideTab>
+ lateinit var verticalTabs: List<GuideTab>
+ protected var currentPage: pageEnum = defaultScreen
+ set(value) {
+ pageList[field]?.onLeave()
+ pageList[value]?.onEnter()
+ field = value
+ }
+
+ val lastVerticalTabWrapper = object : tabWrapper {
+ override var tab: GuideTab? = null
+ }
+ val lastHorizontalTabWrapper = object : tabWrapper {
+ override var tab: GuideTab? = null
+ }
+
+ fun hTab(item: ItemStack, tip: Renderable, onClick: (GuideTab) -> Unit) =
+ GuideTab(item, tip, false, lastHorizontalTabWrapper, onClick)
+
+ fun vTab(item: ItemStack, tip: Renderable, onClick: (GuideTab) -> Unit) =
+ GuideTab(item, tip, true, lastVerticalTabWrapper, onClick)
+
+ interface tabWrapper {
+ var tab: GuideTab?
+ }
+
+ fun refreshPage() {
+ pageList[currentPage]?.refresh()
+ }
+
+ private fun renderHorizontalTabs() {
+ var offset = Pair(tabSpacing.toFloat() * 3f, -tabLongSide.toFloat())
+ GlStateManager.translate(offset.first, offset.second, 0f)
+ for (tab in horizontalTabs) {
+ tab.render(offset.first.toInt(), offset.second.toInt())
+ val xShift = (tabShortSide + tabSpacing).toFloat()
+ offset = offset.first + xShift to offset.second
+ GlStateManager.translate(xShift, 0f, 0f)
+ }
+ GlStateManager.translate(-offset.first, -offset.second, 0f)
+ }
+
+ private fun renderVerticalTabs() {
+ var offset = Pair(-tabLongSide.toFloat(), tabSpacing.toFloat() * 3f)
+ GlStateManager.translate(offset.first, offset.second, 0f)
+ for (tab in verticalTabs) {
+ tab.render(offset.first.toInt(), offset.second.toInt())
+ val yShift = (tabShortSide + tabSpacing).toFloat()
+ offset = offset.first to offset.second + yShift
+ GlStateManager.translate(0f, yShift, 0f)
+ }
+ GlStateManager.translate(-offset.first, -offset.second, 0f)
+ }
+
+ override fun drawScreen(mouseX: Int, mouseY: Int, partialTicks: Float) = try {
+ super.drawScreen(mouseX, mouseY, partialTicks)
+ drawDefaultBackground()
+ val guiLeft = (width - sizeX) / 2
+ val guiTop = (height - sizeY) / 2
+
+ /*
+ val mouseX = Mouse.getX() * width / Minecraft.getMinecraft().displayWidth
+ val mouseY = height - Mouse.getY() * height / Minecraft.getMinecraft().displayHeight - 1
+ */
+
+ val relativeMouseX = mouseX - guiLeft
+ val relativeMouseY = mouseY - guiTop
+
+ GlStateManager.pushMatrix()
+ GlStateManager.translate(guiLeft.toFloat(), guiTop.toFloat(), 0f)
+ drawRect(0, 0, sizeX, sizeY, 0x50000000)
+
+ Renderable.withMousePosition(relativeMouseX, relativeMouseY) {
+ renderHorizontalTabs()
+ renderVerticalTabs()
+
+ Renderable.string(
+ "§7SkyHanni ",
+ horizontalAlign = RenderUtils.HorizontalAlignment.RIGHT,
+ verticalAlign = RenderUtils.VerticalAlignment.BOTTOM
+ ).renderXYAligned(0, 0, sizeX, sizeY)
+
+ val page = pageList[currentPage]
+ page?.drawPage(relativeMouseX, relativeMouseY)
+
+ GlStateManager.translate(-guiLeft.toFloat(), -guiTop.toFloat(), 0f)
+ }
+
+ GlStateManager.popMatrix()
+
+ } catch (e: Exception) {
+ GlStateManager.popMatrix()
+ ErrorManager.logErrorWithData(
+ e, "Something broke in GuideGUI",
+ "Guide" to this.javaClass.typeName,
+ "Page" to currentPage.name
+ )
+ }
+}
+
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/guide/GuidePage.kt b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuidePage.kt
new file mode 100644
index 000000000..a563a531c
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuidePage.kt
@@ -0,0 +1,15 @@
+package at.hannibal2.skyhanni.utils.guide
+
+abstract class GuidePage {
+ abstract fun drawPage(mouseX: Int, mouseY: Int)
+
+ abstract fun onEnter()
+
+ abstract fun onLeave()
+
+ fun refresh() {
+ onLeave()
+ onEnter()
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideRenderablePage.kt b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideRenderablePage.kt
new file mode 100644
index 000000000..ce68a4afe
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideRenderablePage.kt
@@ -0,0 +1,23 @@
+package at.hannibal2.skyhanni.utils.guide
+
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import net.minecraft.client.renderer.GlStateManager
+
+abstract class GuideRenderablePage(
+ val paddingX: Int = 0,
+ val paddingY: Int = 0
+) : GuidePage() {
+
+ protected var renderable: Renderable? = null
+
+ final override fun drawPage(mouseX: Int, mouseY: Int) {
+ GlStateManager.translate(paddingX.toFloat(), paddingY.toFloat(), 0f)
+ renderable?.render(paddingX, paddingY)
+ GlStateManager.translate(-paddingX.toFloat(), -paddingY.toFloat(), 0f)
+ }
+
+ override fun onLeave() {
+ renderable = null
+ }
+
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideScrollPage.kt b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideScrollPage.kt
new file mode 100644
index 000000000..97cf68442
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideScrollPage.kt
@@ -0,0 +1,31 @@
+package at.hannibal2.skyhanni.utils.guide
+
+import at.hannibal2.skyhanni.utils.CollectionUtils.tableStretchXPadding
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import at.hannibal2.skyhanni.utils.renderables.ScrollValue
+
+abstract class GuideScrollPage(
+ val sizeX: Int,
+ val sizeY: Int,
+ paddingX: Int = 0,
+ paddingY: Int = 0,
+ val marginY: Int = 5,
+ val velocity: Double = 3.0,
+ val hasHeader: Boolean = true,
+) : GuideRenderablePage(paddingX, paddingY) {
+
+ private val scroll = ScrollValue()
+
+ fun update(content: List<List<Renderable>>) {
+ renderable = Renderable.scrollTable(
+ content = content,
+ height = sizeY - paddingY * 2,
+ scrollValue = scroll,
+ velocity = velocity,
+ xPadding = content.tableStretchXPadding(sizeX - paddingX * 2),
+ yPadding = marginY,
+ hasHeader = hasHeader,
+ button = 0
+ )
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideTab.kt b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideTab.kt
new file mode 100644
index 000000000..acc69c8cc
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideTab.kt
@@ -0,0 +1,67 @@
+package at.hannibal2.skyhanni.utils.guide
+
+import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment
+import at.hannibal2.skyhanni.utils.RenderUtils.VerticalAlignment
+import at.hannibal2.skyhanni.utils.SoundUtils
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXYAligned
+import net.minecraft.client.gui.Gui
+import net.minecraft.item.ItemStack
+
+class GuideTab(
+ val item: ItemStack,
+ val tip: Renderable,
+ val isVertical: Boolean = false,
+ var lastTab: GuideGUI.tabWrapper,
+ val onClick: (GuideTab) -> Unit
+) {
+
+ fun fakeClick() = click()
+
+ private fun click() {
+ onClick.invoke(this)
+ this.select()
+ if (lastTab.tab != this) {
+ lastTab.tab?.unSelect()
+ lastTab.tab = this
+ }
+ }
+
+ fun select() {
+ selectColor = selectedColor
+ }
+
+ fun unSelect() {
+ selectColor = notSelectedColor
+ }
+
+ fun isSelected() = selectColor == selectedColor
+
+ val width = if (isVertical) tabLongSide else tabShortSide
+ val height = if (isVertical) tabShortSide else tabLongSide
+
+ private var selectColor = notSelectedColor
+
+ private val renderable = Renderable.clickAndHover(object : Renderable {
+ override val width = this@GuideTab.width
+ override val height = this@GuideTab.height
+ override val horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT
+ override val verticalAlign: VerticalAlignment = VerticalAlignment.TOP
+
+ val itemRender = Renderable.itemStack(
+ item, 1.0, horizontalAlign = HorizontalAlignment.CENTER, verticalAlign = VerticalAlignment.CENTER
+ )
+
+ override fun render(posX: Int, posY: Int) {
+ Gui.drawRect(0, 0, width, height, selectColor)
+ itemRender.renderXYAligned(posX, posY, width, height)
+ }
+ }, listOf(tip), onClick = {
+ click()
+ SoundUtils.playClickSound()
+ })
+
+ fun render(posX: Int, posY: Int) {
+ renderable.render(posX, posY)
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideTablePage.kt b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideTablePage.kt
new file mode 100644
index 000000000..85dd5bdda
--- /dev/null
+++ b/src/main/java/at/hannibal2/skyhanni/utils/guide/GuideTablePage.kt
@@ -0,0 +1,33 @@
+package at.hannibal2.skyhanni.utils.guide
+
+import at.hannibal2.skyhanni.utils.CollectionUtils.tableStretchXPadding
+import at.hannibal2.skyhanni.utils.CollectionUtils.tableStretchYPadding
+import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment
+import at.hannibal2.skyhanni.utils.renderables.Renderable
+
+abstract class GuideTablePage(
+ val sizeX: Int,
+ val sizeY: Int,
+ paddingX: Int = 0,
+ paddingY: Int = 0,
+ val footerSpacing: Int = 2
+) : GuideRenderablePage(paddingX, paddingY) {
+
+ fun update(
+ content: List<List<Renderable>>,
+ footer: List<Renderable> = emptyList()
+ ) {
+ val ySpace = (content + listOf(footer)).tableStretchYPadding(sizeY - paddingY * 2)
+ renderable =
+ Renderable.verticalContainer(
+ listOf(
+ Renderable.table(
+ content,
+ xPadding = content.tableStretchXPadding(sizeX - paddingX * 2),
+ yPadding = ySpace
+ ),
+ Renderable.horizontalContainer(footer, footerSpacing, horizontalAlign = HorizontalAlignment.CENTER)
+ ), spacing = ySpace
+ )
+ }
+}
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
index 88b291844..070d7db10 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/Renderable.kt
@@ -19,6 +19,7 @@ import at.hannibal2.skyhanni.utils.NEUItems.renderOnScreen
import at.hannibal2.skyhanni.utils.RenderUtils
import at.hannibal2.skyhanni.utils.RenderUtils.HorizontalAlignment
import at.hannibal2.skyhanni.utils.RenderUtils.VerticalAlignment
+import at.hannibal2.skyhanni.utils.guide.GuideGUI
import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.calculateTableXOffsets
import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.calculateTableYOffsets
import at.hannibal2.skyhanni.utils.renderables.RenderableUtils.renderXAligned
@@ -230,18 +231,20 @@ interface Renderable {
}
private fun shouldAllowLink(debug: Boolean = false, bypassChecks: Boolean): Boolean {
- val isGuiScreen = Minecraft.getMinecraft().currentScreen != null
+ val guiScreen = Minecraft.getMinecraft().currentScreen
+
+ val isGuiScreen = guiScreen != null
if (bypassChecks) {
return isGuiScreen
}
val inMenu = Minecraft.getMinecraft().currentScreen !is GuiIngameMenu
- val isGuiPositionEditor = Minecraft.getMinecraft().currentScreen !is GuiPositionEditor
- val isNotInSignAndOnSlot = if (Minecraft.getMinecraft().currentScreen !is GuiEditSign) {
+ val isGuiPositionEditor = guiScreen !is GuiPositionEditor
+ val isNotInSignAndOnSlot = if (guiScreen !is GuiEditSign && guiScreen !is GuideGUI<*>) {
ToolTipData.lastSlot == null || GuiData.preDrawEventCanceled
} else true
- val isConfigScreen = Minecraft.getMinecraft().currentScreen !is GuiScreenElementWrapper
+ val isConfigScreen = guiScreen !is GuiScreenElementWrapper
- val openGui = Minecraft.getMinecraft().currentScreen?.javaClass?.name ?: "none"
+ val openGui = guiScreen?.javaClass?.name ?: "none"
val isInNeuPv = openGui == "io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer"
val neuFocus = NEUItems.neuHasFocus()
val isInSkyTilsPv = openGui == "gg.skytils.skytilsmod.gui.profile.ProfileGui"
@@ -313,20 +316,45 @@ interface Renderable {
}
}
+ fun itemStackWithTip(
+ item: ItemStack,
+ scale: Double = NEUItems.itemFontSize,
+ xSpacing: Int = 2,
+ ySpacing: Int = 0,
+ rescaleSkulls: Boolean = true,
+ horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
+ verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
+ ) =
+ hoverTips(
+ itemStack(
+ item,
+ scale,
+ xSpacing,
+ ySpacing,
+ rescaleSkulls,
+ horizontalAlign = horizontalAlign,
+ verticalAlign = verticalAlign
+ ),
+ item.getTooltip(Minecraft.getMinecraft().thePlayer, false),
+ stack = item
+ )
+
fun itemStack(
item: ItemStack,
scale: Double = NEUItems.itemFontSize,
xSpacing: Int = 2,
+ ySpacing: Int = 1,
+ rescaleSkulls: Boolean = true,
horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
verticalAlign: VerticalAlignment = VerticalAlignment.CENTER,
) = object : Renderable {
- override val width = (15.5 * scale + 1.5).toInt() + xSpacing
- override val height = (15.5 * scale + 1.5).toInt()
+ override val width = (15.5 * scale + 0.5).toInt() + xSpacing
+ override val height = (15.5 * scale + 0.5).toInt() + ySpacing
override val horizontalAlign = horizontalAlign
override val verticalAlign = verticalAlign
override fun render(posX: Int, posY: Int) {
- item.renderOnScreen(xSpacing / 2.0f, 0F, scaleMultiplier = scale)
+ item.renderOnScreen(xSpacing / 2.0f, 0F, scaleMultiplier = scale, rescaleSkulls)
}
}
@@ -379,7 +407,7 @@ interface Renderable {
scale: Double = 1.0,
color: Color = Color.WHITE,
horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
- verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
+ verticalAlign: VerticalAlignment = VerticalAlignment.CENTER,
) = object : Renderable {
val list by lazy {
@@ -390,9 +418,9 @@ interface Renderable {
override val width by lazy {
if (list.size == 1) {
- (Minecraft.getMinecraft().fontRendererObj.getStringWidth(text) / scale).toInt() + 1
+ (Minecraft.getMinecraft().fontRendererObj.getStringWidth(text) * scale).toInt() + 1
} else {
- (width / scale).toInt() + 1
+ width
}
}
@@ -431,6 +459,7 @@ interface Renderable {
content: List<List<Renderable?>>,
xPadding: Int = 1,
yPadding: Int = 0,
+ useEmptySpace: Boolean = false,
horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
) = object : Renderable {
@@ -442,6 +471,9 @@ interface Renderable {
override val width = xOffsets.last() - xPadding
override val height = yOffsets.last() - yPadding
+ val emptySpaceX = if (useEmptySpace) 0 else xPadding
+ val emptySpaceY = if (useEmptySpace) 0 else yPadding
+
override fun render(posX: Int, posY: Int) {
content.forEachIndexed { rowIndex, row ->
row.forEachIndexed { index, renderable ->
@@ -450,8 +482,8 @@ interface Renderable {
renderable?.renderXYAligned(
posX + xOffsets[index],
posY + yOffsets[rowIndex],
- xOffsets[index + 1] - xOffsets[index],
- yOffsets[rowIndex + 1] - yOffsets[rowIndex]
+ xOffsets[index + 1] - xOffsets[index] - emptySpaceX,
+ yOffsets[rowIndex + 1] - yOffsets[rowIndex] - emptySpaceY
)
GlStateManager.popMatrix()
}
@@ -557,7 +589,52 @@ interface Renderable {
override val horizontalAlign = horizontalAlign
override val verticalAlign = verticalAlign
override fun render(posX: Int, posY: Int) {
- render.renderXAligned(0, 0, width)
+ render.renderXAligned(posX, posY, width)
+ }
+ }
+
+ fun fixedSizeLine(
+ content: List<Renderable>,
+ width: Int,
+ horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
+ verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
+ ) = object : Renderable {
+ val render = content
+
+ override val width = width
+ override val height = render.maxOfOrNull { it.height } ?: 0
+ override val horizontalAlign = horizontalAlign
+ override val verticalAlign = verticalAlign
+
+ val emptySpace = width - render.sumOf { it.width }
+ val spacing = emptySpace / render.size
+
+ override fun render(posX: Int, posY: Int) {
+ var xOffset = posX
+ render.forEach {
+ val x = it.width + spacing
+ it.renderXYAligned(xOffset, posY, x, height)
+ xOffset += x
+ GlStateManager.translate(x.toFloat(), 0f, 0f)
+ }
+ GlStateManager.translate(-(xOffset - posX).toFloat(), 0f, 0f)
+ }
+ }
+
+ fun fixedSizeCollum(
+ content: Renderable,
+ height: Int,
+ horizontalAlign: HorizontalAlignment = HorizontalAlignment.LEFT,
+ verticalAlign: VerticalAlignment = VerticalAlignment.TOP,
+ ) = object : Renderable {
+ val render = content
+
+ override val width = render.width
+ override val height = height
+ override val horizontalAlign = horizontalAlign
+ override val verticalAlign = verticalAlign
+ override fun render(posX: Int, posY: Int) {
+ render.renderYAligned(posX, posY, height)
}
}
@@ -601,7 +678,7 @@ interface Renderable {
override fun render(posX: Int, posY: Int) {
var yOffset = posY
renderables.forEach {
- it.renderXAligned(yOffset, posX, width)
+ it.renderXAligned(posX, yOffset, width)
yOffset += it.height + spacing
GlStateManager.translate(0f, (it.height + spacing).toFloat(), 0f)
}
@@ -722,7 +799,15 @@ interface Renderable {
yOffsets.indexOfFirst { it >= scroll.asInt() }..<(yOffsets.indexOfFirst { it >= end }
.takeIf { it > 0 }
?: yOffsets.size) - 1
- for (rowIndex in range) {
+
+ val range2 =
+ if (range.last + 3 <= yOffsets.size && yOffsets[range.last + 2] - yOffsets[range.first] <= height - renderY) {
+ range.first..range.last() + 1
+ } else {
+ range
+ }
+
+ for (rowIndex in range2) {
content[rowIndex].forEachIndexed { index, renderable ->
GlStateManager.translate(xOffsets[index].toFloat(), 0f, 0f)
renderable?.renderXYAligned(
diff --git a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt
index e1f93574e..cf81fc9ff 100644
--- a/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt
+++ b/src/main/java/at/hannibal2/skyhanni/utils/renderables/RenderableUtils.kt
@@ -13,22 +13,25 @@ internal object RenderableUtils {
buildList {
add(0)
while (true) {
- buffer += content.map { it.getOrNull(index) }.takeIf { it.any { it != null } }?.maxOf {
+ buffer += content.map { it.getOrNull(index) }.takeIf { it.any { it != null } }?.maxOfOrNull {
it?.width ?: 0
}?.let { it + xPadding } ?: break
add(buffer)
index++
}
+ if (this.size == 1) {
+ add(xPadding)
+ }
}
}
/** Calculates the absolute y position of the rows in a table*/
fun calculateTableYOffsets(content: List<List<Renderable?>>, yPadding: Int) = run {
var buffer = 0
- listOf(0) + content.map { row ->
- buffer += row.maxOf { it?.height ?: 0 } + yPadding
+ listOf(0) + (content.takeIf { it.isNotEmpty() }?.map { row ->
+ buffer += (row.maxOfOrNull { it?.height ?: 0 } ?: 0) + yPadding
buffer
- }
+ } ?: listOf(yPadding))
}
private fun calculateAlignmentXOffset(renderable: Renderable, xSpace: Int) = when (renderable.horizontalAlign) {