Advanced hopper start and update to latest Forge

This commit is contained in:
Shadowfacts 2017-07-01 18:15:22 -04:00
parent b99726610f
commit a5545be406
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
40 changed files with 1043 additions and 475 deletions

View File

@ -54,7 +54,7 @@ repositories {
jcenter() jcenter()
maven { maven {
name "shadowfacts" name "shadowfacts"
url "http://mvn.rx14.co.uk/shadowfacts/" url "http://maven.shadowfacts.net/"
} }
maven { maven {
url "http://dvs1.progwml6.com/files/maven" url "http://dvs1.progwml6.com/files/maven"

View File

@ -3,11 +3,11 @@ group = net.shadowfacts
archivesBaseName = ExtraHoppers archivesBaseName = ExtraHoppers
mc_version = 1.12 mc_version = 1.12
mcp_mappings = snapshot_20170615 mcp_mappings = snapshot_20170701
forge_version = 14.21.0.2333 forge_version = 14.21.1.2387
kotlin_version = 1.1.2-4 kotlin_version = 1.1.2-4
shadowmc_version = 3.8.0-SNAPSHOT shadowmc_version = 3.8.1-SNAPSHOT
forgelin_version = 1.5.0 forgelin_version = 1.5.0
jei_version = 4.6.0.61 jei_version = 4.7.0.67

View File

@ -1,18 +1,23 @@
package net.shadowfacts.extrahoppers package net.shadowfacts.extrahoppers
import net.minecraft.block.Block
import net.minecraft.item.Item import net.minecraft.item.Item
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.event.RegistryEvent
import net.minecraftforge.fml.client.registry.ClientRegistry import net.minecraftforge.fml.client.registry.ClientRegistry
import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.Mod
import net.minecraftforge.fml.common.event.FMLMissingMappingsEvent
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent import net.minecraftforge.fml.common.event.FMLPreInitializationEvent
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import net.minecraftforge.fml.common.network.NetworkRegistry import net.minecraftforge.fml.common.network.NetworkRegistry
import net.minecraftforge.fml.common.registry.GameRegistry import net.minecraftforge.fml.common.registry.GameRegistry
import net.minecraftforge.fml.relauncher.Side import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly import net.minecraftforge.fml.relauncher.SideOnly
import net.shadowfacts.extrahoppers.block.ModBlocks import net.shadowfacts.extrahoppers.block.ModBlocks
import net.shadowfacts.extrahoppers.block.advanced.TileEntityAdvancedHopper
import net.shadowfacts.extrahoppers.block.fluid.TESRFluidHopper import net.shadowfacts.extrahoppers.block.fluid.TESRFluidHopper
import net.shadowfacts.extrahoppers.block.fluid.TileEntityFluidHopper import net.shadowfacts.extrahoppers.block.fluid.TileEntityFluidHopper
import net.shadowfacts.extrahoppers.block.inverted.TileEntityInvertedHopper
import net.shadowfacts.extrahoppers.block.wooden.TileEntityWoodenHopper
import net.shadowfacts.extrahoppers.block.wooden_fluid.TileEntityWoodenFluidHopper import net.shadowfacts.extrahoppers.block.wooden_fluid.TileEntityWoodenFluidHopper
import net.shadowfacts.extrahoppers.event.ClientEventHandler import net.shadowfacts.extrahoppers.event.ClientEventHandler
import net.shadowfacts.extrahoppers.gui.GUIHandler import net.shadowfacts.extrahoppers.gui.GUIHandler
@ -31,8 +36,6 @@ object ExtraHoppers {
EHConfig.init(event.modConfigurationDirectory) EHConfig.init(event.modConfigurationDirectory)
EHConfig.save() EHConfig.save()
blocks.init()
NetworkRegistry.INSTANCE.registerGuiHandler(ExtraHoppers, GUIHandler) NetworkRegistry.INSTANCE.registerGuiHandler(ExtraHoppers, GUIHandler)
} }
@ -45,17 +48,51 @@ object ExtraHoppers {
MinecraftForge.EVENT_BUS.register(ClientEventHandler) MinecraftForge.EVENT_BUS.register(ClientEventHandler)
} }
@Mod.EventHandler @Mod.EventBusSubscriber
fun missingMappings(event: FMLMissingMappingsEvent) { object RegistrationHandler {
event.get().forEach {
if (it.name == "funnels:funnel") { @JvmStatic
if (it.type == GameRegistry.Type.BLOCK) { @SubscribeEvent
it.remap(blocks.fluidHopper) fun registerBlocks(event: RegistryEvent.Register<Block>) {
} else { event.registry.registerAll(
it.remap(Item.getItemFromBlock(blocks.fluidHopper)) blocks.invertedHopper,
} blocks.fluidHopper,
} blocks.invertedFluidHopper,
blocks.advancedFluidHopper,
blocks.invertedAdvancedFluidHopper,
blocks.woodenHopper,
blocks.invertedWoodenHopper,
blocks.woodenFluidHopper,
blocks.invertedWoodenFluidHopper,
blocks.advancedHopper,
blocks.invertedAdvancedHopper
)
GameRegistry.registerTileEntity(TileEntityInvertedHopper::class.java, blocks.invertedHopper.registryName.toString())
GameRegistry.registerTileEntity(TileEntityFluidHopper::class.java, blocks.fluidHopper.registryName.toString())
GameRegistry.registerTileEntity(TileEntityWoodenHopper::class.java, blocks.woodenHopper.registryName.toString())
GameRegistry.registerTileEntity(TileEntityWoodenFluidHopper::class.java, blocks.woodenFluidHopper.registryName.toString())
GameRegistry.registerTileEntity(TileEntityAdvancedHopper::class.java, blocks.advancedHopper.registryName.toString())
} }
@JvmStatic
@SubscribeEvent
fun registerItems(event: RegistryEvent.Register<Item>) {
event.registry.registerAll(
blocks.invertedHopper.createItemBlock(),
blocks.fluidHopper.createItemBlock(),
blocks.invertedFluidHopper.createItemBlock(),
blocks.advancedFluidHopper.createItemBlock(),
blocks.invertedAdvancedFluidHopper.createItemBlock(),
blocks.woodenHopper.createItemBlock(),
blocks.invertedWoodenHopper.createItemBlock(),
blocks.woodenFluidHopper.createItemBlock(),
blocks.invertedWoodenFluidHopper.createItemBlock(),
blocks.advancedHopper.createItemBlock(),
blocks.invertedAdvancedHopper.createItemBlock()
)
}
} }
} }

View File

@ -1,42 +1,26 @@
package net.shadowfacts.extrahoppers.block package net.shadowfacts.extrahoppers.block
import net.minecraftforge.fml.common.registry.GameRegistry import net.shadowfacts.extrahoppers.block.advanced.BlockAdvancedHopper
import net.shadowfacts.extrahoppers.block.fluid.BlockFluidHopper import net.shadowfacts.extrahoppers.block.fluid.BlockFluidHopper
import net.shadowfacts.extrahoppers.block.fluid.TileEntityFluidHopper
import net.shadowfacts.extrahoppers.block.inverted.BlockInvertedHopper import net.shadowfacts.extrahoppers.block.inverted.BlockInvertedHopper
import net.shadowfacts.extrahoppers.block.inverted.TileEntityInvertedHopper
import net.shadowfacts.extrahoppers.block.wooden.BlockWoodenHopper import net.shadowfacts.extrahoppers.block.wooden.BlockWoodenHopper
import net.shadowfacts.extrahoppers.block.wooden.TileEntityWoodenHopper
import net.shadowfacts.extrahoppers.block.wooden_fluid.BlockWoodenFluidHopper import net.shadowfacts.extrahoppers.block.wooden_fluid.BlockWoodenFluidHopper
import net.shadowfacts.extrahoppers.block.wooden_fluid.TileEntityWoodenFluidHopper
import net.shadowfacts.shadowmc.block.ModBlocks
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
object ModBlocks: ModBlocks() { object ModBlocks {
val invertedHopper = BlockInvertedHopper() val invertedHopper = BlockInvertedHopper()
val fluidHopper = BlockFluidHopper(false) val fluidHopper = BlockFluidHopper(false, false)
val invertedFluidHopper = BlockFluidHopper(true) val invertedFluidHopper = BlockFluidHopper(true, false)
val advancedFluidHopper = BlockFluidHopper(false, true)
val invertedAdvancedFluidHopper = BlockFluidHopper(true, true)
val woodenHopper = BlockWoodenHopper(false) val woodenHopper = BlockWoodenHopper(false)
val invertedWoodenHopper = BlockWoodenHopper(true) val invertedWoodenHopper = BlockWoodenHopper(true)
val woodenFluidHopper = BlockWoodenFluidHopper(false) val woodenFluidHopper = BlockWoodenFluidHopper(false)
val invertedWoodenFluidHopper = BlockWoodenFluidHopper(true) val invertedWoodenFluidHopper = BlockWoodenFluidHopper(true)
val advancedHopper = BlockAdvancedHopper(false)
override fun init() { val invertedAdvancedHopper = BlockAdvancedHopper(true)
register(invertedHopper)
register(fluidHopper)
register(invertedFluidHopper)
register(woodenHopper)
register(invertedWoodenHopper)
register(woodenFluidHopper)
register(invertedWoodenFluidHopper)
GameRegistry.registerTileEntity(TileEntityInvertedHopper::class.java, invertedHopper.registryName.toString())
GameRegistry.registerTileEntityWithAlternatives(TileEntityFluidHopper::class.java, fluidHopper.registryName.toString(), "funnels:funnel")
GameRegistry.registerTileEntity(TileEntityWoodenHopper::class.java, woodenHopper.registryName.toString())
GameRegistry.registerTileEntity(TileEntityWoodenFluidHopper::class.java, woodenFluidHopper.registryName.toString())
}
} }

