Skip to content

Commit b07f048

Browse files
committed
Add EMI plugin for exclusion areas and better recipe support
1 parent eaf6ba7 commit b07f048

File tree

14 files changed

+219
-23
lines changed

14 files changed

+219
-23
lines changed

Common/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ dependencies {
3131
implementation(libs.bundles.ktor)
3232

3333
modApi(libs.ioticblocks.common)
34+
35+
modImplementation(libs.emi.xplat)
3436
}

Common/src/main/kotlin/gay/object/hexdebug/gui/splicing/SplicingTableScreen.kt

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class SplicingTableScreen(
4949
val data get() = menu.clientView
5050

5151
private val hasMediaItem get() = menu.mediaSlot.hasItem()
52-
private val hasStaffItem get() = menu.staffSlot.hasItem()
52+
val hasStaffItem get() = menu.staffSlot.hasItem()
5353

5454
var guiSpellcasting = GuiSpellcasting(
5555
InteractionHand.MAIN_HAND, mutableListOf(), listOf(), null, 1
@@ -67,10 +67,45 @@ class SplicingTableScreen(
6767
// so offset up if taller or down if shorter
6868
private val staffOffsetY: Int = ((32 * 6) - staffHeight) / 2
6969

70-
private val staffMaxX get() = leftPos - 14
71-
private val staffMinX get() = staffMaxX - staffWidth
72-
private val staffMinY get() = topPos + staffOffsetY
73-
private val staffMaxY get() = staffMinY + staffHeight
70+
// relative to top left (for hasClickedOutside)
71+
private val staffMaxXOffset = -14
72+
private val staffMinXOffset = staffMaxXOffset - staffWidth
73+
private val staffMinYOffset = staffOffsetY
74+
private val staffMaxYOffset = staffMinYOffset + staffHeight
75+
76+
private val staffSlotWidth = 23
77+
private val staffSlotHeight = 24
78+
79+
private val staffSlotMinXOffset = -24
80+
private val staffSlotMaxXOffset = staffSlotMinXOffset + staffSlotWidth
81+
private val staffSlotMinYOffset = 165
82+
private val staffSlotMaxYOffset = staffSlotMinYOffset + staffSlotHeight
83+
84+
private val storageMinXOffset = 192
85+
private val storageMaxXOffset = storageMinXOffset + 46
86+
private val storageMinYOffset = 103
87+
private val storageMaxYOffset = storageMinYOffset + 87
88+
89+
// absolute
90+
val staffMinX get() = leftPos + staffMinXOffset
91+
val staffMaxX get() = leftPos + staffMaxXOffset
92+
val staffMinY get() = topPos + staffMinYOffset
93+
val staffMaxY get() = topPos + staffMaxYOffset
94+
95+
val staffSlotMinX get() = leftPos + staffSlotMinXOffset
96+
val staffSlotMaxX get() = leftPos + staffSlotMaxXOffset
97+
val staffSlotMinY get() = topPos + staffSlotMinYOffset
98+
val staffSlotMaxY get() = topPos + staffSlotMaxYOffset
99+
100+
val storageMinX get() = leftPos + storageMinXOffset
101+
val storageMaxX get() = leftPos + storageMaxXOffset
102+
val storageMinY get() = topPos + storageMinYOffset
103+
val storageMaxY get() = topPos + storageMaxYOffset
104+
105+
val exportButtonX get() = leftPos + 194
106+
val exportButtonY get() = topPos + 18
107+
val exportButtonWidth = 24
108+
val exportButtonHeight = 24
74109

75110
private val predicateButtons = mutableListOf<Pair<AbstractButton, () -> Boolean>>()
76111

@@ -124,12 +159,12 @@ class SplicingTableScreen(
124159
predicateButtons += listOf(
125160
// export hexpattern
126161
object : SpriteButton(
127-
x = leftPos + 194,
128-
y = topPos + 18,
162+
x = exportButtonX,
163+
y = exportButtonY,
129164
uOffset = 432,
130165
vOffset = 392,
131-
width = 24,
132-
height = 24,
166+
width = exportButtonWidth,
167+
height = exportButtonHeight,
133168
message = buttonText("export"),
134169
onPress = {
135170
exportToSystemClipboard()
@@ -521,10 +556,16 @@ class SplicingTableScreen(
521556
private fun isInStaffGrid(mouseX: Double, mouseY: Double, button: Int?) =
522557
staffMinX <= mouseX && mouseX <= staffMaxX && staffMinY <= mouseY && mouseY <= staffMaxY
523558
// avoid interacting with the grid when inserting the staff item...
524-
&& (button == null || hasClickedOutside(mouseX, mouseY, leftPos, topPos, button))
559+
&& (button == null || isOutsideStaffItemSlot(mouseX, mouseY, leftPos, topPos))
525560
// or when clicking the clear grid button
526561
&& !(clearGridButton?.testHitbox(mouseX, mouseY) ?: false)
527562

563+
private fun isOutsideStaffItemSlot(mouseX: Double, mouseY: Double, guiLeft: Int, guiTop: Int) =
564+
mouseX < guiLeft + staffSlotMinXOffset
565+
|| mouseY < guiTop + staffSlotMinYOffset
566+
|| mouseX >= guiLeft + staffSlotMaxXOffset
567+
|| mouseY >= guiTop + staffSlotMaxYOffset
568+
528569
override fun hasClickedOutside(
529570
mouseX: Double,
530571
mouseY: Double,
@@ -536,9 +577,14 @@ class SplicingTableScreen(
536577
// main gui
537578
super.hasClickedOutside(mouseX, mouseY, guiLeft, guiTop, mouseButton)
538579
// storage/media
539-
&& (mouseX < guiLeft + 192 || mouseY < guiTop + 103 || mouseX >= guiLeft + 192 + 46 || mouseY >= guiTop + 103 + 87)
540-
// staff
541-
&& (mouseX < guiLeft - 22 || mouseY < guiTop + 167 || mouseX >= guiLeft - 22 + 20 || mouseY >= guiTop + 167 + 20)
580+
&& (
581+
mouseX < guiLeft + storageMinXOffset
582+
|| mouseY < guiTop + storageMinYOffset
583+
|| mouseX >= guiLeft + storageMaxXOffset
584+
|| mouseY >= guiTop + storageMaxYOffset
585+
)
586+
// staff item slot
587+
&& isOutsideStaffItemSlot(mouseX, mouseY, guiLeft, guiTop)
542588
)
543589
}
544590

@@ -600,10 +646,10 @@ class SplicingTableScreen(
600646
blitSprite(guiGraphics, x = staffMaxX - 1, y = staffMaxY - 1, uOffset = 184, vOffset = 9, width = 8, height = 9)
601647

602648
// staff slot without icon
603-
blitSprite(guiGraphics, x = leftPos - 24, y = topPos + 165, uOffset = 232, vOffset = 293, width = 23, height = 24)
649+
blitSprite(guiGraphics, x = staffSlotMinX, y = staffSlotMinY, uOffset = 232, vOffset = 293, width = staffSlotWidth, height = staffSlotHeight)
604650
} else {
605651
// staff slot with icon
606-
blitSprite(guiGraphics, x = leftPos - 24, y = topPos + 165, uOffset = 232, vOffset = 328, width = 23, height = 24)
652+
blitSprite(guiGraphics, x = staffSlotMinX, y = staffSlotMinY, uOffset = 232, vOffset = 328, width = staffSlotWidth, height = staffSlotHeight)
607653
}
608654
}
609655

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package gay.`object`.hexdebug.interop
2+
3+
import at.petrak.hexcasting.common.lib.HexItems
4+
import dev.emi.emi.api.EmiRegistry
5+
import dev.emi.emi.api.recipe.EmiCraftingRecipe
6+
import dev.emi.emi.api.stack.Comparison
7+
import dev.emi.emi.api.stack.EmiStack
8+
import dev.emi.emi.api.widget.Bounds
9+
import gay.`object`.hexdebug.gui.splicing.SplicingTableScreen
10+
import gay.`object`.hexdebug.items.FocusHolderBlockItem
11+
import gay.`object`.hexdebug.items.FocusHolderBlockItem.Companion.hasIotaStack
12+
import gay.`object`.hexdebug.recipes.FocusHolderEmptyingRecipe
13+
import gay.`object`.hexdebug.recipes.FocusHolderFillingShapelessRecipe
14+
import gay.`object`.hexdebug.registry.HexDebugBlocks
15+
import net.minecraft.resources.ResourceLocation
16+
import net.minecraft.world.item.crafting.RecipeType
17+
18+
object HexDebugEmiPlugin {
19+
fun register(registry: EmiRegistry) {
20+
// if a recipe calls for an empty focus holder, disallow filled, and vice versa
21+
registry.setDefaultComparison(
22+
HexDebugBlocks.FOCUS_HOLDER.item,
23+
Comparison.compareData { it.itemStack.hasIotaStack },
24+
)
25+
26+
// show filled focus holder in sidebar
27+
// necessary because otherwise there's no good way to see the recipe for a new holder with existing focus
28+
registry.addEmiStack(EmiStack.of(FocusHolderBlockItem.withFocus()))
29+
30+
// better recipes for focus holder filling/emptying
31+
for (recipe in registry.recipeManager.getAllRecipesFor(RecipeType.CRAFTING)) {
32+
val emiRecipe = when (recipe) {
33+
is FocusHolderEmptyingRecipe -> EmiCraftingRecipe(
34+
listOf(
35+
EmiStack.of(FocusHolderBlockItem.withFocus())
36+
.setRemainder(EmiStack.of(HexDebugBlocks.FOCUS_HOLDER.item)),
37+
),
38+
EmiStack.of(HexItems.FOCUS),
39+
synthetic(recipe.id),
40+
true,
41+
)
42+
43+
is FocusHolderFillingShapelessRecipe -> EmiCraftingRecipe(
44+
listOf(
45+
EmiStack.of(HexDebugBlocks.FOCUS_HOLDER.item),
46+
EmiStack.of(HexItems.FOCUS),
47+
),
48+
EmiStack.of(FocusHolderBlockItem.withFocus()),
49+
synthetic(recipe.id),
50+
true,
51+
)
52+
53+
else -> continue
54+
}
55+
registry.removeRecipes(recipe.id)
56+
registry.addRecipe(emiRecipe)
57+
}
58+
59+
// screen exclusions for splicing table
60+
registry.addExclusionArea(SplicingTableScreen::class.java) { screen, consumer ->
61+
screen.apply {
62+
consumer.accept(Bounds(
63+
exportButtonX,
64+
exportButtonY,
65+
exportButtonWidth,
66+
exportButtonHeight,
67+
))
68+
consumer.accept(Bounds(
69+
storageMinX,
70+
storageMinY,
71+
storageMaxX - storageMinX,
72+
storageMaxY - storageMinY,
73+
))
74+
consumer.accept(Bounds(
75+
staffSlotMinX,
76+
staffSlotMinY,
77+
staffSlotMaxX - staffSlotMinX,
78+
staffSlotMaxY - staffSlotMinY,
79+
))
80+
if (hasStaffItem) {
81+
consumer.accept(Bounds(
82+
staffMinX,
83+
staffMinY,
84+
staffMaxX - staffMinX,
85+
staffMaxY - staffMinY,
86+
))
87+
}
88+
}
89+
}
90+
}
91+
92+
private fun synthetic(id: ResourceLocation) = id.withPrefix("/")
93+
}

Common/src/main/kotlin/gay/object/hexdebug/items/FocusHolderBlockItem.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import at.petrak.hexcasting.api.casting.iota.Iota
44
import at.petrak.hexcasting.api.item.IotaHolderItem
55
import at.petrak.hexcasting.api.utils.asTranslatedComponent
66
import at.petrak.hexcasting.api.utils.getList
7+
import at.petrak.hexcasting.common.lib.HexItems
78
import gay.`object`.hexdebug.HexDebug
89
import gay.`object`.hexdebug.items.base.ItemPredicateProvider
910
import gay.`object`.hexdebug.items.base.ModelPredicateEntry
1011
import gay.`object`.hexdebug.registry.HexDebugBlockEntities
12+
import gay.`object`.hexdebug.registry.HexDebugBlocks
1113
import gay.`object`.hexdebug.utils.asItemPredicate
1214
import gay.`object`.hexdebug.utils.styledHoverName
1315
import net.minecraft.core.NonNullList
@@ -69,6 +71,13 @@ class FocusHolderBlockItem(block: Block, properties: Properties) :
6971
companion object {
7072
val HAS_ITEM = HexDebug.id("has_item")
7173

74+
fun withFocus(stack: ItemStack? = null): ItemStack {
75+
val result = stack?.copy() ?: ItemStack(HexDebugBlocks.FOCUS_HOLDER.item)
76+
return result.apply {
77+
setIotaStack(ItemStack(HexItems.FOCUS))
78+
}
79+
}
80+
7281
val ItemStack.hasIotaStack get() = getBlockEntityData(this)
7382
?.getList("Items", Tag.TAG_COMPOUND)
7483
?.let { it.size > 0 }

Common/src/main/kotlin/gay/object/hexdebug/recipes/FocusHolderFillingShapedRecipe.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gay.`object`.hexdebug.recipes
22

33
import at.petrak.hexcasting.common.lib.HexItems
44
import com.google.gson.JsonObject
5+
import gay.`object`.hexdebug.items.FocusHolderBlockItem
56
import gay.`object`.hexdebug.items.FocusHolderBlockItem.Companion.hasIotaStack
67
import gay.`object`.hexdebug.items.FocusHolderBlockItem.Companion.setIotaStack
78
import gay.`object`.hexdebug.registry.HexDebugBlocks
@@ -62,9 +63,7 @@ class FocusHolderFillingShapedRecipe(
6263
width = width,
6364
height = height,
6465
recipeItems = ingredients,
65-
result = getResultItem(null).apply {
66-
setIotaStack(ItemStack(HexItems.FOCUS))
67-
},
66+
result = FocusHolderBlockItem.withFocus(getResultItem(null)),
6867
showNotification = showNotification(),
6968
)
7069
}

Common/src/main/kotlin/gay/object/hexdebug/recipes/FocusHolderFillingShapelessRecipe.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gay.`object`.hexdebug.recipes
22

33
import at.petrak.hexcasting.common.lib.HexItems
4+
import gay.`object`.hexdebug.items.FocusHolderBlockItem
45
import gay.`object`.hexdebug.items.FocusHolderBlockItem.Companion.hasIotaStack
56
import gay.`object`.hexdebug.items.FocusHolderBlockItem.Companion.setIotaStack
67
import gay.`object`.hexdebug.registry.HexDebugBlocks
@@ -16,9 +17,7 @@ import net.minecraft.world.item.crafting.Ingredient
1617
import net.minecraft.world.level.Level
1718

1819
class FocusHolderFillingShapelessRecipe(id: ResourceLocation, category: CraftingBookCategory) : CustomRecipe(id, category) {
19-
private val resultItem = ItemStack(HexDebugBlocks.FOCUS_HOLDER.item).apply {
20-
setIotaStack(ItemStack(HexItems.FOCUS))
21-
}
20+
private val resultItem = FocusHolderBlockItem.withFocus()
2221

2322
override fun matches(container: CraftingContainer, level: Level): Boolean {
2423
return findItems(container) != null

Fabric/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ hexdebugModDependencies {
2929
requires("fabric-api")
3030
requires("fabric-language-kotlin")
3131

32+
optional("emi")
3233
optional("modmenu")
3334
}
3435

@@ -78,6 +79,8 @@ dependencies {
7879
modLocalRuntime(libs.devAuth.fabric)
7980

8081
modApi(libs.ioticblocks.fabric)
82+
83+
modImplementation(libs.emi.fabric)
8184
}
8285

8386
publishMods {
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package gay.`object`.hexdebug.fabric.interop
2+
3+
import dev.emi.emi.api.EmiPlugin
4+
import dev.emi.emi.api.EmiRegistry
5+
import gay.`object`.hexdebug.interop.HexDebugEmiPlugin
6+
7+
object FabricHexDebugEmiPlugin : EmiPlugin {
8+
override fun register(registry: EmiRegistry) {
9+
HexDebugEmiPlugin.register(registry)
10+
}
11+
}

Fabric/src/main/kotlin/gay/object/hexdebug/fabric/FabricHexDebugModMenu.kt renamed to Fabric/src/main/kotlin/gay/object/hexdebug/fabric/interop/FabricHexDebugModMenu.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package gay.`object`.hexdebug.fabric
1+
package gay.`object`.hexdebug.fabric.interop
22

33
import com.terraformersmc.modmenu.api.ConfigScreenFactory
44
import com.terraformersmc.modmenu.api.ModMenuApi

Fabric/src/main/resources/fabric.mod.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@
2323
"adapter": "kotlin",
2424
"value": "gay.object.hexdebug.fabric.FabricHexDebugClient"
2525
}],
26+
"emi": [{
27+
"adapter": "kotlin",
28+
"value": "gay.object.hexdebug.fabric.interop.FabricHexDebugEmiPlugin"
29+
}],
2630
"modmenu": [{
2731
"adapter": "kotlin",
28-
"value": "gay.object.hexdebug.fabric.FabricHexDebugModMenu"
32+
"value": "gay.object.hexdebug.fabric.interop.FabricHexDebugModMenu"
2933
}]
3034
},
3135
"mixins": [
@@ -42,6 +46,7 @@
4246
"ioticblocks": ">=${versions.ioticblocks}"
4347
},
4448
"suggests": {
49+
"emi": ">=${versions.emi}",
4550
"modmenu": ">=${versions.modMenu}"
4651
}
4752
}

0 commit comments

Comments
 (0)