ExtraHoppers-forge/src/main/kotlin/net/shadowfacts/extrahoppers/block/fluid/TileEntityFluidHopper.kt

150 lines
4.3 KiB
Kotlin

package net.shadowfacts.extrahoppers.block.fluid
import net.minecraft.block.BlockLiquid
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.EnumFacing
import net.minecraft.util.ITickable
import net.minecraftforge.fluids.Fluid.BUCKET_VOLUME
import net.minecraftforge.fluids.capability.CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY
import net.minecraftforge.fluids.capability.IFluidHandler
import net.minecraftforge.fml.common.network.NetworkRegistry
import net.shadowfacts.extrahoppers.util.FluidUtils
import net.shadowfacts.extrahoppers.EHConfig
import net.shadowfacts.extrahoppers.block.base.TileEntityHopperBase
import net.shadowfacts.shadowmc.ShadowMC
import net.shadowfacts.shadowmc.capability.CapHolder
import net.shadowfacts.shadowmc.fluid.FluidTank
import net.shadowfacts.shadowmc.nbt.AutoSerializeNBT
import net.shadowfacts.shadowmc.network.PacketUpdateTE
/**
* @author shadowfacts
*/
class TileEntityFluidHopper: TileEntityHopperBase(), ITickable {
companion object {
val HANDLER_COOLDOWN = 8
val WORLD_COOLDOWN = 40
}
@AutoSerializeNBT
@CapHolder(capabilities = arrayOf(IFluidHandler::class))
internal var tank = FluidTank(EHConfig.fhSize)
private var handlerCooldown: Int = HANDLER_COOLDOWN
private var worldCooldown: Int = WORLD_COOLDOWN
internal fun save() {
markDirty()
ShadowMC.network.sendToAllAround(PacketUpdateTE(this), NetworkRegistry.TargetPoint(world.provider.dimension, pos.x.toDouble(), pos.y.toDouble(), pos.z.toDouble(), 64.0))
}
override fun update() {
if (!world.isRemote) {
// TODO: redstone me
handlerCooldown--
if (handlerCooldown <= 0) {
handleFluidHandlers()
}
worldCooldown--
if (worldCooldown <= 0) {
handleWorld()
}
}
}
private fun handleFluidHandlers() {
val transferOut = transferOut()
val transferIn = transferIn()
if (transferOut || transferIn) {
handlerCooldown = HANDLER_COOLDOWN
save()
}
}
private fun transferIn(): Boolean {
if (tank.fluidAmount < tank.capacity) {
val handlerPos = pos.up()
val te = world.getTileEntity(handlerPos)
if (te != null && te.hasCapability(FLUID_HANDLER_CAPABILITY, EnumFacing.DOWN)) {
val handler = te.getCapability(FLUID_HANDLER_CAPABILITY, EnumFacing.DOWN)
tank.fill(handler!!.drain(tank.capacity - tank.fluidAmount, true), true)
return true
}
}
return false
}
private fun transferOut(): Boolean {
if (tank.fluidAmount > 0) {
val facing = getHopperFacing()
val handlerPos = pos.offset(facing)
val te = world.getTileEntity(handlerPos)
if (te != null && te.hasCapability(FLUID_HANDLER_CAPABILITY, facing.opposite)) {
val handler = te.getCapability(FLUID_HANDLER_CAPABILITY, facing.opposite)
tank.drain(handler!!.fill(tank.drain(20, false), true), true)
return true
}
}
return false
}
private fun handleWorld() {
val pickup = pickupFromWorld()
val place = placeInWorld()
if (pickup || place) {
worldCooldown = WORLD_COOLDOWN
save()
}
}
private fun pickupFromWorld(): Boolean {
if (EHConfig.fhPickupWorldFluids && tank.fluidAmount <= tank.capacity - BUCKET_VOLUME) {
if (FluidUtils.isFluidBlock(world, pos.up())) {
val toDrain = FluidUtils.drainFluidBlock(world, pos.up(), false)!!
if (toDrain.amount <= tank.capacity - tank.fluidAmount) {
tank.fill(FluidUtils.drainFluidBlock(world, pos.up(), true), true)
return true
}
}
}
return false
}
private fun placeInWorld(): Boolean {
if (EHConfig.fhPlaceFluidsInWorld && tank.fluidAmount >= BUCKET_VOLUME) {
val fluid = tank.fluid
if (fluid!!.fluid.canBePlacedInWorld()) {
var fluidBlock = fluid.fluid.block
if (fluidBlock is BlockLiquid) fluidBlock = BlockLiquid.getFlowingBlock(fluidBlock.getDefaultState().material)
val newPos = pos.offset(getHopperFacing())
if (fluidBlock.canPlaceBlockAt(world, newPos)) {
tank.drain(BUCKET_VOLUME, true)
world.setBlockState(newPos, fluidBlock.defaultState)
return true
}
}
}
return false
}
override fun writeToNBT(tag: NBTTagCompound): NBTTagCompound {
tank.writeToNBT(tag)
tag.setInteger("handlerCooldown", handlerCooldown)
tag.setInteger("worldCooldown", worldCooldown)
return super.writeToNBT(tag)
}
override fun readFromNBT(tag: NBTTagCompound) {
tank.readFromNBT(tag)
handlerCooldown = tag.getInteger("handlerCooldown")
worldCooldown = tag.getInteger("worldCooldown")
super.readFromNBT(tag)
}
}