View File

@ -0,0 +1,45 @@
package net.shadowfacts.extrahoppers.block.advanced
import net.minecraft.block.SoundType
import net.minecraft.block.state.IBlockState
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.util.EnumFacing
import net.minecraft.util.EnumHand
import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
import net.minecraftforge.items.ItemHandlerHelper
import net.shadowfacts.extrahoppers.ExtraHoppers
import net.shadowfacts.extrahoppers.block.base.BlockHopperBase
import net.shadowfacts.extrahoppers.gui.GUIHandler
/**
* @author shadowfacts
*/
class BlockAdvancedHopper(inverted: Boolean): BlockHopperBase<TileEntityAdvancedHopper>(inverted, true, "hopper") {
init {
setHardness(3.5f)
setResistance(8f)
soundType = SoundType.METAL
}
@Deprecated("")
override fun hasComparatorInputOverride(state: IBlockState?): Boolean {
return true
}
@Deprecated("")
override fun getComparatorInputOverride(state: IBlockState, world: World, pos: BlockPos): Int {
return ItemHandlerHelper.calcRedstoneFromInventory(getTileEntity(world, pos).inventory)
}
override fun onBlockActivated(world: World, pos: BlockPos, state: IBlockState, player: EntityPlayer, hand: EnumHand, facing: EnumFacing, hitX: Float, hitY: Float, hitZ: Float): Boolean {
player.openGui(ExtraHoppers, GUIHandler.ADVANCED_HOPPER, world, pos.x, pos.y, pos.z)
return true
}
override fun createTileEntity(world: World, state: IBlockState): TileEntityAdvancedHopper {
return TileEntityAdvancedHopper(inverted)
}
}

View File

@ -0,0 +1,17 @@
package net.shadowfacts.extrahoppers.block.advanced
import net.minecraft.item.ItemStack
import net.shadowfacts.extrahoppers.block.inventory.TileEntityInventoryHopper
import net.shadowfacts.extrahoppers.util.filter.Filter
import net.shadowfacts.extrahoppers.util.filter.ItemFilter
/**
* @author shadowfacts
*/
class TileEntityAdvancedHopper(inverted: Boolean): TileEntityInventoryHopper(inverted, true, 5) {
override var filter: Filter<ItemStack> = ItemFilter(6)
constructor(): this(false)
}

View File

