Add Wooden Hopper GUI, recipe, advancement, item spawning

This commit is contained in:
Shadowfacts 2020-03-28 12:26:25 -04:00
parent c7a2c7f0f4
commit b8d374b982
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
11 changed files with 240 additions and 20 deletions

View File

@ -1,6 +1,9 @@
package net.shadowfacts.extrahoppers package net.shadowfacts.extrahoppers
import net.fabricmc.api.ModInitializer import net.fabricmc.api.ModInitializer
import net.fabricmc.fabric.api.container.ContainerFactory
import net.fabricmc.fabric.api.container.ContainerProviderRegistry
import net.shadowfacts.extrahoppers.block.wood.WoodHopperContainer
import net.shadowfacts.extrahoppers.init.EHBlockEntities import net.shadowfacts.extrahoppers.init.EHBlockEntities
import net.shadowfacts.extrahoppers.init.EHBlocks import net.shadowfacts.extrahoppers.init.EHBlocks
import net.shadowfacts.extrahoppers.init.EHItems import net.shadowfacts.extrahoppers.init.EHItems
@ -8,13 +11,11 @@ import net.shadowfacts.extrahoppers.init.EHItems
object ExtraHoppers: ModInitializer { object ExtraHoppers: ModInitializer {
override fun onInitialize() { override fun onInitialize() {
println("--------------------")
println("hello from extra hoppers")
println("--------------------")
EHBlocks.init() EHBlocks.init()
EHBlockEntities.init() EHBlockEntities.init()
EHItems.init() EHItems.init()
ContainerProviderRegistry.INSTANCE.registerFactory(WoodHopperContainer.ID, ContainerFactory(WoodHopperContainer.Companion::create))
} }
} }

View File

@ -0,0 +1,15 @@
package net.shadowfacts.extrahoppers
import net.fabricmc.api.ClientModInitializer
import net.fabricmc.fabric.api.client.screen.ContainerScreenFactory
import net.fabricmc.fabric.api.client.screen.ScreenProviderRegistry
import net.shadowfacts.extrahoppers.block.wood.WoodHopperContainer
import net.shadowfacts.extrahoppers.block.wood.WoodHopperScreen
object ExtraHoppersClient: ClientModInitializer {
override fun onInitializeClient() {
ScreenProviderRegistry.INSTANCE.registerFactory(WoodHopperContainer.ID, ContainerScreenFactory(WoodHopperScreen.Companion::create))
}
}

View File

