2021-03-28 17:50:11 +00:00
|
|
|
package net.shadowfacts.phycon.block.terminal
|
|
|
|
|
2021-04-03 14:32:41 +00:00
|
|
|
import net.minecraft.entity.player.PlayerEntity
|
2021-03-28 17:50:11 +00:00
|
|
|
import net.minecraft.entity.player.PlayerInventory
|
|
|
|
import net.minecraft.inventory.CraftingInventory
|
|
|
|
import net.minecraft.inventory.CraftingResultInventory
|
|
|
|
import net.minecraft.inventory.Inventory
|
|
|
|
import net.minecraft.item.ItemStack
|
|
|
|
import net.minecraft.network.PacketByteBuf
|
|
|
|
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket
|
2021-12-22 23:59:51 +00:00
|
|
|
import net.minecraft.recipe.RecipeMatcher
|
2021-03-28 17:50:11 +00:00
|
|
|
import net.minecraft.recipe.RecipeType
|
|
|
|
import net.minecraft.screen.slot.CraftingResultSlot
|
|
|
|
import net.minecraft.screen.slot.Slot
|
|
|
|
import net.minecraft.server.network.ServerPlayerEntity
|
|
|
|
import net.shadowfacts.phycon.init.PhyBlocks
|
|
|
|
import net.shadowfacts.phycon.init.PhyScreens
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author shadowfacts
|
|
|
|
*/
|
|
|
|
class CraftingTerminalScreenHandler(
|
|
|
|
syncId: Int,
|
|
|
|
playerInv: PlayerInventory,
|
|
|
|
terminal: CraftingTerminalBlockEntity,
|
|
|
|
): AbstractTerminalScreenHandler<CraftingTerminalBlockEntity>(PhyScreens.CRAFTING_TERMINAL, syncId, playerInv, terminal) {
|
|
|
|
|
|
|
|
val craftingInv = CraftingInv(this)
|
|
|
|
val result = CraftingResultInventory()
|
|
|
|
val resultSlot: CraftingResultSlot
|
|
|
|
|
2021-03-29 23:18:15 +00:00
|
|
|
val craftingSlotsStart: Int
|
|
|
|
val craftingSlotsEnd: Int
|
|
|
|
get() = craftingSlotsStart + 9
|
|
|
|
|
2021-03-28 17:50:11 +00:00
|
|
|
override val xOffset: Int
|
|
|
|
get() = 5
|
|
|
|
|
|
|
|
constructor(syncId: Int, playerInv: PlayerInventory, buf: PacketByteBuf):
|
|
|
|
this(
|
|
|
|
syncId,
|
|
|
|
playerInv,
|
|
|
|
PhyBlocks.CRAFTING_TERMINAL.getBlockEntity(playerInv.player.world, buf.readBlockPos())!!
|
|
|
|
)
|
|
|
|
|
|
|
|
init {
|
2021-03-29 23:18:15 +00:00
|
|
|
craftingSlotsStart = slots.size
|
2021-03-28 17:50:11 +00:00
|
|
|
for (y in 0 until 3) {
|
|
|
|
for (x in 0 until 3) {
|
|
|
|
this.addSlot(Slot(craftingInv, x + y * 3, 13 + x * 18, 140 + y * 18))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
resultSlot = CraftingResultSlot(playerInv.player, craftingInv, result, 0, 31, 224)
|
|
|
|
addSlot(resultSlot)
|
|
|
|
|
|
|
|
updateCraftingResult()
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onContentChanged(inventory: Inventory?) {
|
|
|
|
updateCraftingResult()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun updateCraftingResult() {
|
|
|
|
val world = playerInv.player.world
|
|
|
|
if (!world.isClient) {
|
|
|
|
val player = playerInv.player as ServerPlayerEntity
|
|
|
|
val recipe = world.server!!.recipeManager.getFirstMatch(RecipeType.CRAFTING, craftingInv, world)
|
|
|
|
val resultStack =
|
|
|
|
if (recipe.isPresent && result.shouldCraftRecipe(world, player, recipe.get())) {
|
|
|
|
recipe.get().craft(craftingInv)
|
|
|
|
} else {
|
|
|
|
ItemStack.EMPTY
|
|
|
|
}
|
|
|
|
result.setStack(0, resultStack)
|
2021-12-22 23:59:51 +00:00
|
|
|
player.networkHandler.sendPacket(ScreenHandlerSlotUpdateS2CPacket(syncId, nextRevision(), resultSlot.id, resultStack))
|
2021-03-28 17:50:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun clearCraftingGrid() {
|
|
|
|
assert(!playerInv.player.world.isClient)
|
|
|
|
for (i in 0 until terminal.craftingInv.size()) {
|
|
|
|
val craftingInvStack = terminal.craftingInv.getStack(i)
|
|
|
|
if (craftingInvStack.isEmpty) continue
|
|
|
|
val remainder = terminal.internalBuffer.insert(craftingInvStack, TerminalBufferInventory.Mode.TO_NETWORK)
|
|
|
|
terminal.craftingInv.setStack(i, remainder)
|
|
|
|
}
|
|
|
|
updateCraftingResult()
|
|
|
|
sendContentUpdates()
|
|
|
|
}
|
|
|
|
|
|
|
|
fun requestMoreCraftingIngredients(maxAmount: Int) {
|
|
|
|
assert(!playerInv.player.world.isClient)
|
|
|
|
terminal.requestItemsForCrafting(maxAmount)
|
|
|
|
}
|
|
|
|
|
2021-04-03 14:32:41 +00:00
|
|
|
override fun transferSlot(player: PlayerEntity, slotId: Int): ItemStack {
|
|
|
|
if (slotId == resultSlot.id && resultSlot.hasStack()) {
|
|
|
|
val craftingResult = resultSlot.stack
|
|
|
|
val originalResult = craftingResult.copy()
|
|
|
|
|
|
|
|
// todo: CraftingScreenHandler calls onCraft, but I don't think that's necessary because onStackChanged should handle it
|
|
|
|
craftingResult.item.onCraft(craftingResult, player.world, player)
|
|
|
|
|
|
|
|
if (!insertItem(craftingResult, playerSlotsStart, playerSlotsEnd, true)) {
|
|
|
|
return ItemStack.EMPTY
|
|
|
|
}
|
2021-12-22 23:59:51 +00:00
|
|
|
resultSlot.onQuickTransfer(craftingResult, originalResult)
|
2021-04-03 14:32:41 +00:00
|
|
|
|
|
|
|
if (craftingResult.isEmpty) {
|
|
|
|
resultSlot.stack = ItemStack.EMPTY
|
|
|
|
}
|
|
|
|
|
|
|
|
if (craftingResult.count == originalResult.count) {
|
|
|
|
return ItemStack.EMPTY
|
|
|
|
}
|
|
|
|
|
2021-12-22 23:59:51 +00:00
|
|
|
resultSlot.onTakeItem(player, craftingResult)
|
|
|
|
player.dropItem(craftingResult, false)
|
2021-04-03 14:32:41 +00:00
|
|
|
|
|
|
|
return originalResult
|
|
|
|
} else {
|
|
|
|
return super.transferSlot(player, slotId)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-28 17:50:11 +00:00
|
|
|
// RecipeType.CRAFTING wants a CraftingInventory, but we can't store a CraftingInventory on the BE without a screen handler, so...
|
|
|
|
class CraftingInv(val handler: CraftingTerminalScreenHandler): CraftingInventory(handler, 3, 3) {
|
|
|
|
private val backing = handler.terminal.craftingInv
|
|
|
|
|
|
|
|
override fun isEmpty(): Boolean {
|
|
|
|
return backing.isEmpty
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun getStack(i: Int): ItemStack {
|
|
|
|
return backing.getStack(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun removeStack(i: Int): ItemStack {
|
|
|
|
return backing.removeStack(i)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun removeStack(i: Int, j: Int): ItemStack {
|
|
|
|
val res = backing.removeStack(i, j)
|
|
|
|
if (!res.isEmpty) {
|
|
|
|
handler.onContentChanged(this)
|
|
|
|
}
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun setStack(i: Int, itemStack: ItemStack?) {
|
|
|
|
backing.setStack(i, itemStack)
|
|
|
|
handler.onContentChanged(this)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun clear() {
|
|
|
|
backing.clear()
|
|
|
|
}
|
|
|
|
|
2021-12-22 23:59:51 +00:00
|
|
|
override fun provideRecipeInputs(finder: RecipeMatcher) {
|
2021-03-28 17:50:11 +00:00
|
|
|
TODO()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|