@ -18,7 +18,7 @@ import net.shadowfacts.shadowmc.tileentity.BaseTileEntity
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
abstract class BlockHopperBase<out TE: BaseTileEntity>(val inverted: Boolean, name: String, material: Material = Material.ROCK): BlockTE<TE>(if (inverted) "inverted_$name" else name, material = material) { abstract class BlockHopperBase<out TE: BaseTileEntity>(val inverted: Boolean, val advanced: Boolean, name: String, material: Material = Material.ROCK): BlockTE<TE>(getName(inverted, advanced, name), material = material) {
companion object { companion object {
val FACING: PropertyDirection = PropertyDirection.create("facing") val FACING: PropertyDirection = PropertyDirection.create("facing")
@ -28,6 +28,13 @@ abstract class BlockHopperBase<out TE: BaseTileEntity>(val inverted: Boolean, na
val NORTH_AABB = AxisAlignedBB(0.0, 0.0, 0.875, 1.0, 1.0, 1.0) val NORTH_AABB = AxisAlignedBB(0.0, 0.0, 0.875, 1.0, 1.0, 1.0)
val WEST_AABB = AxisAlignedBB(0.875, 0.0, 0.0, 1.0, 1.0, 1.0) val WEST_AABB = AxisAlignedBB(0.875, 0.0, 0.0, 1.0, 1.0, 1.0)
val EAST_AABB = AxisAlignedBB(0.0, 0.0, 0.0, 0.125, 1.0, 1.0) val EAST_AABB = AxisAlignedBB(0.0, 0.0, 0.0, 0.125, 1.0, 1.0)
private fun getName(inverted: Boolean, advanced: Boolean, name: String): String {
var name = name
if (advanced) name = "advanced_$name"
if (inverted) name = "inverted_$name"
return name
}
} }
init { init {

View File

@ -1,37 +0,0 @@
package net.shadowfacts.extrahoppers.block.base
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.inventory.Slot
import net.minecraft.util.math.BlockPos
import net.minecraftforge.items.SlotItemHandler
import net.shadowfacts.extrahoppers.block.inverted.TileEntityInvertedHopper
import net.shadowfacts.shadowmc.inventory.ContainerBase
/**
* @author shadowfacts
*/
class ContainerInvertedHopper(hopper: TileEntityInvertedHopper, playerInv: InventoryPlayer, pos: BlockPos): ContainerBase(pos) {
init {
for (i in 0.until(hopper.inventory.slots)) {
addSlotToContainer(SlotHopper(hopper, i, 44 + i * 18, 21))
}
for (l in 0..2) {
for (k in 0..8) {
addSlotToContainer(Slot(playerInv, k + l * 9 + 9, 8 + k * 18, l * 18 + 52))
}
}
for (i1 in 0..8) {
addSlotToContainer(Slot(playerInv, i1, 8 + i1 * 18, 110))
}
}
private class SlotHopper(val hopper: TileEntityInvertedHopper, index: Int, x: Int, y: Int): SlotItemHandler(hopper.inventory, index, x, y) {
override fun onSlotChanged() {
hopper.markDirty()
}
}
}

View File

@ -2,30 +2,76 @@ package net.shadowfacts.extrahoppers.block.base
import net.minecraft.nbt.NBTTagCompound import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing import net.minecraft.util.EnumFacing
import net.shadowfacts.extrahoppers.util.filter.Filter
import net.shadowfacts.extrahoppers.util.filter.FilterMode
import net.shadowfacts.shadowmc.ShadowMC
import net.shadowfacts.shadowmc.network.PacketRequestTEUpdate
import net.shadowfacts.shadowmc.tileentity.BaseTileEntity import net.shadowfacts.shadowmc.tileentity.BaseTileEntity
import net.shadowfacts.shadowmc.util.RedstoneMode
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
abstract class TileEntityHopperBase(var inverted: Boolean): BaseTileEntity() { abstract class TileEntityHopperBase<T>(var inverted: Boolean, var advanced: Boolean): BaseTileEntity() {
constructor(): this(false) var mode = RedstoneMode.LOW
private var prevPowered = false
fun isPowered(): Boolean { var filterMode = FilterMode.WHITELIST
return world.isBlockPowered(pos) abstract var filter: Filter<T>
constructor(): this(false, false)
override fun onLoad() {
if (world.isRemote) {
ShadowMC.network.sendToServer(PacketRequestTEUpdate(this))
}
}
protected open fun checkRedstone(): Boolean {
val powered = world.isBlockPowered(pos)
if (advanced) {
val res = when (mode) {
RedstoneMode.LOW -> !powered
RedstoneMode.HIGH -> powered
RedstoneMode.PULSE -> !prevPowered && powered
RedstoneMode.NEVER -> false
else -> true
}
prevPowered = powered
return res
} else {
return !powered
}
} }
fun getHopperFacing(): EnumFacing { fun getHopperFacing(): EnumFacing {
return world.getBlockState(pos).getValue(BlockHopperBase.FACING) return world.getBlockState(pos).getValue(BlockHopperBase.FACING)
} }
fun filterAccepts(it: T): Boolean {
if (!advanced) return true
return when (filterMode) {
FilterMode.WHITELIST -> filter.accepts(it)
FilterMode.BLACKLIST -> !filter.accepts(it)
}
}
override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound { override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound {
tag.setBoolean("inverted", inverted) tag.setBoolean("inverted", inverted)
tag.setBoolean("advanced", advanced)
tag.setString("mode", mode.name)
tag.setString("filterMode", filterMode.name)
filter.writeToNBT(tag)
return super.writeToNBT(tag) return super.writeToNBT(tag)
} }
override fun readFromNBT(tag: NBTTagCompound) { override fun readFromNBT(tag: NBTTagCompound) {
inverted = tag.getBoolean("inverted") inverted = tag.getBoolean("inverted")
advanced = tag.getBoolean("advanced")
if (tag.hasKey("mode")) mode = RedstoneMode.valueOf(tag.getString("mode"))
if (tag.hasKey("filterMode")) filterMode = FilterMode.valueOf(tag.getString("filterMode"))
filter.readFromNBT(tag)
super.readFromNBT(tag) super.readFromNBT(tag)
} }

View File

@ -21,7 +21,7 @@ import net.shadowfacts.extrahoppers.gui.GUIHandler
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
open class BlockFluidHopper(inverted: Boolean, name: String = "fluid_hopper", material: Material = Material.IRON): BlockHopperBase<TileEntityFluidHopper>(inverted, name, material = material) { open class BlockFluidHopper(inverted: Boolean, advanced: Boolean, name: String = "fluid_hopper", material: Material = Material.IRON): BlockHopperBase<TileEntityFluidHopper>(inverted, advanced, name, material = material) {
init { init {
setHardness(3.5f) setHardness(3.5f)
@ -35,7 +35,7 @@ open class BlockFluidHopper(inverted: Boolean, name: String = "fluid_hopper", ma
} }
@Deprecated("") @Deprecated("")
override fun getComparatorInputOverride(blockState: IBlockState, world: World, pos: BlockPos): Int { override fun getComparatorInputOverride(state: IBlockState, world: World, pos: BlockPos): Int {
val tank = getTileEntity(world, pos).tank val tank = getTileEntity(world, pos).tank
if (tank.fluidAmount == 0) { if (tank.fluidAmount == 0) {
return 0 return 0
@ -57,11 +57,13 @@ open class BlockFluidHopper(inverted: Boolean, name: String = "fluid_hopper", ma
} }
override fun addInformation(stack: ItemStack, world: World?, tooltip: MutableList<String>, flag: ITooltipFlag) { override fun addInformation(stack: ItemStack, world: World?, tooltip: MutableList<String>, flag: ITooltipFlag) {
if (!advanced) {
tooltip.add(I18n.format("tile.extrahoppers:fluid_hopper.tooltip")) tooltip.add(I18n.format("tile.extrahoppers:fluid_hopper.tooltip"))
} }
}
override fun createTileEntity(world: World, state: IBlockState): TileEntityFluidHopper { override fun createTileEntity(world: World, state: IBlockState): TileEntityFluidHopper {
return TileEntityFluidHopper(inverted) return TileEntityFluidHopper(inverted, advanced)
} }
} }

View File

@ -4,6 +4,7 @@ import net.minecraft.client.gui.inventory.GuiContainer
import net.minecraft.inventory.Container import net.minecraft.inventory.Container
import net.minecraft.util.ResourceLocation import net.minecraft.util.ResourceLocation
import net.shadowfacts.extrahoppers.MOD_ID import net.shadowfacts.extrahoppers.MOD_ID
import net.shadowfacts.extrahoppers.gui.element.UIFilterButton
import net.shadowfacts.extrahoppers.gui.element.UIFluidIndicator import net.shadowfacts.extrahoppers.gui.element.UIFluidIndicator
import net.shadowfacts.shadowmc.ui.dsl.container import net.shadowfacts.shadowmc.ui.dsl.container
@ -34,6 +35,21 @@ object GUIFluidHopper {
height = 166 / 2 height = 166 / 2
add(UIFluidIndicator(hopper.tank, "fluidIndicator")) add(UIFluidIndicator(hopper.tank, "fluidIndicator"))
if (hopper.advanced) {
buttonRedstoneMode {
id = "mode"
mode = hopper.mode
callback = {
hopper.mode = it
hopper.sync()
}
}
add(UIFilterButton({
// TODO
}, "filter"))
}
} }
} }

View File

@ -15,7 +15,7 @@ import org.lwjgl.opengl.GL11
*/ */
object TESRFluidHopper: TileEntitySpecialRenderer<TileEntityFluidHopper>() { object TESRFluidHopper: TileEntitySpecialRenderer<TileEntityFluidHopper>() {
override fun renderTileEntityAt(te: TileEntityFluidHopper, x: Double, y: Double, z: Double, partialTicks: Float, destroyStage: Int, alpha: Float) { override fun render(te: TileEntityFluidHopper, x: Double, y: Double, z: Double, partialTicks: Float, destroyStage: Int, alpha: Float) {
val pos = if (te.inverted) te.pos.down() else te.pos.up() val pos = if (te.inverted) te.pos.down() else te.pos.up()
if (te.tank.fluid != null && !te.world.getBlockState(pos).isSideSolid(te.world, pos, EnumFacing.DOWN)) { if (te.tank.fluid != null && !te.world.getBlockState(pos).isSideSolid(te.world, pos, EnumFacing.DOWN)) {

View File

@ -13,6 +13,8 @@ import net.minecraftforge.fml.common.network.NetworkRegistry
import net.shadowfacts.extrahoppers.EHConfig import net.shadowfacts.extrahoppers.EHConfig
import net.shadowfacts.extrahoppers.block.base.TileEntityHopperBase import net.shadowfacts.extrahoppers.block.base.TileEntityHopperBase
import net.shadowfacts.extrahoppers.util.FluidUtils import net.shadowfacts.extrahoppers.util.FluidUtils
import net.shadowfacts.extrahoppers.util.filter.Filter
import net.shadowfacts.extrahoppers.util.filter.FluidFilter
import net.shadowfacts.shadowmc.ShadowMC import net.shadowfacts.shadowmc.ShadowMC
import net.shadowfacts.shadowmc.network.PacketRequestTEUpdate import net.shadowfacts.shadowmc.network.PacketRequestTEUpdate
import net.shadowfacts.shadowmc.network.PacketUpdateTE import net.shadowfacts.shadowmc.network.PacketUpdateTE
@ -20,21 +22,24 @@ import net.shadowfacts.shadowmc.network.PacketUpdateTE
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
open class TileEntityFluidHopper(inverted: Boolean): TileEntityHopperBase(inverted), ITickable { open class TileEntityFluidHopper(inverted: Boolean, advanced: Boolean): TileEntityHopperBase<FluidStack>(inverted, advanced), ITickable {
constructor(): this(false)
companion object { companion object {
val HANDLER_COOLDOWN = 8 val HANDLER_COOLDOWN = 8
val WORLD_COOLDOWN = 40 val WORLD_COOLDOWN = 40
} }
override var filter: Filter<FluidStack> = FluidFilter(6)
constructor(): this(false, false)
internal var tank = object: FluidTank(EHConfig.fhSize) { internal var tank = object: FluidTank(EHConfig.fhSize) {
override fun onContentsChanged() { override fun onContentsChanged() {
save() save()
} }
override fun canFillFluidType(fluid: FluidStack?): Boolean { override fun canFillFluidType(fluid: FluidStack?): Boolean {
// return fluid == null || (fluidValiator(fluid) && filterAccepts(fluid))
return fluid == null || fluidValiator(fluid) return fluid == null || fluidValiator(fluid)
} }
} }
@ -57,14 +62,14 @@ open class TileEntityFluidHopper(inverted: Boolean): TileEntityHopperBase(invert
override fun update() { override fun update() {
if (!world.isRemote) { if (!world.isRemote) {
if (isPowered()) return
handlerCooldown-- handlerCooldown--
worldCooldown--
if (!checkRedstone()) return
if (handlerCooldown <= 0) { if (handlerCooldown <= 0) {
handleFluidHandlers() handleFluidHandlers()
} }
worldCooldown--
if (worldCooldown <= 0) { if (worldCooldown <= 0) {
handleWorld() handleWorld()
} }

View File

@ -0,0 +1,65 @@
package net.shadowfacts.extrahoppers.block.inventory
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.entity.player.InventoryPlayer
import net.minecraft.inventory.ClickType
import net.minecraft.inventory.Slot
import net.minecraft.item.ItemStack
import net.minecraft.util.math.BlockPos
import net.minecraftforge.items.SlotItemHandler
import net.shadowfacts.extrahoppers.util.SlotItemFilter
import net.shadowfacts.shadowmc.inventory.ContainerBase
/**
* @author shadowfacts
*/
class ContainerInventoryHopper(val hopper: TileEntityInventoryHopper, playerInv: InventoryPlayer, pos: BlockPos): ContainerBase(pos) {
init {
for (i in 0.until(hopper.inventory.slots)) {
addSlotToContainer(SlotHopper(hopper, i, 44 + i * 18, 21))
}
for (i in 0..2) {
addSlotToContainer(SlotItemFilter(hopper, i, -62 + i * 18, 12))
}
for (i in 0..2) {
addSlotToContainer(SlotItemFilter(hopper, i + 3, -62 + i * 18, 33))
}
for (l in 0..2) {
for (k in 0..8) {
addSlotToContainer(Slot(playerInv, k + l * 9 + 9, 8 + k * 18, l * 18 + 52))
}
}
for (i1 in 0..8) {
addSlotToContainer(Slot(playerInv, i1, 8 + i1 * 18, 110))
}
}
override fun slotClick(id: Int, dragType: Int, type: ClickType, player: EntityPlayer): ItemStack {
if (id in hopper.inventory.slots..hopper.inventory.slots + 5) {
if (type == ClickType.PICKUP || type == ClickType.PICKUP_ALL || type == ClickType.SWAP) {
hopper.filter.setFromStack(id - hopper.inventory.slots, player.inventory.itemStack)
hopper.markDirty()
}
return ItemStack.EMPTY
}
return super.slotClick(id, dragType, type, player)
}
override fun transferStackInSlot(player: EntityPlayer, index: Int): ItemStack {
if (index in hopper.inventory.slots..hopper.inventory.slots + 5) {
return ItemStack.EMPTY
}
return super.transferStackInSlot(player, index)
}
private class SlotHopper(val hopper: TileEntityInventoryHopper, index: Int, x: Int, y: Int): SlotItemHandler(hopper.inventory, index, x, y) {
override fun onSlotChanged() {
hopper.markDirty()
}
}
}

View File

@ -0,0 +1,80 @@
package net.shadowfacts.extrahoppers.block.inventory
import net.minecraft.inventory.Container
import net.minecraft.inventory.Slot
import net.minecraft.util.ResourceLocation
import net.shadowfacts.extrahoppers.MOD_ID
import net.shadowfacts.extrahoppers.gui.element.UIFilterButton
import net.shadowfacts.extrahoppers.util.filter.FilterMode
import net.shadowfacts.extrahoppers.util.filter.ItemFilter
import net.shadowfacts.shadowmc.ui.element.UIRect
import net.shadowfacts.shadowmc.ui.element.button.UIButtonEnum
import net.shadowfacts.shadowmc.ui.element.button.UIButtonRedstoneMode
import net.shadowfacts.shadowmc.ui.element.button.UIImage
import net.shadowfacts.shadowmc.ui.element.view.UIFixedView
import net.shadowfacts.shadowmc.ui.element.view.UIStackView
import net.shadowfacts.shadowmc.ui.mcwrapper.UIContainerWrapper
import net.shadowfacts.shadowmc.ui.style.UIAttribute
import net.shadowfacts.shadowmc.ui.style.UIHorizontalLayoutMode
import net.shadowfacts.shadowmc.ui.style.UIVerticalLayoutMode
import net.shadowfacts.shadowmc.ui.style.stylesheet.StylesheetParser
import java.util.function.Consumer
import java.util.function.Function
/**
* @author shadowfacts
*/
class GUIInventoryHopper(container: Container, tile: TileEntityInventoryHopper): UIContainerWrapper(container) {
private val BG = ResourceLocation("minecraft", "textures/gui/container/hopper.png")
private val FILTER_BG = ResourceLocation(MOD_ID, "textures/gui/filter.png")
init {
add(UIFixedView(176 + 83 * 2, 133, "root").apply {
add(UIImage(BG, 176, 133, "bg"))
if (tile.advanced) {
add(UIFixedView(176, 60, "top").apply {
add(UIFilterButton({
// TODO
}, "filter"))
add(UIButtonRedstoneMode(tile.mode, Consumer {
tile.mode = it
tile.sync()
}, "mode"))
})
add(UIFixedView(83, 86, "filter-container").apply {
add(UIImage(FILTER_BG, 83, 86, "filter-bg"))
// add(UIFixedView(52, 37, "filter-slots").apply {
// for (i in 0..2) {
// add(UIItemFilterSlot(tile, i, "filter-slot-$i", "filter-slot-top"))
// }
// for (i in 3..5) {
// add(UIItemFilterSlot(tile, i, "filter-slot-$i", "filter-slot-bottom"))
// }
// })
add(UIFixedView(83, 34, "filter-bottom").apply {
add(UIButtonEnum<FilterMode>(tile.filterMode, Function(FilterMode::localize), Consumer {
tile.filterMode = it.value
tile.sync()
}, "filter-mode"))
})
})
}
})
val style = StylesheetParser.load("$MOD_ID:inventory_hopper")
val sheet = StylesheetParser.parse(style)
children.forEach(sheet::style)
layout()
xSize = 176
ySize = 133
}
}

View File

@ -0,0 +1,207 @@
package net.shadowfacts.extrahoppers.block.inventory
import net.minecraft.entity.item.EntityItem
import net.minecraft.inventory.IInventory
import net.minecraft.inventory.ISidedInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
import net.minecraft.util.ITickable
import net.minecraft.util.math.AxisAlignedBB
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY
import net.minecraftforge.items.ItemStackHandler
import net.shadowfacts.extrahoppers.block.base.TileEntityHopperBase
import net.shadowfacts.extrahoppers.util.filter.Filter
import net.shadowfacts.extrahoppers.util.filter.ItemFilter
import net.shadowfacts.extrahoppers.util.insert
import net.shadowfacts.forgelin.extensions.get
import net.shadowfacts.forgelin.extensions.isEmpty
/**
* @author shadowfacts
*/
abstract class TileEntityInventoryHopper(inverted: Boolean, advanced: Boolean, size: Int): TileEntityHopperBase<ItemStack>(inverted, advanced), ITickable {
companion object {
val COOLDOWN = 8
}
val inventory = object: ItemStackHandler(size) {
override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack {
if (!filterAccepts(stack)) return stack
return super.insertItem(slot, stack, simulate)
}
}
var cooldown = COOLDOWN
val box by lazy {
if (inverted) {
AxisAlignedBB(pos.x - 0.5, pos.y - 1.5, pos.z - 0.5, pos.x + 0.5, pos.y.toDouble(), pos.z + 0.5)
} else {
AxisAlignedBB(pos.x - 0.5, pos.y.toDouble(), pos.z - 0.5, pos.x + 0.5, pos.y + 1.5, pos.z + 0.5)
}
}
override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound {
tag.setTag("inventory", inventory.serializeNBT())
return super.writeToNBT(tag)
}
override fun readFromNBT(tag: NBTTagCompound) {
inventory.deserializeNBT(tag.getCompoundTag("inventory"))
super.readFromNBT(tag)
}
override fun update() {
if (!world.isRemote) {
cooldown--
if (!checkRedstone()) return
if (cooldown <= 0) {
val pulled = pull()
val pushed = push()
if (pulled || pushed) {
cooldown = COOLDOWN
markDirty()
}
}
}
}
private fun push(): Boolean {
if (!inventory.isEmpty) {
val facing = getHopperFacing()
val tile = world.getTileEntity(pos.offset(facing))
if (tile is ISidedInventory) {
val slots = tile.getSlotsForFace(facing.opposite)
for (i in slots) {
for (slot in 0.until(inventory.slots)) {
if (inventory[slot].isEmpty) continue
val remainder = tile.insert(inventory.extractItem(slot, 1, true), i)
if (remainder.isEmpty) {
inventory.extractItem(slot, 1, false)
return true
}
}
}
} else if (tile is IInventory) {
for (i in 0.until(tile.sizeInventory)) {
for (slot in 0.until(inventory.slots)) {
if (inventory[slot].isEmpty) continue
val remainder = tile.insert(inventory.extractItem(slot, 1, true), i)
if (remainder.isEmpty) {
inventory.extractItem(slot, 1, false)
return true
}
}
}
} else if (tile != null && tile.hasCapability(ITEM_HANDLER_CAPABILITY, facing.opposite)) {
val handler = tile.getCapability(ITEM_HANDLER_CAPABILITY, facing.opposite)!!
for (i in 0.until(handler.slots)) {
for (slot in 0.until(inventory.slots)) {
if (inventory[slot].isEmpty) continue
val remainder = handler.insertItem(i, inventory.extractItem(slot, 1, true), false)
if (remainder.isEmpty) {
inventory.extractItem(slot, 1, false)
return true
}
}
}
}
}
return false
}
private fun pull(): Boolean {
val items = world.getEntitiesWithinAABB(EntityItem::class.java, box)
for (item in items) {
for (slot in 0.until(inventory.slots)) {
val result = inventory.insertItem(slot, item.item, true)
if (result.count != item.item.count) {
inventory.insertItem(slot, item.item, false)
if (result.isEmpty) {
item.setDead()
} else {
item.item = result
}
return true
}
}
}
// val facing = getHopperFacing()
val side = if (inverted) EnumFacing.DOWN else EnumFacing.UP
val tile = world.getTileEntity(pos.offset(side))
if (tile is ISidedInventory) {
val slots = tile.getSlotsForFace(side.opposite)
for (i in slots) {
for (slot in 0.until(inventory.slots)) {
val current = tile[i]
if (!current.isEmpty) {
val copy = current.copy()
copy.count = 1
val remainder = inventory.insertItem(slot, copy, false)
if (remainder.isEmpty) {
current.shrink(1)
return true
}
}
}
}
} else if (tile is IInventory) {
for (i in 0.until(tile.sizeInventory)) {
for (slot in 0.until(inventory.slots)) {
val current = tile[i]
if (!current.isEmpty) {
val copy = current.copy()
copy.count = 1
val remainder = inventory.insertItem(slot, copy, false)
if (remainder.isEmpty) {
current.shrink(1)
return true
}
}
}
}
} else if (tile != null && tile.hasCapability(ITEM_HANDLER_CAPABILITY, side.opposite)) {
val handler = tile.getCapability(ITEM_HANDLER_CAPABILITY, side.opposite)!!
for (i in 0.until(handler.slots)) {
for (slot in 0.until(inventory.slots)) {
val remainder = inventory.insertItem(slot, handler.extractItem(i, 1, true), false)
if (remainder.isEmpty()) {
handler.extractItem(i, 1, false)
return true
}
}
}
}
return false
}
override fun hasCapability(capability: Capability<*>, facing: EnumFacing?): Boolean {
if (capability == ITEM_HANDLER_CAPABILITY) {
val side = if (inverted) EnumFacing.DOWN else EnumFacing.UP
return facing == side || facing == getHopperFacing()
}
return super.hasCapability(capability, facing)
}
override fun <T: Any?> getCapability(capability: Capability<T>, facing: EnumFacing?): T? {
if (capability == ITEM_HANDLER_CAPABILITY) {
val side = if (inverted) EnumFacing.DOWN else EnumFacing.UP
if (facing == side || facing == getHopperFacing()) {
return inventory as T
}
}
return super.getCapability(capability, facing)
}
}

View File

@ -16,7 +16,7 @@ import net.shadowfacts.extrahoppers.gui.GUIHandler
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class BlockInvertedHopper: BlockHopperBase<TileEntityInvertedHopper>(true, "hopper", Material.IRON) { class BlockInvertedHopper: BlockHopperBase<TileEntityInvertedHopper>(true, false, "hopper", Material.IRON) {
init { init {
setHardness(3.5f) setHardness(3.5f)
@ -30,7 +30,7 @@ class BlockInvertedHopper: BlockHopperBase<TileEntityInvertedHopper>(true, "hopp
} }
@Deprecated("") @Deprecated("")
override fun getComparatorInputOverride(blockState: IBlockState, world: World, pos: BlockPos): Int { override fun getComparatorInputOverride(state: IBlockState, world: World, pos: BlockPos): Int {
return ItemHandlerHelper.calcRedstoneFromInventory(getTileEntity(world, pos).inventory) return ItemHandlerHelper.calcRedstoneFromInventory(getTileEntity(world, pos).inventory)
} }

View File

@ -1,26 +0,0 @@
package net.shadowfacts.extrahoppers.block.inverted
import net.minecraft.inventory.Container
import net.minecraft.util.ResourceLocation
import net.shadowfacts.shadowmc.ui.element.button.UIImage
import net.shadowfacts.shadowmc.ui.element.view.UIFixedView
import net.shadowfacts.shadowmc.ui.mcwrapper.UIContainerWrapper
/**
* @author shadowfacts
*/
class GUIInvertedHopper(container: Container): UIContainerWrapper(container) {
private val BG = ResourceLocation("minecraft", "textures/gui/container/hopper.png")
init {
add(UIFixedView(176, 133, "root").apply {
add(UIImage(BG, 176, 133, "bg"))
})
layout()
xSize = 176
ySize = 133
}
}

View File

@ -1,184 +1,15 @@
package net.shadowfacts.extrahoppers.block.inverted package net.shadowfacts.extrahoppers.block.inverted
import net.minecraft.entity.item.EntityItem import net.minecraft.item.ItemStack
import net.minecraft.inventory.IInventory import net.shadowfacts.extrahoppers.block.inventory.TileEntityInventoryHopper
import net.minecraft.inventory.ISidedInventory import net.shadowfacts.extrahoppers.util.filter.Filter
import net.minecraft.nbt.NBTTagCompound import net.shadowfacts.extrahoppers.util.filter.NoOpFilter
import net.minecraft.util.EnumFacing
import net.minecraft.util.ITickable
import net.minecraft.util.math.AxisAlignedBB
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY
import net.minecraftforge.items.ItemStackHandler
import net.shadowfacts.extrahoppers.block.base.TileEntityHopperBase
import net.shadowfacts.extrahoppers.util.insert
import net.shadowfacts.forgelin.extensions.get
import net.shadowfacts.forgelin.extensions.isEmpty
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class TileEntityInvertedHopper: TileEntityHopperBase(true), ITickable { class TileEntityInvertedHopper: TileEntityInventoryHopper(true, false, 5) {
companion object { override var filter: Filter<ItemStack> = NoOpFilter
val COOLDOWN = 8
}
val inventory = ItemStackHandler(5)
var cooldown = COOLDOWN
override fun update() {
if (!world.isRemote) {
if (isPowered()) return
cooldown--
if (cooldown <= 0) {
val pulled = pull()
val pushed = push()
if (pulled || pushed) {
cooldown = COOLDOWN
markDirty()
}
}
}
}
private fun push(): Boolean {
if (!inventory.isEmpty) {
val facing = getHopperFacing()
val tile = world.getTileEntity(pos.offset(facing))
if (tile is ISidedInventory) {
val slots = tile.getSlotsForFace(facing.opposite)
for (i in slots) {
for (slot in 0.until(inventory.slots)) {
val remainder = tile.insert(inventory.extractItem(slot, 1, true), i)
if (remainder.isEmpty) {
inventory.extractItem(slot, 1, false)
return true
}
}
}
} else if (tile is IInventory) {
for (i in 0.until(tile.sizeInventory)) {
for (slot in 0.until(inventory.slots)) {
val remainder = tile.insert(inventory.extractItem(slot, 1, true), i)
if (remainder.isEmpty) {
inventory.extractItem(slot, 1, false)
return true
}
}
}
} else if (tile != null && tile.hasCapability(ITEM_HANDLER_CAPABILITY, facing.opposite)) {
val handler = tile.getCapability(ITEM_HANDLER_CAPABILITY, facing.opposite)!!
for (i in 0.until(handler.slots)) {
for (slot in 0.until(inventory.slots)) {
val remainder = handler.insertItem(i, inventory.extractItem(slot, 1, true), false)
if (remainder.isEmpty) {
inventory.extractItem(slot, 1, false)
return true
}
}
}
}
}
return false
}
private fun pull(): Boolean {
val items = world.getEntitiesWithinAABB(EntityItem::class.java, AxisAlignedBB(pos.x.toDouble(), pos.y - 0.5, pos.z.toDouble(), pos.x + 1.0, pos.y + 0.5, pos.z + 1.0))
for (item in items) {
for (slot in 0.until(inventory.slots)) {
val result = inventory.insertItem(slot, item.item, true)
if (result.count != item.item.count) {
inventory.insertItem(slot, item.item, false)
if (result.isEmpty) {
item.setDead()
} else {
item.item = result
}
return true
}
}
}
val tile = world.getTileEntity(pos.down())
if (tile is ISidedInventory) {
val slots = tile.getSlotsForFace(EnumFacing.UP)
for (i in slots) {
for (slot in 0.until(inventory.slots)) {
val current = tile[i]
if (!current.isEmpty) {
val copy = current.copy()
copy.count = 1
val remainder = inventory.insertItem(slot, copy, false)
if (remainder.isEmpty) {
current.shrink(1)
return true
}
}
}
}
} else if (tile is IInventory) {
for (i in 0.until(tile.sizeInventory)) {
for (slot in 0.until(inventory.slots)) {
val current = tile[i]
if (!current.isEmpty) {
val copy = current.copy()
copy.count = 1
val remainder = inventory.insertItem(slot, copy, false)
if (remainder.isEmpty) {
current.shrink(1)
return true
}
}
}
}
} else if (tile != null && tile.hasCapability(ITEM_HANDLER_CAPABILITY, EnumFacing.UP)) {
val handler = tile.getCapability(ITEM_HANDLER_CAPABILITY, EnumFacing.UP)!!
for (i in 0.until(handler.slots)) {
for (slot in 0.until(inventory.slots)) {
val remainder = inventory.insertItem(slot, handler.extractItem(i, 1, true), false)
if (remainder.isEmpty) {
handler.extractItem(i, 1, false)
return true
}
}
}
}
return false
}
override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound {
tag.setTag("inventory", inventory.serializeNBT())
tag.setInteger("cooldown", cooldown)
return super.writeToNBT(tag)
}
override fun readFromNBT(tag: NBTTagCompound) {
inventory.deserializeNBT(tag.getCompoundTag("inventory"))
cooldown = tag.getInteger("cooldown")
super.readFromNBT(tag)
}
override fun hasCapability(capability: Capability<*>, facing: EnumFacing?): Boolean {
if (capability == ITEM_HANDLER_CAPABILITY) {
return facing == EnumFacing.DOWN || facing == getHopperFacing()
}
return super.hasCapability(capability, facing)
}
override fun <T: Any?> getCapability(capability: Capability<T>, facing: EnumFacing?): T? {
if (capability == ITEM_HANDLER_CAPABILITY) {
if (facing == EnumFacing.DOWN || facing == getHopperFacing()) {
return inventory as T
}
}
return super.getCapability(capability, facing)
}
} }

View File

@ -15,7 +15,7 @@ import net.shadowfacts.extrahoppers.gui.GUIHandler
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class BlockWoodenHopper(inverted: Boolean): BlockHopperBase<TileEntityWoodenHopper>(inverted, "wooden_hopper", Material.WOOD) { class BlockWoodenHopper(inverted: Boolean): BlockHopperBase<TileEntityWoodenHopper>(inverted, false, "wooden_hopper", Material.WOOD) {
init { init {
setHardness(1.5f) setHardness(1.5f)

View File

@ -1,173 +1,18 @@
package net.shadowfacts.extrahoppers.block.wooden package net.shadowfacts.extrahoppers.block.wooden
import net.minecraft.entity.item.EntityItem import net.minecraft.item.ItemStack
import net.minecraft.inventory.IInventory
import net.minecraft.inventory.ISidedInventory
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
import net.minecraft.util.ITickable import net.minecraft.util.ITickable
import net.minecraft.util.math.AxisAlignedBB import net.shadowfacts.extrahoppers.block.inventory.TileEntityInventoryHopper
import net.minecraftforge.common.capabilities.Capability import net.shadowfacts.extrahoppers.util.filter.Filter
import net.minecraftforge.items.CapabilityItemHandler.ITEM_HANDLER_CAPABILITY import net.shadowfacts.extrahoppers.util.filter.NoOpFilter
import net.minecraftforge.items.ItemStackHandler
import net.shadowfacts.extrahoppers.block.base.TileEntityHopperBase
import net.shadowfacts.extrahoppers.util.insert
import net.shadowfacts.forgelin.extensions.get
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class TileEntityWoodenHopper(inverted: Boolean): TileEntityHopperBase(inverted), ITickable { class TileEntityWoodenHopper(inverted: Boolean): TileEntityInventoryHopper(inverted, false, 1), ITickable {
companion object { override var filter: Filter<ItemStack> = NoOpFilter
val COOLDOWN = 24
}
val inventory = ItemStackHandler(1)
var cooldown = COOLDOWN
constructor(): this(false) constructor(): this(false)
override fun update() {
if (!world.isRemote) {
if (isPowered()) return
cooldown--
if (cooldown <= 0) {
val pulled = pull()
val pushed = push()
if (pulled || pushed) {
cooldown = COOLDOWN
markDirty()
}
}
}
}
private fun push(): Boolean {
if (!inventory[0].isEmpty) {
val facing = getHopperFacing()
val tile = world.getTileEntity(pos.offset(facing))
if (tile is ISidedInventory) {
val slots = tile.getSlotsForFace(facing.opposite)
for (i in slots) {
val remainder = tile.insert(inventory.extractItem(0, 1, true), i)
if (remainder.isEmpty) {
inventory.extractItem(0, 1, false)
return true
}
}
} else if (tile is IInventory) {
for (i in 0.until(tile.sizeInventory)) {
val remainder = tile.insert(inventory.extractItem(0, 1, true), i)
if (remainder.isEmpty) {
inventory.extractItem(0, 1, false)
return true
}
}
} else if (tile != null && tile.hasCapability(ITEM_HANDLER_CAPABILITY, facing.opposite)) {
val handler = tile.getCapability(ITEM_HANDLER_CAPABILITY, facing.opposite)!!
for (i in 0.until(handler.slots)) {
val remainder = handler.insertItem(i, inventory.extractItem(0, 1, true), false)
if (remainder.isEmpty) {
inventory.extractItem(0, 1, false)
return true
}
}
}
}
return false
}
private fun pull(): Boolean {
val yOffset = if (inverted) -1 else 0
val items = world.getEntitiesWithinAABB(EntityItem::class.java, AxisAlignedBB(pos.x.toDouble(), pos.y + 0.5 + yOffset, pos.z.toDouble(), pos.x + 1.0, pos.y + 1.5 + yOffset, pos.z + 1.0))
for (item in items) {
val result = inventory.insertItem(0, item.item, true)
if (result.count != item.item.count) {
inventory.insertItem(0, item.item, false)
if (result.isEmpty) {
item.setDead()
} else {
item.item = result
}
return true
}
}
val tile = world.getTileEntity(if (inverted) pos.down() else pos.up())
val side = if (inverted) EnumFacing.UP else EnumFacing.DOWN
if (tile is ISidedInventory) {
val slots = tile.getSlotsForFace(side)
for (i in slots) {
val current = tile[i]
if (!current.isEmpty) {
val copy = current.copy()
copy.count = 1
val remainder = inventory.insertItem(0, copy, false)
if (remainder.isEmpty) {
current.shrink(1)
return true
}
}
}
} else if (tile is IInventory) {
for (i in 0.until(tile.sizeInventory)) {
val current = tile[i]
if (!current.isEmpty) {
val copy = current.copy()
copy.count = 1
val remainder = inventory.insertItem(0, copy, false)
if (remainder.isEmpty) {
current.shrink(1)
return true
}
}
}
} else if (tile != null && tile.hasCapability(ITEM_HANDLER_CAPABILITY, side)) {
val handler = tile.getCapability(ITEM_HANDLER_CAPABILITY, side)!!
for (i in 0.until(handler.slots)) {
val remainder = inventory.insertItem(0, handler.extractItem(i, 1, true), false)
if (remainder.isEmpty) {
handler.extractItem(i, 1, false)
return true
}
}
}
return false
}
override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound {
tag.setTag("inventory", inventory.serializeNBT())
tag.setInteger("cooldown", cooldown)
return super.writeToNBT(tag)
}
override fun readFromNBT(tag: NBTTagCompound) {
inventory.deserializeNBT(tag.getCompoundTag("inventory"))
cooldown = tag.getInteger("cooldown")
super.readFromNBT(tag)
}
override fun hasCapability(capability: Capability<*>, facing: EnumFacing?): Boolean {
if (capability == ITEM_HANDLER_CAPABILITY) {
return facing == (if (inverted) EnumFacing.DOWN else EnumFacing.UP) || facing == getHopperFacing()
}
return super.hasCapability(capability, facing)
}
override fun <T: Any?> getCapability(capability: Capability<T>, facing: EnumFacing?): T? {
if (capability == ITEM_HANDLER_CAPABILITY) {
if (facing == (if (inverted) EnumFacing.DOWN else EnumFacing.UP) || facing == getHopperFacing()) {
return inventory as T
}
}
return super.getCapability(capability, facing)
}
} }

View File

@ -18,7 +18,7 @@ import net.shadowfacts.extrahoppers.gui.GUIHandler
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class BlockWoodenFluidHopper(inverted: Boolean): BlockFluidHopper(inverted, name = "wooden_fluid_hopper", material = Material.WOOD) { class BlockWoodenFluidHopper(inverted: Boolean): BlockFluidHopper(inverted, false, name = "wooden_fluid_hopper", material = Material.WOOD) {
init { init {
setHardness(1.5f) setHardness(1.5f)

View File

@ -3,14 +3,18 @@ package net.shadowfacts.extrahoppers.block.wooden_fluid
import net.minecraftforge.fluids.FluidStack import net.minecraftforge.fluids.FluidStack
import net.shadowfacts.extrahoppers.EHConfig import net.shadowfacts.extrahoppers.EHConfig
import net.shadowfacts.extrahoppers.block.fluid.TileEntityFluidHopper import net.shadowfacts.extrahoppers.block.fluid.TileEntityFluidHopper
import net.shadowfacts.extrahoppers.util.filter.Filter
import net.shadowfacts.extrahoppers.util.filter.NoOpFilter
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class TileEntityWoodenFluidHopper(inverted: Boolean): TileEntityFluidHopper(inverted) { class TileEntityWoodenFluidHopper(inverted: Boolean): TileEntityFluidHopper(inverted, false) {
constructor(): this(false) override var filter: Filter<FluidStack> = NoOpFilter
override val fluidValiator: (FluidStack) -> Boolean = { it.fluid.temperature <= EHConfig.wfhMaxTemperature } override val fluidValiator: (FluidStack) -> Boolean = { it.fluid.temperature <= EHConfig.wfhMaxTemperature }
constructor(): this(false)
} }

View File

@ -15,11 +15,6 @@ class EHGUIFactory: IModGuiFactory {
override fun createConfigGui(parentScreen: GuiScreen) = EHConfigGUI(parentScreen) override fun createConfigGui(parentScreen: GuiScreen) = EHConfigGUI(parentScreen)
@Deprecated("")
override fun mainConfigGuiClass() = EHConfigGUI::class.java
override fun runtimeGuiCategories() = null override fun runtimeGuiCategories() = null
override fun getHandlerFor(element: IModGuiFactory.RuntimeOptionCategoryElement) = null
} }

View File

@ -5,10 +5,11 @@ import net.minecraft.inventory.Container
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraftforge.fml.common.network.IGuiHandler import net.minecraftforge.fml.common.network.IGuiHandler
import net.shadowfacts.extrahoppers.block.base.ContainerInvertedHopper import net.shadowfacts.extrahoppers.block.inventory.ContainerInventoryHopper
import net.shadowfacts.extrahoppers.block.fluid.GUIFluidHopper import net.shadowfacts.extrahoppers.block.fluid.GUIFluidHopper
import net.shadowfacts.extrahoppers.block.fluid.TileEntityFluidHopper import net.shadowfacts.extrahoppers.block.fluid.TileEntityFluidHopper
import net.shadowfacts.extrahoppers.block.inverted.GUIInvertedHopper import net.shadowfacts.extrahoppers.block.inventory.GUIInventoryHopper
import net.shadowfacts.extrahoppers.block.inventory.TileEntityInventoryHopper
import net.shadowfacts.extrahoppers.block.inverted.TileEntityInvertedHopper import net.shadowfacts.extrahoppers.block.inverted.TileEntityInvertedHopper
import net.shadowfacts.extrahoppers.block.wooden.ContainerWoodenHopper import net.shadowfacts.extrahoppers.block.wooden.ContainerWoodenHopper
import net.shadowfacts.extrahoppers.block.wooden.GUIWoodenHopper import net.shadowfacts.extrahoppers.block.wooden.GUIWoodenHopper
@ -25,13 +26,14 @@ object GUIHandler: IGuiHandler {
val FLUID_HOPPER = 1 val FLUID_HOPPER = 1
val WOODEN_HOPPER = 2 val WOODEN_HOPPER = 2
val WOODEN_FLUID_HOPPER = 3 val WOODEN_FLUID_HOPPER = 3
val ADVANCED_HOPPER = 4
var woodenFluidHopperOpen = false var woodenFluidHopperOpen = false
override fun getClientGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): Any? { override fun getClientGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): Any? {
val pos = BlockPos(x, y, z) val pos = BlockPos(x, y, z)
return when (ID) { return when (ID) {
INVERTED_HOPPER -> GUIInvertedHopper(getServerGuiElement(ID, player, world, x, y, z)!!) INVERTED_HOPPER, ADVANCED_HOPPER -> GUIInventoryHopper(getServerGuiElement(ID, player, world, x, y, z)!!, world.getTileEntity(pos) as TileEntityInventoryHopper)
FLUID_HOPPER -> GUIFluidHopper.create(world.getTileEntity(pos) as TileEntityFluidHopper, getServerGuiElement(ID, player, world, x, y, z)!!) FLUID_HOPPER -> GUIFluidHopper.create(world.getTileEntity(pos) as TileEntityFluidHopper, getServerGuiElement(ID, player, world, x, y, z)!!)
WOODEN_HOPPER -> GUIWoodenHopper(getServerGuiElement(ID, player, world, x, y, z)!!) WOODEN_HOPPER -> GUIWoodenHopper(getServerGuiElement(ID, player, world, x, y, z)!!)
WOODEN_FLUID_HOPPER -> GUIWoodenFluidHopper.create(world.getTileEntity(pos) as TileEntityFluidHopper, getServerGuiElement(ID, player, world, x, y, z)!!) WOODEN_FLUID_HOPPER -> GUIWoodenFluidHopper.create(world.getTileEntity(pos) as TileEntityFluidHopper, getServerGuiElement(ID, player, world, x, y, z)!!)
@ -42,7 +44,7 @@ object GUIHandler: IGuiHandler {
override fun getServerGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): Container? { override fun getServerGuiElement(ID: Int, player: EntityPlayer, world: World, x: Int, y: Int, z: Int): Container? {
val pos = BlockPos(x, y, z) val pos = BlockPos(x, y, z)
return when (ID) { return when (ID) {
INVERTED_HOPPER -> ContainerInvertedHopper(world.getTileEntity(pos) as TileEntityInvertedHopper, player.inventory, pos) INVERTED_HOPPER, ADVANCED_HOPPER -> ContainerInventoryHopper(world.getTileEntity(pos) as TileEntityInventoryHopper, player.inventory, pos)
FLUID_HOPPER, WOODEN_FLUID_HOPPER -> ContainerPlayerInv(pos, player.inventory) FLUID_HOPPER, WOODEN_FLUID_HOPPER -> ContainerPlayerInv(pos, player.inventory)
WOODEN_HOPPER -> ContainerWoodenHopper(world.getTileEntity(pos) as TileEntityWoodenHopper, player.inventory, pos) WOODEN_HOPPER -> ContainerWoodenHopper(world.getTileEntity(pos) as TileEntityWoodenHopper, player.inventory, pos)
else -> null else -> null

View File

@ -0,0 +1,35 @@
package net.shadowfacts.extrahoppers.gui.element
import net.minecraft.client.Minecraft
import net.shadowfacts.shadowmc.ui.UIDimensions
import net.shadowfacts.shadowmc.ui.element.button.UIButtonBase
import net.shadowfacts.shadowmc.ui.util.UIHelper
import net.shadowfacts.shadowmc.util.MouseButton
/**
* @author shadowfacts
*/
//TODO: move me to ShadowMC
class UIFilterButton(val callback: (UIFilterButton) -> Unit, id: String, vararg classes: String): UIButtonBase("", id, *classes) {
override fun getMinDimensions(): UIDimensions {
return preferredDimensions
}
override fun getPreferredDimensions(): UIDimensions {
return UIDimensions(20, 20)
}
override fun handlePress(mouseX: Int, mouseY: Int, button: MouseButton?): Boolean {
callback(this)
return true
}
override fun drawButton(mouseX: Int, mouseY: Int) {
val sprite = Minecraft.getMinecraft().textureMapBlocks.getAtlasSprite("minecraft:items/paper")
UIHelper.drawFluidQuad(x + 3, y + 2, 16, 16, sprite.minU, sprite.minV, sprite.maxU, sprite.maxV)
// Minecraft.getMinecraft().textureManager.bindTexture(TextureMap.LOCATION_BLOCKS_TEXTURE)
// UIHelper.drawTexturedRect(x + 2, y + 2, sprite.getInterpolatedU(0.0), sprite.getInterpolatedV(0.0), 16, 16)
}
}

View File

@ -0,0 +1,10 @@
package net.shadowfacts.extrahoppers.util
import net.minecraftforge.items.SlotItemHandler
import net.shadowfacts.extrahoppers.block.inventory.TileEntityInventoryHopper
import net.shadowfacts.extrahoppers.util.filter.ItemFilter
/**
* @author shadowfacts
*/
class SlotItemFilter(hopper: TileEntityInventoryHopper, id: Int, x: Int, y: Int): SlotItemHandler((hopper.filter as ItemFilter).inventory, id, x, y)

View File

@ -0,0 +1,19 @@
package net.shadowfacts.extrahoppers.util.filter
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
/**
* @author shadowfacts
*/
abstract class Filter<in T> {
abstract fun setFromStack(i: Int, stack: ItemStack)
abstract fun accepts(stack: T): Boolean
abstract fun writeToNBT(tag: NBTTagCompound): NBTTagCompound
abstract fun readFromNBT(tag: NBTTagCompound)
}

View File

@ -0,0 +1,17 @@
package net.shadowfacts.extrahoppers.util.filter
import net.minecraft.client.resources.I18n
/**
* @author shadowfacts
*/
enum class FilterMode {
WHITELIST,
BLACKLIST;
fun localize(): String {
return I18n.format("extrahoppers.filtermode.${name.toLowerCase()}")
}
}

View File

@ -0,0 +1,61 @@
package net.shadowfacts.extrahoppers.util.filter
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.nbt.NBTTagList
import net.minecraftforge.common.util.Constants
import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.capability.CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY
import net.minecraftforge.fluids.capability.CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY
import net.minecraftforge.fluids.capability.IFluidHandler
import net.shadowfacts.forgelin.extensions.forEach
/**
* @author shadowfacts
*/
class FluidFilter(size: Int): Filter<FluidStack>() {
private val filter: Array<FluidStack?> = arrayOfNulls(size)
override fun setFromStack(i: Int, stack: ItemStack) {
if (stack.isEmpty) {
filter[i] = null
} else {
val handler: IFluidHandler = if (stack.hasCapability(FLUID_HANDLER_CAPABILITY, null)) {
stack.getCapability(FLUID_HANDLER_CAPABILITY, null)!!
} else if (stack.hasCapability(FLUID_HANDLER_ITEM_CAPABILITY, null)) {
stack.getCapability(FLUID_HANDLER_ITEM_CAPABILITY, null)!!
} else {
return
}
filter[i] = handler.tankProperties[0].contents?.copy()
}
}
override fun accepts(stack: FluidStack): Boolean {
return filter.contains(stack)
}
override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound {
val list = NBTTagList()
filter.forEach {
if (it != null) {
list.appendTag(it.writeToNBT(NBTTagCompound()))
}
}
tag.setTag("filter", list)
return tag
}
override fun readFromNBT(tag: NBTTagCompound) {
val list = tag.getTagList("filter", Constants.NBT.TAG_COMPOUND)
var i = 0
list.forEach {
if (it is NBTTagCompound) {
filter[i] = FluidStack.loadFluidStackFromNBT(it)
i++
}
}
}
}

View File

@ -0,0 +1,40 @@
package net.shadowfacts.extrahoppers.util.filter
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.items.ItemStackHandler
import net.shadowfacts.forgelin.extensions.forEach
import net.shadowfacts.forgelin.extensions.set
/**
* @author shadowfacts
*/
class ItemFilter(size: Int): Filter<ItemStack>() {
val inventory = ItemStackHandler(size)
override fun setFromStack(i: Int, stack: ItemStack) {
inventory[i] = stack.copy().apply {
count = 1
}
}
override fun accepts(stack: ItemStack): Boolean {
inventory.forEach {
if (!it.isEmpty && ItemStack.areItemStacksEqual(it, stack)) {
return true
}
}
return false
}
override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound {
tag.setTag("filter", inventory.serializeNBT())
return tag
}
override fun readFromNBT(tag: NBTTagCompound) {
inventory.deserializeNBT(tag.getCompoundTag("filter"))
}
}

View File

@ -0,0 +1,25 @@
package net.shadowfacts.extrahoppers.util.filter
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
/**
* @author shadowfacts
*/
object NoOpFilter: Filter<Any>() {
override fun setFromStack(i: Int, stack: ItemStack) {
}
override fun accepts(stack: Any): Boolean {
return true
}
override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound {
return tag
}
override fun readFromNBT(tag: NBTTagCompound) {
}
}

View File

@ -0,0 +1,40 @@
{
"forge_marker": 1,
"defaults": {
"textures": {
"particle": "blocks/gold_block",
"top": "blocks/gold_block",
"side": "blocks/gold_block",
"inside": "blocks/gold_block"
}
},
"variants": {
"inventory": {
"model": "hopper_down",
"transform": "forge:default-block"
},
"facing": {
"up": {
"model": "hopper_down"
},
"down": {
"model": "hopper_down"
},
"north": {
"model": "hopper_side"
},
"south": {
"model": "hopper_side",
"y": 180
},
"west": {
"model": "hopper_side",
"y": 270
},
"east": {
"model": "hopper_side",
"y": 90
}
}
}
}

View File

@ -0,0 +1,40 @@
{
"forge_marker": 1,
"defaults": {
"textures": {
"particle": "blocks/gold_block",
"top": "blocks/gold_block",
"side": "blocks/gold_block",
"inside": "blocks/gold_block"
}
},
"variants": {
"inventory": {
"model": "hopper_down",
"transform": "forge:default-block"
},
"facing": {
"up": {
"model": "hopper_down"
},
"down": {
"model": "hopper_down"
},
"north": {
"model": "hopper_side"
},
"south": {
"model": "hopper_side",
"y": 180
},
"west": {
"model": "hopper_side",
"y": 270
},
"east": {
"model": "hopper_side",
"y": 90
}
}
}
}

View File

@ -0,0 +1,40 @@
{
"forge_marker": 1,
"defaults": {
"textures": {
"particle": "blocks/gold_block",
"top": "blocks/gold_block",
"side": "blocks/gold_block",
"inside": "blocks/gold_block"
}
},
"variants": {
"inventory": {
"model": "extrahoppers:hopper_up",
"transform": "forge:default-block"
},
"facing": {
"up": {
"model": "extrahoppers:hopper_up"
},
"down": {
"model": "extrahoppers:hopper_up"
},
"north": {
"model": "extrahoppers:inverted_hopper_side"
},
"south": {
"model": "extrahoppers:inverted_hopper_side",
"y": 180
},
"west": {
"model": "extrahoppers:inverted_hopper_side",
"y": 270
},
"east": {
"model": "extrahoppers:inverted_hopper_side",
"y": 90
}
}
}
}

View File

@ -0,0 +1,40 @@
{
"forge_marker": 1,
"defaults": {
"textures": {
"particle": "blocks/gold_block",
"top": "blocks/gold_block",
"side": "blocks/gold_block",
"inside": "blocks/gold_block"
}
},
"variants": {
"inventory": {
"model": "extrahoppers:hopper_up",
"transform": "forge:default-block"
},
"facing": {
"up": {
"model": "extrahoppers:hopper_up"
},
"down": {
"model": "extrahoppers:hopper_up"
},
"north": {
"model": "extrahoppers:inverted_hopper_side"
},
"south": {
"model": "extrahoppers:inverted_hopper_side",
"y": 180
},
"west": {
"model": "extrahoppers:inverted_hopper_side",
"y": 270
},
"east": {
"model": "extrahoppers:inverted_hopper_side",
"y": 90
}
}
}
}

View File

@ -1,3 +1,13 @@
#top { #top {
vertical-layout: top vertical-layout: top
} }
#mode {
horizontal-layout: left
margin-left: 20
}
#filter {
horizontal-layout: right
margin-right: 20
}

View File

@ -0,0 +1,59 @@
#top {
vertical-layout: top
}
#filter {
horizontal-layout: left
margin-left: 12
vertical-layout: top
margin-top: 18
}
#mode {
horizontal-layout: right
margin-right: 12
vertical-layout: top
margin-top: 18
}
#filter-container {
horizontal-layout: left
vertical-layout: top
margin-left: 4
}
#filter-bottom {
vertical-layout: bottom
margin-bottom: 3
}
#filter-slots {
vertical-layout: top
margin-top: 11
horizontal-layout: left
margin-left: 17
}
.filter-slot-top {
vertical-layout: top
}
#filter-slot-0 {
horizontal-layout: left
}
#filter-slot-2 {
horizontal-layout: right
}
.filter-slot-bottom {
vertical-layout: bottom
}
#filter-slot-3 {
horizontal-layout: left
}
#filter-slot-4 {
horizontal-layout: right
}

View File

@ -6,6 +6,10 @@ tile.extrahoppers:wooden_hopper.name=Wooden Hopper
tile.extrahoppers:inverted_wooden_hopper.name=Inverted Wooden Hopper tile.extrahoppers:inverted_wooden_hopper.name=Inverted Wooden Hopper
tile.extrahoppers:wooden_fluid_hopper.name=Wooden Fluid Hopper tile.extrahoppers:wooden_fluid_hopper.name=Wooden Fluid Hopper
tile.extrahoppers:inverted_wooden_fluid_hopper.name=Inverted Wooden Fluid Hopper tile.extrahoppers:inverted_wooden_fluid_hopper.name=Inverted Wooden Fluid Hopper
tile.extrahoppers:advanced_fluid_hopper.name=Advanced Fluid Hopper
tile.extrahoppers:inverted_advanced_fluid_hopper.name=Inverted Advanced Fluid Hopper
tile.extrahoppers:advanced_hopper.name=Advanced Hopper
tile.extrahoppers:inverted_advanced_hopper.name=Inverted Advanced Hopper
extrahoppers.wooden_fluid_hopper.temperature=Temperature: %s%dK extrahoppers.wooden_fluid_hopper.temperature=Temperature: %s%dK
@ -13,3 +17,6 @@ extrahoppers.config.gui.title=Extra Hoppers Config
extrahoppers.config.gui.category.fluidhopper=Fluid Hopper extrahoppers.config.gui.category.fluidhopper=Fluid Hopper
itemGroup.extrahoppers=Extra Hoppers itemGroup.extrahoppers=Extra Hoppers
extrahoppers.filtermode.whitelist=Whitelist
extrahoppers.filtermode.blacklist=Blacklist

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB