diff options
5 files changed, 136 insertions, 5 deletions
@@ -27,4 +27,8 @@ Priority 2: - dirt wand - block zapper +Priority 3: +- Use REIs "Move Item" functionality to higlight slots + + - and much more that i will add as i go along diff --git a/src/main/kotlin/moe/nea/notenoughupdates/recipes/SBCraftingRecipe.kt b/src/main/kotlin/moe/nea/notenoughupdates/recipes/SBCraftingRecipe.kt new file mode 100644 index 0000000..12bc1d3 --- /dev/null +++ b/src/main/kotlin/moe/nea/notenoughupdates/recipes/SBCraftingRecipe.kt @@ -0,0 +1,74 @@ +package moe.nea.notenoughupdates.recipes + +import io.github.moulberry.repo.data.NEUCraftingRecipe +import io.github.moulberry.repo.data.NEUIngredient +import io.github.moulberry.repo.data.NEURecipe +import me.shedaniel.math.Point +import me.shedaniel.math.Rectangle +import me.shedaniel.rei.api.client.gui.Renderer +import me.shedaniel.rei.api.client.gui.widgets.Widget +import me.shedaniel.rei.api.client.gui.widgets.Widgets +import me.shedaniel.rei.api.client.registry.display.DisplayCategory +import me.shedaniel.rei.api.common.category.CategoryIdentifier +import me.shedaniel.rei.api.common.display.Display +import me.shedaniel.rei.api.common.entry.EntryIngredient +import me.shedaniel.rei.api.common.util.EntryStacks +import net.minecraft.block.Blocks +import net.minecraft.text.Text +import moe.nea.notenoughupdates.NotEnoughUpdates +import moe.nea.notenoughupdates.rei.SBItemEntryDefinition +import moe.nea.notenoughupdates.util.SkyblockId + +abstract class SBRecipe() : Display { + abstract val neuRecipe: NEURecipe + override fun getInputEntries(): List<EntryIngredient> { + return neuRecipe.allInputs.map { + val entryStack = SBItemEntryDefinition.getEntry(SkyblockId(it.itemId)) + EntryIngredient.of(entryStack) + } + } + + override fun getOutputEntries(): List<EntryIngredient> { + return neuRecipe.allOutputs.map { + val entryStack = SBItemEntryDefinition.getEntry(SkyblockId(it.itemId)) + EntryIngredient.of(entryStack) + } + } +} + +class SBCraftingRecipe(override val neuRecipe: NEUCraftingRecipe) : SBRecipe() { + override fun getCategoryIdentifier(): CategoryIdentifier<*> = Category.catIdentifier + + object Category : DisplayCategory<SBCraftingRecipe> { + val catIdentifier = CategoryIdentifier.of<SBCraftingRecipe>(NotEnoughUpdates.MOD_ID, "crafing_recipe") + override fun getCategoryIdentifier(): CategoryIdentifier<out SBCraftingRecipe> = catIdentifier + + override fun getTitle(): Text = Text.literal("SkyBlock Crafting") + + override fun getIcon(): Renderer = EntryStacks.of(Blocks.CRAFTING_TABLE) + override fun setupDisplay(display: SBCraftingRecipe, bounds: Rectangle): List<Widget> { + val point = Point(bounds.centerX - 58, bounds.centerY - 27) + return buildList { + add(Widgets.createRecipeBase(bounds)) + add(Widgets.createArrow(Point(point.x + 60, point.y + 18))) + add(Widgets.createResultSlotBackground(Point(point.x + 95, point.y + 19))) + for (i in 0 until 3) { + for (j in 0 until 3) { + val slot = Widgets.createSlot(Point(point.x + 1 + i * 18, point.y + 1 + j * 18)).markInput() + add(slot) + val item = display.neuRecipe.inputs[i + j * 3] + if (item == null || item == NEUIngredient.SENTINEL_EMPTY) continue + slot.entry(SBItemEntryDefinition.getEntry(SkyblockId(item.itemId))) // TODO: make use of stackable item entries + } + } + add( + Widgets.createSlot(Point(point.x + 95, point.y + 19)) + .entry(SBItemEntryDefinition.getEntry(SkyblockId(display.neuRecipe.output.itemId))) + .disableBackground().markOutput() + ) + } + } + + } + +} diff --git a/src/main/kotlin/moe/nea/notenoughupdates/rei/NEUReiPlugin.kt b/src/main/kotlin/moe/nea/notenoughupdates/rei/NEUReiPlugin.kt index de515f3..2bf3a5b 100644 --- a/src/main/kotlin/moe/nea/notenoughupdates/rei/NEUReiPlugin.kt +++ b/src/main/kotlin/moe/nea/notenoughupdates/rei/NEUReiPlugin.kt @@ -1,19 +1,27 @@ package moe.nea.notenoughupdates.rei +import io.github.moulberry.repo.data.NEUCraftingRecipe import io.github.moulberry.repo.data.NEUItem +import java.util.* import me.shedaniel.rei.api.client.plugins.REIClientPlugin +import me.shedaniel.rei.api.client.registry.category.CategoryRegistry +import me.shedaniel.rei.api.client.registry.display.DisplayRegistry +import me.shedaniel.rei.api.client.registry.display.DynamicDisplayGenerator import me.shedaniel.rei.api.client.registry.entry.CollapsibleEntryRegistry import me.shedaniel.rei.api.client.registry.entry.EntryRegistry import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry +import me.shedaniel.rei.api.client.view.ViewSearchBuilder import me.shedaniel.rei.api.common.entry.EntryStack import me.shedaniel.rei.api.common.entry.type.EntryTypeRegistry import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes import net.minecraft.item.ItemStack import net.minecraft.text.Text import net.minecraft.util.Identifier +import moe.nea.notenoughupdates.recipes.SBCraftingRecipe import moe.nea.notenoughupdates.repo.ItemCache.asItemStack import moe.nea.notenoughupdates.repo.RepoManager import moe.nea.notenoughupdates.util.SkyblockId +import moe.nea.notenoughupdates.util.skyblockId class NEUReiPlugin : REIClientPlugin { @@ -30,6 +38,38 @@ class NEUReiPlugin : REIClientPlugin { registry.register(SKYBLOCK_ITEM_TYPE_ID, SBItemEntryDefinition) } + override fun registerCategories(registry: CategoryRegistry) { + registry.add(SBCraftingRecipe.Category) + } + override fun registerDisplays(registry: DisplayRegistry) { + registry.registerGlobalDisplayGenerator(object : DynamicDisplayGenerator<SBCraftingRecipe> { + override fun getRecipeFor(entry: EntryStack<*>): Optional<List<SBCraftingRecipe>> { + if (entry.type != SBItemEntryDefinition.type) return Optional.empty() + val item = entry.castValue<NEUItem>() + val recipes = RepoManager.getRecipesFor(item.skyblockId) + val craftingRecipes = recipes.filterIsInstance<NEUCraftingRecipe>() + return Optional.of(craftingRecipes.map { SBCraftingRecipe(it) }) + } + + override fun generate(builder: ViewSearchBuilder): Optional<List<SBCraftingRecipe>> { + if (SBCraftingRecipe.Category.catIdentifier !in builder.categories) return Optional.empty() + return Optional.of( + RepoManager.getAllRecipes().filterIsInstance<NEUCraftingRecipe>().map { SBCraftingRecipe(it) } + .toList() + ) + } + + override fun getUsageFor(entry: EntryStack<*>): Optional<List<SBCraftingRecipe>> { + if (entry.type != SBItemEntryDefinition.type) return Optional.empty() + val item = entry.castValue<NEUItem>() + val recipes = RepoManager.getUsagesFor(item.skyblockId) + val craftingRecipes = recipes.filterIsInstance<NEUCraftingRecipe>() + return Optional.of(craftingRecipes.map { SBCraftingRecipe(it) }) + + } + }) + } + override fun registerCollapsibleEntries(registry: CollapsibleEntryRegistry) { RepoManager.neuRepo.constants.parents.parents .forEach { (parent, children) -> diff --git a/src/main/kotlin/moe/nea/notenoughupdates/rei/SBItemEntryDefinition.kt b/src/main/kotlin/moe/nea/notenoughupdates/rei/SBItemEntryDefinition.kt index 90d5931..b449848 100644 --- a/src/main/kotlin/moe/nea/notenoughupdates/rei/SBItemEntryDefinition.kt +++ b/src/main/kotlin/moe/nea/notenoughupdates/rei/SBItemEntryDefinition.kt @@ -16,7 +16,10 @@ import net.minecraft.util.Identifier import moe.nea.notenoughupdates.rei.NEUReiPlugin.Companion.asItemEntry import moe.nea.notenoughupdates.repo.ItemCache.asItemStack import moe.nea.notenoughupdates.repo.ItemCache.getIdentifier +import moe.nea.notenoughupdates.repo.RepoManager +import moe.nea.notenoughupdates.util.SkyblockId +// TODO: allow stackable entries object SBItemEntryDefinition : EntryDefinition<NEUItem> { override fun equals(o1: NEUItem?, o2: NEUItem?, context: ComparisonContext?): Boolean { return o1 === o2 @@ -69,6 +72,7 @@ object SBItemEntryDefinition : EntryDefinition<NEUItem> { } fun getEntry(neuItem: NEUItem?) = EntryStack.of(this, neuItem) + fun getEntry(skyblockId: SkyblockId?) = EntryStack.of(this, skyblockId?.let { RepoManager.getNEUItem(it) }) } diff --git a/src/main/kotlin/moe/nea/notenoughupdates/repo/RepoManager.kt b/src/main/kotlin/moe/nea/notenoughupdates/repo/RepoManager.kt index 6470914..acaaacd 100644 --- a/src/main/kotlin/moe/nea/notenoughupdates/repo/RepoManager.kt +++ b/src/main/kotlin/moe/nea/notenoughupdates/repo/RepoManager.kt @@ -1,20 +1,22 @@ package moe.nea.notenoughupdates.repo import io.github.cottonmc.cotton.gui.client.CottonHud +import io.github.moulberry.repo.NEURecipeCache import io.github.moulberry.repo.NEURepository import io.github.moulberry.repo.NEURepositoryException +import io.github.moulberry.repo.data.NEURecipe +import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import kotlinx.coroutines.launch import kotlinx.serialization.Serializable import kotlinx.serialization.serializer -import moe.nea.notenoughupdates.NotEnoughUpdates -import moe.nea.notenoughupdates.NotEnoughUpdates.logger -import moe.nea.notenoughupdates.hud.ProgressBar -import moe.nea.notenoughupdates.util.data.DataHolder -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import net.minecraft.client.MinecraftClient import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket import net.minecraft.text.Text +import moe.nea.notenoughupdates.NotEnoughUpdates +import moe.nea.notenoughupdates.NotEnoughUpdates.logger +import moe.nea.notenoughupdates.hud.ProgressBar import moe.nea.notenoughupdates.util.SkyblockId +import moe.nea.notenoughupdates.util.data.DataHolder object RepoManager : DataHolder<RepoManager.Config>(serializer(), "repo", ::Config) { @Serializable @@ -43,6 +45,13 @@ object RepoManager : DataHolder<RepoManager.Config>(serializer(), "repo", ::Conf } } + private val recipeCache = NEURecipeCache.forRepo(neuRepo) + + fun getAllRecipes() = neuRepo.items.items.values.asSequence().flatMap { it.recipes } + + fun getRecipesFor(skyblockId: SkyblockId): Set<NEURecipe> = recipeCache.recipes[skyblockId.neuItem] ?: setOf() + fun getUsagesFor(skyblockId: SkyblockId): Set<NEURecipe> = recipeCache.usages[skyblockId.neuItem] ?: setOf() + private fun trySendClientboundUpdateRecipesPacket(): Boolean { return MinecraftClient.getInstance().world != null && MinecraftClient.getInstance().networkHandler?.onSynchronizeRecipes( SynchronizeRecipesS2CPacket(mutableListOf()) |