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
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.EHBlocks
import net.shadowfacts.extrahoppers.init.EHItems
@ -8,13 +11,11 @@ import net.shadowfacts.extrahoppers.init.EHItems
object ExtraHoppers: ModInitializer {
override fun onInitialize() {
println("--------------------")
println("hello from extra hoppers")
println("--------------------")
EHBlocks.init()
EHBlockEntities.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
import net.fabricmc.fabric.api.block.FabricBlockSettings
import net.fabricmc.fabric.api.container.ContainerProviderRegistry
import net.minecraft.block.*
import net.minecraft.block.entity.Hopper
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityContext
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.player.PlayerEntity
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.property.Properties
import net.minecraft.util.*
@ -23,7 +25,7 @@ import net.shadowfacts.extrahoppers.block.base.BlockWithEntity
/**
* @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 {
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 {
// todo: container
return super.onUse(state, world, pos, player, hand, hitResult)
if (!world.isClient) {
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) {
if (oldState.block != newState.block) {
getBlockEntity(world, pos)?.also {
// todo: spawn items
// ItemScatterer.spawn(world, pos, it)
ItemScatterer.spawn(world, pos, it)
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) {
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.Hopper
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.inventory.Inventories
import net.minecraft.inventory.Inventory
import net.minecraft.inventory.SidedInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompoundTag
import net.minecraft.util.BooleanBiFunction
import net.minecraft.util.DefaultedList
import net.minecraft.util.Tickable
import net.minecraft.util.math.Direction
import net.minecraft.util.shape.VoxelShapes
import net.shadowfacts.extrahoppers.init.EHBlockEntities
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
if (world == null || world.isClient) return
@ -58,7 +70,7 @@ class WoodHopperBlockEntity: BlockEntity(EHBlockEntities.WOOD_HOPPER), Inventory
if (!isInvEmpty && insert()) {
didWork = true
}
if (!isFull() && HopperBlockEntity.extract(this)) {
if (!isFull() && ((extractor != null && extractor()) || HopperBlockEntity.extract(this))) {
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",
"value": "net.shadowfacts.extrahoppers.ExtraHoppers"
}
],
"client": [
{
"adapter": "kotlin",
"value": "net.shadowfacts.extrahoppers.ExtraHoppersClient"
}
]
},
"depends": {