Merge branch 'mc-1.21.3'
This commit is contained in:
@@ -1,19 +1,22 @@
|
||||
package moe.nea.firmament.compat.rei
|
||||
|
||||
import me.shedaniel.math.Dimension
|
||||
import me.shedaniel.math.FloatingDimension
|
||||
import me.shedaniel.math.Point
|
||||
import me.shedaniel.math.Rectangle
|
||||
import me.shedaniel.rei.api.client.gui.widgets.WidgetWithBounds
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
import net.minecraft.client.gui.Drawable
|
||||
import net.minecraft.client.gui.Element
|
||||
import net.minecraft.client.gui.ParentElement
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import moe.nea.firmament.gui.entity.EntityRenderer
|
||||
import moe.nea.firmament.util.ErrorUtil
|
||||
|
||||
|
||||
class EntityWidget(val entity: LivingEntity?, val point: Point) : WidgetWithBounds() {
|
||||
class EntityWidget(
|
||||
val entity: LivingEntity?,
|
||||
val point: Point,
|
||||
val size: FloatingDimension = FloatingDimension(defaultSize)
|
||||
) : WidgetWithBounds() {
|
||||
override fun children(): List<Element> {
|
||||
return emptyList()
|
||||
}
|
||||
@@ -22,18 +25,35 @@ class EntityWidget(val entity: LivingEntity?, val point: Point) : WidgetWithBoun
|
||||
|
||||
override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
try {
|
||||
if (!hasErrored)
|
||||
EntityRenderer.renderEntity(entity!!, context, point.x, point.y, mouseX.toFloat(), mouseY.toFloat())
|
||||
context.matrices.push()
|
||||
if (!hasErrored) {
|
||||
context.matrices.translate(point.x.toDouble(), point.y.toDouble(), 0.0)
|
||||
val xScale = size.width / defaultSize.width.toDouble()
|
||||
val yScale = size.height / defaultSize.height.toDouble()
|
||||
context.matrices.scale(xScale.toFloat(), yScale.toFloat(), 1.0F)
|
||||
EntityRenderer.renderEntity(
|
||||
entity!!,
|
||||
context,
|
||||
0, 0,
|
||||
(mouseX - point.x) * xScale,
|
||||
(mouseY - point.y) * yScale)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
ErrorUtil.softError("Failed to render constructed entity: $entity", ex)
|
||||
hasErrored = true
|
||||
} finally {
|
||||
context.matrices.pop()
|
||||
}
|
||||
if (hasErrored) {
|
||||
context.fill(point.x, point.y, point.x + 50, point.y + 80, 0xFFAA2222.toInt())
|
||||
context.fill(point.x, point.y, point.x + size.width.toInt(), point.y + size.height.toInt(), 0xFFAA2222.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val defaultSize = Dimension(50, 80)
|
||||
}
|
||||
|
||||
override fun getBounds(): Rectangle {
|
||||
return Rectangle(point, Dimension(50, 80))
|
||||
return Rectangle(point, size)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import moe.nea.firmament.compat.rei.recipes.SBEssenceUpgradeRecipe
|
||||
import moe.nea.firmament.compat.rei.recipes.SBForgeRecipe
|
||||
import moe.nea.firmament.compat.rei.recipes.SBKatRecipe
|
||||
import moe.nea.firmament.compat.rei.recipes.SBMobDropRecipe
|
||||
import moe.nea.firmament.compat.rei.recipes.SBReforgeRecipe
|
||||
import moe.nea.firmament.events.HandledScreenPushREIEvent
|
||||
import moe.nea.firmament.features.inventory.CraftingOverlay
|
||||
import moe.nea.firmament.features.inventory.storageoverlay.StorageOverlayScreen
|
||||
@@ -78,6 +79,7 @@ class FirmamentReiPlugin : REIClientPlugin {
|
||||
registry.add(SBForgeRecipe.Category)
|
||||
registry.add(SBMobDropRecipe.Category)
|
||||
registry.add(SBKatRecipe.Category)
|
||||
registry.add(SBReforgeRecipe.Category)
|
||||
registry.add(SBEssenceUpgradeRecipe.Category)
|
||||
}
|
||||
|
||||
@@ -90,6 +92,10 @@ class FirmamentReiPlugin : REIClientPlugin {
|
||||
registry.registerDisplayGenerator(
|
||||
SBCraftingRecipe.Category.catIdentifier,
|
||||
SkyblockCraftingRecipeDynamicGenerator)
|
||||
registry.registerDisplayGenerator(
|
||||
SBReforgeRecipe.catIdentifier,
|
||||
SBReforgeRecipe.DynamicGenerator
|
||||
)
|
||||
registry.registerDisplayGenerator(
|
||||
SBForgeRecipe.Category.categoryIdentifier,
|
||||
SkyblockForgeRecipeDynamicGenerator)
|
||||
|
||||
@@ -0,0 +1,210 @@
|
||||
package moe.nea.firmament.compat.rei.recipes
|
||||
|
||||
import java.util.Optional
|
||||
import me.shedaniel.math.Dimension
|
||||
import me.shedaniel.math.FloatingDimension
|
||||
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.Label
|
||||
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.client.registry.display.DynamicDisplayGenerator
|
||||
import me.shedaniel.rei.api.client.view.ViewSearchBuilder
|
||||
import me.shedaniel.rei.api.common.category.CategoryIdentifier
|
||||
import me.shedaniel.rei.api.common.display.Display
|
||||
import me.shedaniel.rei.api.common.display.DisplaySerializer
|
||||
import me.shedaniel.rei.api.common.entry.EntryIngredient
|
||||
import me.shedaniel.rei.api.common.entry.EntryStack
|
||||
import net.minecraft.entity.EntityType
|
||||
import net.minecraft.entity.SpawnReason
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.village.VillagerProfession
|
||||
import moe.nea.firmament.Firmament
|
||||
import moe.nea.firmament.compat.rei.EntityWidget
|
||||
import moe.nea.firmament.compat.rei.SBItemEntryDefinition
|
||||
import moe.nea.firmament.gui.entity.EntityRenderer
|
||||
import moe.nea.firmament.repo.Reforge
|
||||
import moe.nea.firmament.repo.ReforgeStore
|
||||
import moe.nea.firmament.repo.RepoItemTypeCache
|
||||
import moe.nea.firmament.repo.RepoManager
|
||||
import moe.nea.firmament.repo.SBItemStack
|
||||
import moe.nea.firmament.util.AprilFoolsUtil
|
||||
import moe.nea.firmament.util.FirmFormatters
|
||||
import moe.nea.firmament.util.SkyblockId
|
||||
import moe.nea.firmament.util.gold
|
||||
import moe.nea.firmament.util.grey
|
||||
import moe.nea.firmament.util.skyblock.ItemType
|
||||
import moe.nea.firmament.util.skyblock.Rarity
|
||||
import moe.nea.firmament.util.skyblock.SkyBlockItems
|
||||
import moe.nea.firmament.util.skyblockId
|
||||
import moe.nea.firmament.util.tr
|
||||
|
||||
class SBReforgeRecipe(
|
||||
val reforge: Reforge,
|
||||
val limitToItem: SkyblockId?,
|
||||
) : Display {
|
||||
companion object {
|
||||
val catIdentifier = CategoryIdentifier.of<SBReforgeRecipe>(Firmament.MOD_ID, "reforge_recipe")
|
||||
}
|
||||
|
||||
object Category : DisplayCategory<SBReforgeRecipe> {
|
||||
override fun getCategoryIdentifier(): CategoryIdentifier<out SBReforgeRecipe> {
|
||||
return catIdentifier
|
||||
}
|
||||
|
||||
override fun getTitle(): Text {
|
||||
return tr("firmament.recipecategory.reforge", "Reforge")
|
||||
}
|
||||
|
||||
override fun getIcon(): Renderer {
|
||||
return SBItemEntryDefinition.getEntry(SkyBlockItems.REFORGE_ANVIL)
|
||||
}
|
||||
|
||||
override fun setupDisplay(display: SBReforgeRecipe, bounds: Rectangle): MutableList<Widget> {
|
||||
val list = mutableListOf<Widget>()
|
||||
list.add(Widgets.createRecipeBase(bounds))
|
||||
val inputSlot = Widgets.createSlot(Point(bounds.minX + 10, bounds.centerY - 9))
|
||||
.markInput().entries(display.inputItems)
|
||||
list.add(inputSlot)
|
||||
if (display.reforgeStone != null) {
|
||||
list.add(Widgets.createSlot(Point(bounds.minX + 10 + 24, bounds.centerY - 9 - 10))
|
||||
.markInput().entry(display.reforgeStone))
|
||||
list.add(Widgets.withTooltip(
|
||||
Widgets.withTranslate(Widgets.wrapRenderer(
|
||||
Rectangle(Point(bounds.minX + 10 + 24, bounds.centerY - 9 + 10), Dimension(16, 16)),
|
||||
SBItemEntryDefinition.getEntry(SkyBlockItems.REFORGE_ANVIL)), 0.0, 0.0, 150.0),
|
||||
Rarity.entries.mapNotNull { rarity ->
|
||||
display.reforge.reforgeCosts?.get(rarity)?.let { rarity to it }
|
||||
}.map { (rarity, cost) ->
|
||||
Text.literal("")
|
||||
.append(rarity.text)
|
||||
.append(": ")
|
||||
.append(Text.literal("${FirmFormatters.formatCommas(cost, 0)} Coins").gold())
|
||||
}
|
||||
))
|
||||
} else {
|
||||
val size = if (AprilFoolsUtil.isAprilFoolsDay) 1.2 else 0.6
|
||||
val dimension =
|
||||
FloatingDimension(EntityWidget.defaultSize.width * size, EntityWidget.defaultSize.height * size)
|
||||
list.add(Widgets.withTooltip(
|
||||
EntityWidget(
|
||||
EntityType.VILLAGER.create(EntityRenderer.fakeWorld, SpawnReason.COMMAND)
|
||||
?.also { it.villagerData = it.villagerData.withProfession(VillagerProfession.WEAPONSMITH) },
|
||||
Point(bounds.minX + 10 + 24 + 8 - dimension.width / 2, bounds.centerY - dimension.height / 2),
|
||||
dimension
|
||||
),
|
||||
tr("firmament.recipecategory.reforge.basic",
|
||||
"This is a basic reforge, available at the Blacksmith.").grey()
|
||||
))
|
||||
}
|
||||
list.add(Widgets.createSlot(Point(bounds.minX + 10 + 24 + 24, bounds.centerY - 9))
|
||||
.markInput().entries(display.outputItems))
|
||||
val statToLineMappings = mutableListOf<Pair<String, Label>>()
|
||||
for ((i, statId) in display.reforge.statUniverse.withIndex()) {
|
||||
val label = Widgets.createLabel(
|
||||
Point(bounds.minX + 10 + 24 + 24 + 20, bounds.minY + 8 + i * 11),
|
||||
SBItemStack.Companion.StatLine(SBItemStack.statIdToName(statId), null).reconstitute(7))
|
||||
.horizontalAlignment(Label.LEFT_ALIGNED)
|
||||
statToLineMappings.add(statId to label)
|
||||
list.add(label)
|
||||
}
|
||||
fun updateStatLines() {
|
||||
val entry = inputSlot.currentEntry?.castValue<SBItemStack>() ?: return
|
||||
val stats = display.reforge.reforgeStats?.get(entry.rarity) ?: mapOf()
|
||||
for ((stat, label) in statToLineMappings) {
|
||||
label.message =
|
||||
SBItemStack.Companion.StatLine(
|
||||
SBItemStack.statIdToName(stat), null,
|
||||
valueNum = stats[stat]
|
||||
).reconstitute(7)
|
||||
}
|
||||
}
|
||||
updateStatLines()
|
||||
inputSlot.withEntriesListener { updateStatLines() }
|
||||
return list
|
||||
}
|
||||
}
|
||||
|
||||
object DynamicGenerator : DynamicDisplayGenerator<SBReforgeRecipe> {
|
||||
fun getRecipesForSBItemStack(item: SBItemStack): Optional<List<SBReforgeRecipe>> {
|
||||
val reforgeRecipes = mutableListOf<SBReforgeRecipe>()
|
||||
for (reforge in ReforgeStore.findEligibleForInternalName(item.skyblockId)) {
|
||||
reforgeRecipes.add(SBReforgeRecipe(reforge, item.skyblockId))
|
||||
}
|
||||
for (reforge in ReforgeStore.findEligibleForItem(item.itemType ?: ItemType.NIL)) {
|
||||
reforgeRecipes.add(SBReforgeRecipe(reforge, item.skyblockId))
|
||||
}
|
||||
if (reforgeRecipes.isEmpty()) return Optional.empty()
|
||||
return Optional.of(reforgeRecipes)
|
||||
}
|
||||
|
||||
override fun getRecipeFor(entry: EntryStack<*>): Optional<List<SBReforgeRecipe>> {
|
||||
if (entry.type != SBItemEntryDefinition.type) return Optional.empty()
|
||||
val item = entry.castValue<SBItemStack>()
|
||||
return getRecipesForSBItemStack(item)
|
||||
}
|
||||
|
||||
override fun getUsageFor(entry: EntryStack<*>): Optional<List<SBReforgeRecipe>> {
|
||||
if (entry.type != SBItemEntryDefinition.type) return Optional.empty()
|
||||
val item = entry.castValue<SBItemStack>()
|
||||
ReforgeStore.byReforgeStone[item.skyblockId]?.let { stoneReforge ->
|
||||
return Optional.of(listOf(SBReforgeRecipe(stoneReforge, null)))
|
||||
}
|
||||
return getRecipesForSBItemStack(item)
|
||||
}
|
||||
|
||||
override fun generate(builder: ViewSearchBuilder): Optional<List<SBReforgeRecipe>> {
|
||||
// TODO: check builder.recipesFor and such and optionally return all reforge recipes
|
||||
return Optional.empty()
|
||||
}
|
||||
}
|
||||
|
||||
private val eligibleItems =
|
||||
if (limitToItem != null) listOfNotNull(RepoManager.getNEUItem(limitToItem))
|
||||
else reforge.eligibleItems.flatMap {
|
||||
when (it) {
|
||||
is Reforge.ReforgeEligibilityFilter.AllowsInternalName ->
|
||||
listOfNotNull(RepoManager.getNEUItem(it.internalName))
|
||||
|
||||
is Reforge.ReforgeEligibilityFilter.AllowsItemType ->
|
||||
ReforgeStore.resolveItemType(it.itemType)
|
||||
.flatMap {
|
||||
RepoItemTypeCache.byItemType[it] ?: listOf()
|
||||
}
|
||||
|
||||
is Reforge.ReforgeEligibilityFilter.AllowsVanillaItemType -> {
|
||||
listOf() // TODO: add filter support for this and potentially rework this to search for the declared item type in repo, instead of remapped item type
|
||||
}
|
||||
}
|
||||
}
|
||||
private val inputItems = eligibleItems.map { SBItemEntryDefinition.getEntry(it.skyblockId) }
|
||||
private val outputItems =
|
||||
inputItems.map { SBItemEntryDefinition.getEntry(it.value.copy(reforge = reforge.reforgeId)) }
|
||||
private val reforgeStone = reforge.reforgeStone?.let(SBItemEntryDefinition::getEntry)
|
||||
private val inputEntries =
|
||||
listOf(EntryIngredient.of(inputItems)) + listOfNotNull(reforgeStone?.let(EntryIngredient::of))
|
||||
private val outputEntries = listOf(EntryIngredient.of(outputItems))
|
||||
|
||||
override fun getInputEntries(): List<EntryIngredient> {
|
||||
return inputEntries
|
||||
}
|
||||
|
||||
override fun getOutputEntries(): List<EntryIngredient> {
|
||||
return outputEntries
|
||||
}
|
||||
|
||||
override fun getCategoryIdentifier(): CategoryIdentifier<*> {
|
||||
return catIdentifier
|
||||
}
|
||||
|
||||
override fun getDisplayLocation(): Optional<Identifier> {
|
||||
return Optional.empty()
|
||||
}
|
||||
|
||||
override fun getSerializer(): DisplaySerializer<out Display>? {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,11 @@ import dev.isxander.yacl3.api.OptionGroup
|
||||
import dev.isxander.yacl3.api.YetAnotherConfigLib
|
||||
import dev.isxander.yacl3.api.controller.ControllerBuilder
|
||||
import dev.isxander.yacl3.api.controller.DoubleSliderControllerBuilder
|
||||
import dev.isxander.yacl3.api.controller.EnumControllerBuilder
|
||||
import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder
|
||||
import dev.isxander.yacl3.api.controller.StringControllerBuilder
|
||||
import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder
|
||||
import dev.isxander.yacl3.api.controller.ValueFormatter
|
||||
import dev.isxander.yacl3.gui.YACLScreen
|
||||
import dev.isxander.yacl3.gui.tab.ListHolderWidget
|
||||
import kotlin.time.Duration
|
||||
@@ -23,8 +25,10 @@ import net.minecraft.client.gui.Element
|
||||
import net.minecraft.client.gui.screen.Screen
|
||||
import net.minecraft.text.Text
|
||||
import moe.nea.firmament.gui.config.BooleanHandler
|
||||
import moe.nea.firmament.gui.config.ChoiceHandler
|
||||
import moe.nea.firmament.gui.config.ClickHandler
|
||||
import moe.nea.firmament.gui.config.DurationHandler
|
||||
import moe.nea.firmament.gui.config.EnumRenderer
|
||||
import moe.nea.firmament.gui.config.FirmamentConfigScreenProvider
|
||||
import moe.nea.firmament.gui.config.HudMeta
|
||||
import moe.nea.firmament.gui.config.HudMetaHandler
|
||||
@@ -89,6 +93,10 @@ class YaclIntegration : FirmamentConfigScreenProvider {
|
||||
}
|
||||
.build()
|
||||
|
||||
is ChoiceHandler<*> -> return createDefaultBinding {
|
||||
createChoiceBinding(handler as ChoiceHandler<*>, managedOption as ManagedOption<*>, it as Option<*>)
|
||||
}.build()
|
||||
|
||||
is BooleanHandler -> return createDefaultBinding(TickBoxControllerBuilder::create).build()
|
||||
is StringHandler -> return createDefaultBinding(StringControllerBuilder::create).build()
|
||||
is IntegerHandler -> return createDefaultBinding {
|
||||
@@ -114,6 +122,27 @@ class YaclIntegration : FirmamentConfigScreenProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private enum class Sacrifice {}
|
||||
|
||||
private fun createChoiceBinding(
|
||||
handler: ChoiceHandler<*>,
|
||||
managedOption: ManagedOption<*>,
|
||||
option: Option<*>
|
||||
): ControllerBuilder<Any> {
|
||||
val b = EnumControllerBuilder.create(option as Option<Sacrifice>)
|
||||
b.enumClass(handler.enumClass as Class<Sacrifice>)
|
||||
/**
|
||||
* This is a function with E to avoid realizing the Sacrifice outside of a `X<E>` wrapper.
|
||||
*/
|
||||
fun <E : Enum<*>> makeValueFormatter(): ValueFormatter<E> {
|
||||
return ValueFormatter<E> {
|
||||
(handler.renderer as EnumRenderer<E>).getName(managedOption as ManagedOption<E>, it)
|
||||
}
|
||||
}
|
||||
b.formatValue(makeValueFormatter())
|
||||
return b as ControllerBuilder<Any>
|
||||
}
|
||||
|
||||
|
||||
fun buildConfig(): YetAnotherConfigLib {
|
||||
return YetAnotherConfigLib.createBuilder()
|
||||
|
||||
Reference in New Issue
Block a user