@ -1,13 +1,15 @@
package net.shadowfacts.extrahoppers.block.wood package net.shadowfacts.extrahoppers.block.wood
import net.fabricmc.fabric.api.block.FabricBlockSettings
import net.fabricmc.fabric.api.container.ContainerProviderRegistry
import net.minecraft.block.* import net.minecraft.block.*
import net.minecraft.block.entity.Hopper import net.minecraft.block.entity.Hopper
import net.minecraft.entity.Entity import net.minecraft.entity.Entity
import net.minecraft.entity.EntityContext import net.minecraft.entity.EntityContext
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerEntity
import net.minecraft.item.ItemPlacementContext import net.minecraft.item.ItemPlacementContext
import net.minecraft.item.ItemStack import net.minecraft.sound.BlockSoundGroup
import net.minecraft.stat.Stats
import net.minecraft.state.StateManager import net.minecraft.state.StateManager
import net.minecraft.state.property.Properties import net.minecraft.state.property.Properties
import net.minecraft.util.* import net.minecraft.util.*
@ -23,7 +25,7 @@ import net.shadowfacts.extrahoppers.block.base.BlockWithEntity
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class WoodHopperBlock: BlockWithEntity<WoodHopperBlockEntity>(Settings.of(Material.WOOD)) { class WoodHopperBlock: BlockWithEntity<WoodHopperBlockEntity>(FabricBlockSettings.of(Material.WOOD).strength(2f, 3f).sounds(BlockSoundGroup.WOOD).nonOpaque().build()) {
companion object { companion object {
val ID = Identifier("extrahoppers", "wood_hopper") val ID = Identifier("extrahoppers", "wood_hopper")
@ -83,28 +85,28 @@ class WoodHopperBlock: BlockWithEntity<WoodHopperBlockEntity>(Settings.of(Materi
} }
override fun onUse(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hitResult: BlockHitResult): ActionResult { override fun onUse(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hitResult: BlockHitResult): ActionResult {
// todo: container if (!world.isClient) {
return super.onUse(state, world, pos, player, hand, hitResult) player.incrementStat(Stats.INSPECT_HOPPER)
ContainerProviderRegistry.INSTANCE.openContainer(WoodHopperContainer.ID, player) { buf ->
buf.writeBlockPos(pos)
}
}
return ActionResult.SUCCESS
} }
override fun onBlockRemoved(oldState: BlockState, world: World, pos: BlockPos, newState: BlockState, bl: Boolean) { override fun onBlockRemoved(oldState: BlockState, world: World, pos: BlockPos, newState: BlockState, bl: Boolean) {
if (oldState.block != newState.block) { if (oldState.block != newState.block) {
getBlockEntity(world, pos)?.also { getBlockEntity(world, pos)?.also {
// todo: spawn items ItemScatterer.spawn(world, pos, it)
// ItemScatterer.spawn(world, pos, it)
world.updateHorizontalAdjacent(pos, this) world.updateHorizontalAdjacent(pos, this)
} }
super.onBlockRemoved(oldState, world, pos, newState, bl)
} }
super.onBlockRemoved(oldState, world, pos, newState, bl)
}
override fun getRenderType(blockState: BlockState?): BlockRenderType {
return BlockRenderType.MODEL
} }
override fun onEntityCollision(state: BlockState, world: World, pos: BlockPos, entity: Entity) { override fun onEntityCollision(state: BlockState, world: World, pos: BlockPos, entity: Entity) {
getBlockEntity(world, pos)?.also { getBlockEntity(world, pos)?.also {
// todo: handle entity collision it.onEntityCollision(entity)
} }
} }

View File

@ -3,15 +3,19 @@ package net.shadowfacts.extrahoppers.block.wood
import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.BlockEntity
import net.minecraft.block.entity.Hopper import net.minecraft.block.entity.Hopper
import net.minecraft.block.entity.HopperBlockEntity import net.minecraft.block.entity.HopperBlockEntity
import net.minecraft.entity.Entity
import net.minecraft.entity.ItemEntity
import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerEntity
import net.minecraft.inventory.Inventories import net.minecraft.inventory.Inventories
import net.minecraft.inventory.Inventory import net.minecraft.inventory.Inventory
import net.minecraft.inventory.SidedInventory import net.minecraft.inventory.SidedInventory
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
import net.minecraft.util.BooleanBiFunction
import net.minecraft.util.DefaultedList import net.minecraft.util.DefaultedList
import net.minecraft.util.Tickable import net.minecraft.util.Tickable
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
import net.minecraft.util.shape.VoxelShapes
import net.shadowfacts.extrahoppers.init.EHBlockEntities import net.shadowfacts.extrahoppers.init.EHBlockEntities
import net.shadowfacts.extrahoppers.util.toVec3d import net.shadowfacts.extrahoppers.util.toVec3d
@ -50,7 +54,15 @@ class WoodHopperBlockEntity: BlockEntity(EHBlockEntities.WOOD_HOPPER), Inventory
} }
} }
fun insertAndExtract() { fun onEntityCollision(entity: Entity) {
if (entity is ItemEntity) {
if (VoxelShapes.matchesAnywhere(VoxelShapes.cuboid(entity.boundingBox.offset(-pos.x.toDouble(), -pos.y.toDouble(), -pos.z.toDouble())), inputAreaShape, BooleanBiFunction.AND)) {
insertAndExtract()
}
}
}
fun insertAndExtract(extractor: (() -> Boolean)? = null) {
val world = world val world = world
if (world == null || world.isClient) return if (world == null || world.isClient) return
@ -58,7 +70,7 @@ class WoodHopperBlockEntity: BlockEntity(EHBlockEntities.WOOD_HOPPER), Inventory
if (!isInvEmpty && insert()) { if (!isInvEmpty && insert()) {
didWork = true didWork = true
} }
if (!isFull() && HopperBlockEntity.extract(this)) { if (!isFull() && ((extractor != null && extractor()) || HopperBlockEntity.extract(this))) {
didWork = true didWork = true
} }

View File

@ -0,0 +1,74 @@
package net.shadowfacts.extrahoppers.block.wood
import net.minecraft.container.Container
import net.minecraft.container.Slot
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.inventory.Inventory
import net.minecraft.item.ItemStack
import net.minecraft.util.Identifier
import net.minecraft.util.PacketByteBuf
import net.shadowfacts.extrahoppers.init.EHBlocks
class WoodHopperContainer(syncId: Int, playerInv: PlayerInventory, val hopperInv: Inventory): Container(null, syncId) {
companion object {
val ID = Identifier("extrahoppers", "wood_hopper")
fun create(syncId: Int, identifier: Identifier, player: PlayerEntity, buf: PacketByteBuf): WoodHopperContainer {
val pos = buf.readBlockPos()
val blockEntity = EHBlocks.WOOD_HOPPER.getBlockEntity(player.world, pos)!!
return WoodHopperContainer(syncId, player.inventory, blockEntity)
}
}
init {
addSlot(Slot(hopperInv, 0, 80, 20))
// player inv
for (y in 0 until 3) {
for (x in 0 until 9) {
addSlot(Slot(playerInv, x + y * 9 + 9, 8 + x * 18, 51 + y * 18))
}
}
// hotbar
for (x in 0 until 9) {
addSlot(Slot(playerInv, x, 8 + x * 18, 109))
}
}
override fun canUse(player: PlayerEntity): Boolean {
return true
}
override fun close(player: PlayerEntity) {
super.close(player)
hopperInv.onInvClose(player)
}
override fun transferSlot(player: PlayerEntity, slotIndex: Int): ItemStack {
var remaining = ItemStack.EMPTY
val slot = slots[slotIndex]
if (slot != null && slot.hasStack()) {
val slotStack = slot.stack
remaining = slotStack.copy()
if (slotIndex < hopperInv.invSize) {
if (!insertItem(slotStack, hopperInv.invSize, slots.size, true)) {
return ItemStack.EMPTY;
}
} else if (!insertItem(slotStack, 0, hopperInv.invSize, false)) {
return ItemStack.EMPTY;
}
if (slotStack.isEmpty) {
slot.stack = ItemStack.EMPTY;
} else {
slot.markDirty()
}
}
return remaining
}
}

View File

@ -0,0 +1,37 @@
package net.shadowfacts.extrahoppers.block.wood
import com.mojang.blaze3d.platform.GlStateManager
import net.minecraft.client.MinecraftClient
import net.minecraft.client.gui.screen.ingame.ContainerScreen
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.text.LiteralText
import net.minecraft.util.Identifier
class WoodHopperScreen(container: WoodHopperContainer, playerInv: PlayerInventory): ContainerScreen<WoodHopperContainer>(container, playerInv, LiteralText("Wooden Hopper")) {
companion object {
val BACKGROUND = Identifier("extrahoppers", "textures/gui/wood_hopper.png")
fun create(container: WoodHopperContainer): WoodHopperScreen {
return WoodHopperScreen(container, MinecraftClient.getInstance().player!!.inventory)
}
}
init {
containerHeight = 133
}
override fun drawForeground(mouseX: Int, mouseY: Int) {
font.draw(title.asFormattedString(), 8f, 6f, 0x404040)
font.draw(playerInventory.displayName.asFormattedString(), 8f, containerHeight - 94f, 0x404040)
}
override fun drawBackground(f: Float, i: Int, j: Int) {
GlStateManager.color4f(1f, 1f, 1f, 1f)
minecraft!!.textureManager.bindTexture(BACKGROUND)
val x = (width - containerWidth) / 2
val y = (height - containerHeight) / 2
blit(x, y, 0, 0, containerWidth, containerHeight)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -0,0 +1,35 @@
{
"parent": "minecraft:recipes/root",
"rewards": {
"recipes": [
"extrahoppers:wood_hopper"
]
},
"criteria": {
"has_logs_and_chest": {
"trigger": "minecraft:inventory_changed",
"conditions": {
"items": [
{
"tag": "minecraft:logs"
},
{
"item": "minecraft:chest"
}
]
}
},
"has_the_recipe": {
"trigger": "minecraft:recipe_unlocked",
"conditions": {
"recipe": "extrahoppers:wood_hopper"
}
}
},
"requirements": [
[
"has_logs_and_chest",
"has_the_recipe"
]
]
}

View File

@ -0,0 +1,19 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "extrahoppers:wood_hopper"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@ -0,0 +1,19 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"L L",
"LCL",
" L "
],
"key": {
"C": {
"item": "minecraft:chest"
},
"L": {
"tag": "minecraft:logs"
}
},
"result": {
"item": "extrahoppers:wood_hopper"
}
}

View File

@ -9,6 +9,12 @@
"adapter": "kotlin", "adapter": "kotlin",
"value": "net.shadowfacts.extrahoppers.ExtraHoppers" "value": "net.shadowfacts.extrahoppers.ExtraHoppers"
} }
],
"client": [
{
"adapter": "kotlin",
"value": "net.shadowfacts.extrahoppers.ExtraHoppersClient"
}
] ]
}, },
"depends": { "depends": {