Started converting TileGrate to scala

This commit is contained in:
Robert S 2014-07-22 02:32:42 -04:00
parent c734a80f5d
commit 8aadbab7b5
4 changed files with 478 additions and 689 deletions

View file

@ -11,11 +11,6 @@ import net.minecraft.item.ItemStack
import net.minecraftforge.oredict.OreDictionary
import net.minecraftforge.oredict.ShapedOreRecipe
import resonant.content.loader.ModManager
import resonant.lib.content.ContentRegistry
import resonant.lib.modproxy.ProxyHandler
import resonant.lib.network.PacketAnnotation
import resonant.lib.network.PacketHandler
import resonant.lib.prefab.item.ItemBlockMetadata
import resonant.lib.recipe.UniversalRecipe
import resonantinduction.archaic.blocks.TileTurntable
import resonantinduction.archaic.crate.BlockCrate
@ -61,103 +56,96 @@ object Archaic {
final val ID = "ResonantInduction|Archaic"
final val NAME = Reference.NAME + " Archaic"
final val NAME = Reference.name + " Archaic"
val contentRegistry = new ModManager().setPrefix(Reference.PREFIX).setTab(ResonantTab.DEFAULT)
val contentRegistry = new ModManager().setPrefix( Reference.prefix ).setTab( ResonantTab )
@Instance(ID)
var INSTANCE: Archaic = _
@Instance( ID )
var INSTANCE : Archaic = _
@SidedProxy(clientSide = "resonantinduction.archaic.ClientProxy", serverSide = "resonantinduction.archaic.CommonProxy")
var proxy: CommonProxy = _
@SidedProxy( clientSide = "resonantinduction.archaic.ClientProxy", serverSide = "resonantinduction.archaic.CommonProxy" )
var proxy : CommonProxy = _
@Mod.Metadata(ID)
var metadata: ModMetadata = _
@Mod.Metadata( ID )
var metadata : ModMetadata = _
}
@Mod(modid = Archaic.ID, name = Archaic.NAME, version = Reference.VERSION, dependencies = "required-after:" + ResonantInduction.ID)
@Mod( modid = Archaic.ID, name = Archaic.NAME, version = Reference.version, dependencies = "required-after:" + ResonantInduction.ID )
class Archaic {
var modproxies: ProxyHandler = _
@EventHandler
def preInit(evt: FMLPreInitializationEvent) {
modproxies = new ProxyHandler()
NetworkRegistry.instance().registerGuiHandler(this, proxy)
def preInit( evt : FMLPreInitializationEvent ) {
NetworkRegistry.instance().registerGuiHandler( this, proxy )
Settings.config.load()
ArchaicBlocks.blockEngineeringTable = contentRegistry.newBlock(classOf[TileEngineeringTable])
ArchaicBlocks.blockCrate = contentRegistry.createBlock(classOf[BlockCrate], classOf[ItemBlockCrate], classOf[TileCrate])
ArchaicBlocks.blockImprinter = contentRegistry.createTile(classOf[BlockImprinter], classOf[TileImprinter])
ArchaicBlocks.blockTurntable = contentRegistry.newBlock(classOf[TileTurntable])
ArchaicBlocks.blockFirebox = contentRegistry.createBlock(classOf[BlockFirebox], classOf[ItemBlockMetadata], classOf[TileFirebox])
ArchaicBlocks.blockHotPlate = contentRegistry.createTile(classOf[BlockHotPlate], classOf[TileHotPlate])
ArchaicBlocks.blockMillstone = contentRegistry.createTile(classOf[BlockMillstone], classOf[TileMillstone])
ArchaicBlocks.blockCast = contentRegistry.createTile(classOf[BlockCastingMold], classOf[TileCastingMold])
ArchaicBlocks.blockGutter = contentRegistry.newBlock(classOf[TileGutter])
ArchaicBlocks.blockGrate = contentRegistry.newBlock(classOf[TileGrate])
ArchaicBlocks.blockFilter = contentRegistry.newBlock(classOf[TileFilter])
ArchaicBlocks.blockTank = contentRegistry.newBlock(classOf[TileTank])
ArchaicItems.itemHandCrank = contentRegistry.createItem(classOf[ItemHandCrank])
ArchaicItems.itemImprint = contentRegistry.createItem(classOf[ItemImprint])
ArchaicItems.itemHammer = contentRegistry.createItem(classOf[ItemHammer])
modproxies.applyModule(classOf[Waila], true)
ArchaicBlocks.blockEngineeringTable = contentRegistry.newBlock( classOf[ TileEngineeringTable ] )
ArchaicBlocks.blockCrate = contentRegistry.createBlock( classOf[ BlockCrate ], classOf[ ItemBlockCrate ], classOf[ TileCrate ] )
ArchaicBlocks.blockImprinter = contentRegistry.createTile( classOf[ BlockImprinter ], classOf[ TileImprinter ] )
ArchaicBlocks.blockTurntable = contentRegistry.newBlock( classOf[ TileTurntable ] )
ArchaicBlocks.blockFirebox = contentRegistry.createBlock( classOf[ BlockFirebox ], classOf[ ItemBlockMetadata ], classOf[ TileFirebox ] )
ArchaicBlocks.blockHotPlate = contentRegistry.createTile( classOf[ BlockHotPlate ], classOf[ TileHotPlate ] )
ArchaicBlocks.blockMillstone = contentRegistry.createTile( classOf[ BlockMillstone ], classOf[ TileMillstone ] )
ArchaicBlocks.blockCast = contentRegistry.createTile( classOf[ BlockCastingMold ], classOf[ TileCastingMold ] )
ArchaicBlocks.blockGutter = contentRegistry.newBlock( classOf[ TileGutter ] )
ArchaicBlocks.blockGrate = contentRegistry.newBlock( classOf[ TileGrate ] )
ArchaicBlocks.blockFilter = contentRegistry.newBlock( classOf[ TileFilter ] )
ArchaicBlocks.blockTank = contentRegistry.newBlock( classOf[ TileTank ] )
ArchaicItems.itemHandCrank = contentRegistry.createItem( classOf[ ItemHandCrank ] )
ArchaicItems.itemImprint = contentRegistry.createItem( classOf[ ItemImprint ] )
ArchaicItems.itemHammer = contentRegistry.createItem( classOf[ ItemHammer ] )
Settings.config.save()
proxy.preInit()
modproxies.preInit()
}
@EventHandler
def init(evt: FMLInitializationEvent) {
Settings.setModMetadata(metadata, ID, NAME, ResonantInduction.ID)
def init( evt : FMLInitializationEvent ) {
Settings.setModMetadata( metadata, ID, NAME, ResonantInduction.ID )
proxy.init()
modproxies.init()
}
@EventHandler
def postInit(evt: FMLPostInitializationEvent) {
ResonantTab.ITEMSTACK = new ItemStack(blockEngineeringTable)
if (OreDictionary.getOres("cobblestone") == null) {
OreDictionary.registerOre("cobblestone", Blocks.cobblestone)
def postInit( evt : FMLPostInitializationEvent ) {
ResonantTab.itemStack = new ItemStack( ArchaicBlocks.blockEngineeringTable )
if ( OreDictionary.getOres( "cobblestone" ) == null ) {
OreDictionary.registerOre( "cobblestone", Blocks.cobblestone )
}
if (OreDictionary.getOres("stickWood") == null) {
OreDictionary.registerOre("stickWood", Items.stick)
if ( OreDictionary.getOres( "stickWood" ) == null ) {
OreDictionary.registerOre( "stickWood", Items.stick )
}
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockEngineeringTable, Array("P", "C", 'P', Blocks.wooden_pressure_plate, 'C', Blocks.crafting_table)))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockFilter, Array("B", "P", "B", 'B', Blocks.iron_bars, 'P', Items.paper)))
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ArchaicBlocks.blockCrate, 1, 0), Array("WWW", "WSW", "WWW",
'S', "stickWood", 'W', "logWood")))
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ArchaicBlocks.blockCrate, 1, 1), Array("WWW", "WSW", "WWW",
'S', new ItemStack(ArchaicBlocks.blockCrate, 1, 0), 'W', "ingotIron")))
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ArchaicBlocks.blockCrate, 1, 2), Array("WWW", "WSW", "WWW",
'S', new ItemStack(ArchaicBlocks.blockCrate, 1, 1), 'W', UniversalRecipe.PRIMARY_METAL.get)))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockFirebox, Array("III", "SFS", "SSS", 'I', Items.iron_ingot,
'F', Blocks.furnace, 'S', Blocks.stone)))
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(ArchaicBlocks.blockFirebox, 1, 1), Array("III", "SFS", "SSS",
'I', UniversalRecipe.PRIMARY_METAL.get, 'F', new ItemStack(ArchaicBlocks.blockFirebox, 1, 0), 'S', UniversalRecipe.WIRE.get)))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockImprinter, Array("SSS", "W W", "PPP", 'S', Blocks.stone,
'P', Blocks.piston, 'W', "logWood")))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockTurntable, Array("SSS", "PGP", "WWW", 'S', Blocks.stone,
'G', Items.redstone, 'P', Blocks.piston, 'W', "logWood")))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockCast, Array("I I", "IBI", "III", 'S', Items.iron_ingot, 'B',
Blocks.iron_bars)))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockGutter, Array("S S", "I I", "III", 'S', Items.stick, 'I',
"cobblestone")))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockGrate, Array("WBW", "B B", "WBW", 'B', Blocks.iron_bars,
'W', "plankWood")))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockHotPlate, Array("SSS", "III", 'I', Items.iron_ingot, 'S',
Blocks.stone)))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockMillstone, Array("SPS", "SAS", "SSS", 'P', Blocks.piston,
'A', Items.stone_pickaxe, 'S', Blocks.stone)))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicBlocks.blockTank, Array("GGG", "GSG", "GGG", 'G', Blocks.glass, 'S',
Items.iron_ingot)))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicItems.itemHandCrank, Array("S ", "SSS", " S", 'S', "stickWood")))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicItems.itemImprint, Array("PPP", "PIP", "PPP", 'P', Items.paper, 'I',
new ItemStack(Items.dye, 0))))
GameRegistry.addRecipe(new ShapedOreRecipe(ArchaicItems.itemHammer, Array("CC ", "CS ", " S", 'C', "cobblestone", 'S',
"stickWood")))
GameRegistry.registerCraftingHandler(new CrateCraftingHandler())
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockEngineeringTable, Array( "P", "C", 'P', Blocks.wooden_pressure_plate, 'C', Blocks.crafting_table ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockFilter, Array( "B", "P", "B", 'B', Blocks.iron_bars, 'P', Items.paper ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( new ItemStack( ArchaicBlocks.blockCrate, 1, 0 ), Array( "WWW", "WSW", "WWW",
'S', "stickWood", 'W', "logWood" ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( new ItemStack( ArchaicBlocks.blockCrate, 1, 1 ), Array( "WWW", "WSW", "WWW",
'S', new ItemStack( ArchaicBlocks.blockCrate, 1, 0 ), 'W', "ingotIron" ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( new ItemStack( ArchaicBlocks.blockCrate, 1, 2 ), Array( "WWW", "WSW", "WWW",
'S', new ItemStack( ArchaicBlocks.blockCrate, 1, 1 ), 'W', UniversalRecipe.PRIMARY_METAL.get ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockFirebox, Array( "III", "SFS", "SSS", 'I', Items.iron_ingot,
'F', Blocks.furnace, 'S', Blocks.stone ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( new ItemStack( ArchaicBlocks.blockFirebox, 1, 1 ), Array( "III", "SFS", "SSS",
'I', UniversalRecipe.PRIMARY_METAL.get, 'F', new ItemStack( ArchaicBlocks.blockFirebox, 1, 0 ), 'S', UniversalRecipe.WIRE.get ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockImprinter, Array( "SSS", "W W", "PPP", 'S', Blocks.stone,
'P', Blocks.piston, 'W', "logWood" ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockTurntable, Array( "SSS", "PGP", "WWW", 'S', Blocks.stone,
'G', Items.redstone, 'P', Blocks.piston, 'W', "logWood" ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockCast, Array( "I I", "IBI", "III", 'S', Items.iron_ingot, 'B',
Blocks.iron_bars ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockGutter, Array( "S S", "I I", "III", 'S', Items.stick, 'I',
"cobblestone" ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockGrate, Array( "WBW", "B B", "WBW", 'B', Blocks.iron_bars,
'W', "plankWood" ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockHotPlate, Array( "SSS", "III", 'I', Items.iron_ingot, 'S',
Blocks.stone ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockMillstone, Array( "SPS", "SAS", "SSS", 'P', Blocks.piston,
'A', Items.stone_pickaxe, 'S', Blocks.stone ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicBlocks.blockTank, Array( "GGG", "GSG", "GGG", 'G', Blocks.glass, 'S',
Items.iron_ingot ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicItems.itemHandCrank, Array( "S ", "SSS", " S", 'S', "stickWood" ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicItems.itemImprint, Array( "PPP", "PIP", "PPP", 'P', Items.paper, 'I',
new ItemStack( Items.dye, 0 ) ) ) )
GameRegistry.addRecipe( new ShapedOreRecipe( ArchaicItems.itemHammer, Array( "CC ", "CS ", " S", 'C', "cobblestone", 'S',
"stickWood" ) ) )
GameRegistry.registerCraftingHandler( new CrateCraftingHandler() )
proxy.postInit()
modproxies.postInit()
}
}

View file

@ -1,12 +1,12 @@
package resonantinduction.archaic.blocks
import codechicken.multipart.TileMultipart
import cpw.mods.fml.relauncher.{Side, SideOnly}
import cpw.mods.fml.relauncher.{ Side, SideOnly }
import net.minecraft.block.Block
import net.minecraft.block.material.Material
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.util.IIcon
import net.minecraft.world.{IBlockAccess, World}
import net.minecraft.world.{ IBlockAccess, World }
import net.minecraftforge.common.util.ForgeDirection
import resonant.api.IRotatable
import resonant.content.prefab.RenderRotatedTexture
@ -15,92 +15,78 @@ import resonant.lib.content.prefab.TRotatable
import resonantinduction.core.Reference
import universalelectricity.core.transform.vector.Vector3
object TileTurntable
{
var top: IIcon = null
object TileTurntable {
var top : IIcon = null
}
class TileTurntable extends SpatialBlock(Material.piston) with TRotatable with RenderRotatedTexture
{
textureName = "turntable_side"
tickRandomly = true
rotationMask = Integer.parseInt("111111", 2).toByte
class TileTurntable extends SpatialBlock( Material.piston ) with TRotatable with RenderRotatedTexture {
textureName = "turntable_side"
tickRandomly = true
rotationMask = Integer.parseInt( "111111", 2 ).toByte
override def tickRate(par1World: World): Int = 5
override def tickRate( par1World : World ) : Int = 5
@SideOnly(Side.CLIENT)
override def registerIcons(iconReg: IIconRegister)
{
super.registerIcons(iconReg)
TileTurntable.top = iconReg.registerIcon(Reference.prefix + "turntable")
}
override def update()
{
updateTurntableState(world, x, y, z)
}
@SideOnly(Side.CLIENT)
override def getIcon(access: IBlockAccess, side: Int): IIcon =
{
if (side == metadata)
{
return TileTurntable.top
@SideOnly( Side.CLIENT )
override def registerIcons( iconReg : IIconRegister ) {
super.registerIcons( iconReg )
TileTurntable.top = iconReg.registerIcon( Reference.prefix + "turntable" )
}
return getIcon
}
@SideOnly(Side.CLIENT)
override def getIcon(side: Int, meta: Int): IIcon =
{
if (side == 1)
{
return TileTurntable.top
override def update() {
updateTurntableState( world, x, y, z )
}
return getIcon
}
override def onNeighborChanged(block: Block)
{
scheduleTick(10)
}
private def updateTurntableState(world: World, x: Int, y: Int, z: Int)
{
if (world.isBlockIndirectlyGettingPowered(x, y, z))
{
try
{
val facing: ForgeDirection = ForgeDirection.getOrientation(world.getBlockMetadata(x, y, z))
val position = new Vector3(x, y, z) + facing
val tileEntity = position.getTileEntity(world)
val block = position.getBlock(world)
if (!(tileEntity.isInstanceOf[TileMultipart]))
@SideOnly( Side.CLIENT )
override def getIcon( access : IBlockAccess, side : Int ) : IIcon =
{
if (tileEntity.isInstanceOf[IRotatable])
{
val blockRotation = tileEntity.asInstanceOf[IRotatable].getDirection
tileEntity.asInstanceOf[IRotatable].setDirection(blockRotation.getRotation(facing.getOpposite))
}
else if (block != null)
{
block.rotateBlock(world, position.xi, position.yi, position.zi, facing.getOpposite)
}
if ( side == metadata ) {
return TileTurntable.top
}
world.markBlockForUpdate(position.xi, position.yi, position.zi)
world.playSoundEffect(x + 0.5D, y + 0.5D, z + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat * 0.15F + 0.6F)
return getIcon
}
}
catch
@SideOnly( Side.CLIENT )
override def getIcon( side : Int, meta : Int ) : IIcon =
{
case e: Exception =>
{
System.out.println("Error while rotating a block near " + x + "x " + y + "y " + z + "z " + (if (world != null && world.provider != null) world.provider.dimensionId + "d" else "null:world"))
e.printStackTrace
}
if ( side == 1 ) {
return TileTurntable.top
}
return getIcon
}
override def onNeighborChanged( block : Block ) {
scheduleTick( 10 )
}
private def updateTurntableState( world : World, x : Int, y : Int, z : Int ) {
if ( world.isBlockIndirectlyGettingPowered( x, y, z ) ) {
try {
val facing : ForgeDirection = ForgeDirection.getOrientation( world.getBlockMetadata( x, y, z ) )
val position = new Vector3( x, y, z ) + facing
val tileEntity = position.getTileEntity( world )
val block = position.getBlock( world )
if ( !( tileEntity.isInstanceOf[ TileMultipart ] ) ) {
if ( tileEntity.isInstanceOf[ IRotatable ] ) {
val blockRotation = tileEntity.asInstanceOf[ IRotatable ].getDirection
tileEntity.asInstanceOf[ IRotatable ].setDirection( blockRotation.getRotation( facing.getOpposite ) )
}
else if ( block != null ) {
block.rotateBlock( world, position.xi, position.yi, position.zi, facing.getOpposite )
}
world.markBlockForUpdate( position.xi, position.yi, position.zi )
world.playSoundEffect( x + 0.5D, y + 0.5D, z + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat * 0.15F + 0.6F )
}
}
catch {
case e : Exception =>
{
System.out.println( "Error while rotating a block near " + x + "x " + y + "y " + z + "z " + ( if ( world != null && world.provider != null ) world.provider.dimensionId + "d" else "null:world" ) )
e.printStackTrace
}
}
}
}
}
}

View file

@ -1,533 +0,0 @@
package resonantinduction.archaic.fluid.grate;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.PriorityQueue;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import resonant.api.IRotatable;
import resonant.lib.config.Config;
import resonant.lib.utility.FluidUtility;
import resonantinduction.core.Reference;
import resonantinduction.core.grid.fluid.pressure.FluidPressureNode;
import resonantinduction.core.grid.fluid.pressure.TilePressureNode;
import universalelectricity.core.transform.vector.Vector3;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
public class TileGrate extends TilePressureNode implements IRotatable
{
@Config(comment = "The multiplier for the influence of the grate. Dependent on pressure.")
private static double grateEffectMultiplier = 5;
@Config(comment = "The speed in which the grate drains blocks. Dependent on grate block influence.")
private static double grateDrainSpeedMultiplier = 0.01;
@SideOnly(Side.CLIENT)
private static IIcon iconFront, iconSide;
private GratePathfinder gratePath;
private boolean fillOver = true;
public TileGrate()
{
super(Material.rock);
isOpaqueCube = false;
normalRender = true;
rotationMask = Byte.parseByte("111111", 2);
node = new FluidPressureNode(this);
node.maxFlowRate = getPressureTank().getCapacity();
}
@Override
public IIcon getIcon(IBlockAccess world, int side)
{
return side == getDirection().ordinal() ? iconFront : iconSide;
}
@Override
public IIcon getIcon(int side, int metadata)
{
return side == 1 ? iconFront : iconSide;
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister iconRegister)
{
iconFront = iconRegister.registerIcon(Reference.PREFIX + "grate_front");
iconSide = iconRegister.registerIcon(Reference.PREFIX + "grate");
}
@Override
protected boolean configure(EntityPlayer player, int side, Vector3 hit)
{
if (!player.isSneaking())
{
if (!world().isRemote)
{
fillOver = !fillOver;
player.addChatMessage("Grate now set to " + (fillOver ? "" : "not ") + "fill higher than itself.");
gratePath = null;
}
return true;
}
return super.configure(player, side, hit);
}
@Override
public void readFromNBT(NBTTagCompound nbt)
{
super.readFromNBT(nbt);
fillOver = nbt.getBoolean("fillOver");
}
@Override
public void writeToNBT(NBTTagCompound nbt)
{
super.writeToNBT(nbt);
nbt.setBoolean("fillOver", fillOver);
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from)
{
return new FluidTankInfo[] { getPressureTank().getInfo() };
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid)
{
return getDirection() != from;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid)
{
return getDirection() != from;
}
@Override
public void updateEntity()
{
super.updateEntity();
if (!world().isRemote)
{
if (ticks % 10 == 0)
{
int pressure = node.getPressure(getDirection());
int blockEffect = (int) Math.abs(pressure * grateEffectMultiplier);
getPressureTank().setCapacity((int) Math.max(blockEffect * FluidContainerRegistry.BUCKET_VOLUME * grateDrainSpeedMultiplier, FluidContainerRegistry.BUCKET_VOLUME));
if (pressure > 0)
{
// Fill
if (getPressureTank().getFluidAmount() >= FluidContainerRegistry.BUCKET_VOLUME)
{
if (gratePath == null)
{
gratePath = new GratePathfinder(true);
gratePath.startFill(new Vector3(this), getPressureTank().getFluid().getFluid().getID());
}
int filledInWorld = gratePath.tryFill(getPressureTank().getFluidAmount(), blockEffect);
getPressureTank().drain(filledInWorld, true);
}
}
else if (pressure < 0)
{
// Drain
int maxDrain = getPressureTank().getCapacity() - getPressureTank().getFluidAmount();
if (maxDrain > 0)
{
if (gratePath == null)
{
gratePath = new GratePathfinder(false);
if (!gratePath.startDrain(new Vector3(this)))
{
resetPath();
}
}
if (gratePath != null && gratePath.tryPopulateDrainMap(blockEffect))
{
getPressureTank().fill(gratePath.tryDrain(maxDrain, true), true);
}
}
}
}
}
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill)
{
return getPressureTank().fill(resource, doFill);
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain)
{
if (resource != null)
{
return drain(from, resource.amount, doDrain);
}
return null;
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain)
{
return getPressureTank().drain(maxDrain, doDrain);
}
/**
* Pathfinding operations
*
* @author Calclavia
*/
public void resetPath()
{
this.gratePath = null;
}
public static class ComparableVector implements Comparable
{
public Vector3 position;
public int iterations;
public ComparableVector(Vector3 position, int iterations)
{
this.position = position;
this.iterations = iterations;
}
@Override
public int compareTo(Object obj)
{
ComparableVector wr = (ComparableVector) obj;
if (this.position.y == wr.position.y)
{
return this.iterations - wr.iterations;
}
return this.position.yi() - wr.position.yi();
}
}
public class GratePathfinder
{
/**
* The type of fluid we're dealing with. When draining, this will be the type of fluid being
* drained.
*/
public Fluid fluidType;
/**
* The starting vector for our grate.
*/
Vector3 start;
/**
* All the back trace blocks tracing back to the original.
*/
HashMap<Vector3, Vector3> navigationMap = new HashMap<Vector3, Vector3>();
/**
* The nodes we're currently working on.
*/
PriorityQueue<ComparableVector> workingNodes;
/**
* The list of blocks to drain.
*/
PriorityQueue<ComparableVector> drainNodes = new PriorityQueue<ComparableVector>(1024, Collections.reverseOrder());
public GratePathfinder(boolean checkVertical)
{
if (checkVertical)
{
this.workingNodes = new PriorityQueue<ComparableVector>();
}
else
{
this.workingNodes = new PriorityQueue<ComparableVector>(1024, new Comparator()
{
@Override
public int compare(Object a, Object b)
{
TileGrate.ComparableVector wa = (TileGrate.ComparableVector) a;
TileGrate.ComparableVector wb = (TileGrate.ComparableVector) b;
return wa.iterations - wb.iterations;
}
});
}
}
/**
* Traces back to the start position to see if this fluid position is connected with the
* starting position through fluid mediums.
*/
public boolean isConnected(Vector3 check)
{
if (check.equals(this.start))
{
return true;
}
do
{
check = this.navigationMap.get(check);
if (check == null)
{
return false;
}
if (check.equals(this.start))
{
return true;
}
}
while (FluidUtility.getFluidFromBlock(TileGrate.this.worldObj, check) != null && fluidType.getID() == FluidUtility.getFluidFromBlock(TileGrate.this.worldObj, check).getID());
return false;
}
public void startFill(Vector3 start, int fluidID)
{
this.fluidType = FluidRegistry.getFluid(fluidID);
this.start = start;
for (int i = 0; i < 6; i++)
{
ForgeDirection dir = ForgeDirection.getOrientation(i);
if (dir == TileGrate.this.getDirection())
{
Vector3 check = start.clone().add(dir);
this.navigationMap.put(check, start);
this.workingNodes.add(new TileGrate.ComparableVector(check, 0));
}
}
}
/**
* Tries to fill.
*
* @param amount
* @param tries
* @return Amount filled.
*/
public int tryFill(int amount, int tries)
{
int filled = 0;
if (amount >= FluidContainerRegistry.BUCKET_VOLUME)
{
for (int i = 0; i < tries; i++)
{
ComparableVector next = workingNodes.poll();
if (next == null)
{
TileGrate.this.resetPath();
return 0;
}
if (!isConnected(next.position))
{
TileGrate.this.resetPath();
return 0;
}
int didFill = FluidUtility.fillBlock(TileGrate.this.worldObj, next.position, new FluidStack(fluidType, amount), true);
filled += didFill;
if (FluidUtility.getFluidAmountFromBlock(TileGrate.this.worldObj, next.position) > 0 || didFill > 0)
{
addNextFill(next);
}
if (filled >= amount)
{
return filled;
}
}
}
return filled;
}
/**
* Adds new nodes into the map.
*
* @param next
*/
public void addNextFill(ComparableVector next)
{
for (int i = 0; i < 6; i++)
{
Vector3 newPosition = next.position.clone().add(ForgeDirection.getOrientation(i));
if (!this.navigationMap.containsKey(newPosition) && !(!fillOver && newPosition.yi() > y()))
{
this.navigationMap.put(newPosition, next.position);
this.workingNodes.add(new ComparableVector(newPosition, next.iterations + 1));
}
}
}
public boolean startDrain(Vector3 start)
{
fluidType = null;
this.start = start;
for (int i = 0; i < 6; i++)
{
ForgeDirection dir = ForgeDirection.getOrientation(i);
if (dir == TileGrate.this.getDirection())
{
Vector3 check = start.clone().add(dir);
this.navigationMap.put(check, start);
this.workingNodes.add(new ComparableVector(check, 0));
fluidType = FluidUtility.getFluidFromBlock(TileGrate.this.worldObj, check);
}
}
return fluidType != null;
}
/**
* Creates a map of all the fluids to be drained.
*
* @param tries
* @return True if there is drainable fluid.
*/
public boolean tryPopulateDrainMap(int tries)
{
for (int i = 0; i < tries; i++)
{
ComparableVector check = workingNodes.poll();
if (check == null)
{
return true;
}
Fluid checkFluid = FluidUtility.getFluidFromBlock(TileGrate.this.worldObj, check.position);
if (checkFluid != null && fluidType.getID() == checkFluid.getID())
{
addNextDrain(check);
int checkAmount = FluidUtility.getFluidAmountFromBlock(TileGrate.this.worldObj, check.position);
if (checkAmount > 0)
{
drainNodes.add(check);
}
}
}
return drainNodes.size() > 0;
}
public void addNextDrain(ComparableVector next)
{
for (int i = 0; i < 6; i++)
{
Vector3 check = next.position.clone().add(ForgeDirection.getOrientation(i));
Fluid checkFluid = FluidUtility.getFluidFromBlock(TileGrate.this.worldObj, check);
if (checkFluid != null && fluidType.getID() == checkFluid.getID())
{
if (!navigationMap.containsKey(check))
{
navigationMap.put(check, next.position);
workingNodes.add(new TileGrate.ComparableVector(check, next.iterations + 1));
}
}
}
}
/**
* Tries to drain a specific amount of fluid.
*
* @return - The amount drained.
*/
public FluidStack tryDrain(int targetAmount, boolean doDrain)
{
int drainedAmount = 0;
while (!drainNodes.isEmpty())
{
ComparableVector fluidCoord = drainNodes.peek();
if (!isConnected(fluidCoord.position))
{
TileGrate.this.resetPath();
return new FluidStack(fluidType, drainedAmount);
}
if (FluidUtility.getFluidFromBlock(TileGrate.this.worldObj, fluidCoord.position) == null || this.fluidType.getID() != FluidUtility.getFluidFromBlock(TileGrate.this.worldObj, fluidCoord.position).getID())
{
this.drainNodes.poll();
}
else
{
int checkAmount = FluidUtility.getFluidAmountFromBlock(TileGrate.this.worldObj, fluidCoord.position);
if (drainedAmount + checkAmount > targetAmount)
{
break;
}
if (checkAmount == 0)
{
this.drainNodes.poll();
}
else
{
FluidStack fluidStack = FluidUtility.drainBlock(TileGrate.this.worldObj, fluidCoord.position, doDrain);
this.drainNodes.poll();
if (fluidStack != null)
{
drainedAmount += fluidStack.amount;
if (drainedAmount >= targetAmount)
{
break;
}
}
}
}
}
TileGrate.this.resetPath();
if (drainedAmount > 0)
{
return new FluidStack(fluidType, drainedAmount);
}
return null;
}
}
}

View file

@ -0,0 +1,348 @@
package resonantinduction.archaic.fluid.grate
import java.util.Collections
import java.util.Comparator
import java.util.HashMap
import java.util.PriorityQueue
import net.minecraft.block.material.Material
import net.minecraft.client.renderer.texture.IIconRegister
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.nbt.NBTTagCompound
import net.minecraft.util.IIcon
import net.minecraft.world.IBlockAccess
import net.minecraftforge.common.util.ForgeDirection
import net.minecraftforge.fluids.Fluid
import net.minecraftforge.fluids.FluidContainerRegistry
import net.minecraftforge.fluids.FluidRegistry
import net.minecraftforge.fluids.FluidStack
import net.minecraftforge.fluids.FluidTankInfo
import resonant.api.IRotatable
import resonant.lib.config.Config
import resonant.lib.utility.FluidUtility
import resonantinduction.core.Reference
import resonantinduction.core.grid.fluid.pressure.FluidPressureNode
import resonantinduction.core.grid.fluid.pressure.TilePressureNode
import universalelectricity.core.transform.vector.Vector3
import cpw.mods.fml.relauncher.Side
import cpw.mods.fml.relauncher.SideOnly
import TileGrate._
//remove if not needed
import scala.collection.JavaConversions._
object TileGrate {
@Config( comment = "The multiplier for the influence of the grate. Dependent on pressure." )
private var grateEffectMultiplier : Double = 5
@Config( comment = "The speed in which the grate drains blocks. Dependent on grate block influence." )
private var grateDrainSpeedMultiplier : Double = 0.01
@SideOnly( Side.CLIENT )
private var iconFront : IIcon = _
@SideOnly( Side.CLIENT )
private var iconSide : IIcon = _
class ComparableVector( var position : Vector3, var iterations : Int ) extends Comparable[ _ ] {
override def compareTo( obj : AnyRef ) : Int = {
val wr = obj.asInstanceOf[ ComparableVector ]
if ( this.position.y == wr.position.y ) {
return this.iterations - wr.iterations
}
this.position.yi() - wr.position.yi()
}
}
}
class TileGrate extends TilePressureNode( Material.rock ) with IRotatable {
private var gratePath : GratePathfinder = _
private var fillOver : Boolean = true
isOpaqueCube = false
normalRender = true
rotationMask = java.lang.Byte.parseByte( "111111", 2 )
node = new FluidPressureNode( this )
node.maxFlowRate = getPressureTank.getCapacity
override def getIcon( world : IBlockAccess, side : Int ) : IIcon = {
if ( side == getDirection.ordinal() ) iconFront else iconSide
}
override def getIcon( side : Int, metadata : Int ) : IIcon = if ( side == 1 ) iconFront else iconSide
@SideOnly( Side.CLIENT )
override def registerIcons( iconRegister : IIconRegister ) {
iconFront = iconRegister.registerIcon( Reference.PREFIX + "grate_front" )
iconSide = iconRegister.registerIcon( Reference.PREFIX + "grate" )
}
protected override def configure( player : EntityPlayer, side : Int, hit : Vector3 ) : Boolean = {
if ( !player.isSneaking ) {
if ( !world().isRemote ) {
fillOver = !fillOver
player.addChatMessage( "Grate now set to " + ( if ( fillOver ) "" else "not " ) +
"fill higher than itself." )
gratePath = null
}
return true
}
super.configure( player, side, hit )
}
override def readFromNBT( nbt : NBTTagCompound ) {
super.readFromNBT( nbt )
fillOver = nbt.getBoolean( "fillOver" )
}
override def writeToNBT( nbt : NBTTagCompound ) {
super.writeToNBT( nbt )
nbt.setBoolean( "fillOver", fillOver )
}
override def getTankInfo( from : ForgeDirection ) : Array[ FluidTankInfo ] = Array( getPressureTank.getInfo )
override def canFill( from : ForgeDirection, fluid : Fluid ) : Boolean = getDirection != from
override def canDrain( from : ForgeDirection, fluid : Fluid ) : Boolean = getDirection != from
override def updateEntity() {
super.updateEntity()
if ( !world().isRemote ) {
if ( ticks % 10 == 0 ) {
val pressure = node.getPressure( getDirection )
val blockEffect = Math.abs( pressure * grateEffectMultiplier ).toInt
getPressureTank.setCapacity( Math.max( blockEffect * FluidContainerRegistry.BUCKET_VOLUME * grateDrainSpeedMultiplier,
FluidContainerRegistry.BUCKET_VOLUME ).toInt )
if ( pressure > 0 ) {
if ( getPressureTank.getFluidAmount >= FluidContainerRegistry.BUCKET_VOLUME ) {
if ( gratePath == null ) {
gratePath = new GratePathfinder( true )
gratePath.startFill( new Vector3( this ), getPressureTank.getFluid.getFluid.getID )
}
val filledInWorld = gratePath.tryFill( getPressureTank.getFluidAmount, blockEffect )
getPressureTank.drain( filledInWorld, true )
}
}
else if ( pressure < 0 ) {
val maxDrain = getPressureTank.getCapacity - getPressureTank.getFluidAmount
if ( maxDrain > 0 ) {
if ( gratePath == null ) {
gratePath = new GratePathfinder( false )
if ( !gratePath.startDrain( new Vector3( this ) ) ) {
resetPath()
}
}
if ( gratePath != null && gratePath.tryPopulateDrainMap( blockEffect ) ) {
getPressureTank.fill( gratePath.tryDrain( maxDrain, true ), true )
}
}
}
}
}
}
override def fill( from : ForgeDirection, resource : FluidStack, doFill : Boolean ) : Int = getPressureTank.fill( resource, doFill )
override def drain( from : ForgeDirection, resource : FluidStack, doDrain : Boolean ) : FluidStack = {
if ( resource != null ) {
return drain( from, resource.amount, doDrain )
}
null
}
override def drain( from : ForgeDirection, maxDrain : Int, doDrain : Boolean ) : FluidStack = {
getPressureTank.drain( maxDrain, doDrain )
}
def resetPath() {
this.gratePath = null
}
class GratePathfinder( checkVertical : Boolean ) {
var fluidType : Fluid = _
var start : Vector3 = _
var navigationMap : HashMap[ Vector3, Vector3 ] = new HashMap[ Vector3, Vector3 ]()
var workingNodes : PriorityQueue[ ComparableVector ] = if ( checkVertical ) new PriorityQueue[ ComparableVector ]() else new PriorityQueue[ ComparableVector ]( 1024,
new Comparator() {
override def compare( a : AnyRef, b : AnyRef ) : Int = {
var wa = a.asInstanceOf[ TileGrate.ComparableVector ]
var wb = b.asInstanceOf[ TileGrate.ComparableVector ]
wa.iterations - wb.iterations
}
} )
var drainNodes : PriorityQueue[ ComparableVector ] = new PriorityQueue[ ComparableVector ]( 1024, Collections.reverseOrder() )
def isConnected( check : Vector3 ) : Boolean = {
if ( check == this.start ) {
return true
}
do {
check = this.navigationMap.get( check )
if ( check == null ) {
return false
}
if ( check == this.start ) {
return true
}
} while ( FluidUtility.getFluidFromBlock( TileGrate.this.worldObj, check ) !=
null &&
fluidType.getID ==
FluidUtility.getFluidFromBlock( TileGrate.this.worldObj, check )
.getID );
false
}
def startFill( start : Vector3, fluidID : Int ) {
this.fluidType = FluidRegistry.getFluid( fluidID )
this.start = start
for ( i <- 0 until 6 ) {
val dir = ForgeDirection.getOrientation( i )
if ( dir == TileGrate.this.getDirection ) {
val check = start.clone().add( dir )
this.navigationMap.put( check, start )
this.workingNodes.add( new TileGrate.ComparableVector( check, 0 ) )
}
}
}
def tryFill( amount : Int, tries : Int ) : Int = {
var filled = 0
if ( amount >= FluidContainerRegistry.BUCKET_VOLUME ) {
for ( i <- 0 until tries ) {
val next = workingNodes.poll()
if ( next == null ) {
TileGrate.this.resetPath()
return 0
}
if ( !isConnected( next.position ) ) {
TileGrate.this.resetPath()
return 0
}
val didFill = FluidUtility.fillBlock( TileGrate.this.worldObj, next.position, new FluidStack( fluidType,
amount ), true )
filled += didFill
if ( FluidUtility.getFluidAmountFromBlock( TileGrate.this.worldObj, next.position ) >
0 ||
didFill > 0 ) {
addNextFill( next )
}
if ( filled >= amount ) {
return filled
}
}
}
filled
}
def addNextFill( next : ComparableVector ) {
for ( i <- 0 until 6 ) {
val newPosition = next.position.clone().add( ForgeDirection.getOrientation( i ) )
if ( !this.navigationMap.containsKey( newPosition ) && !( !fillOver && newPosition.yi() > y() ) ) {
this.navigationMap.put( newPosition, next.position )
this.workingNodes.add( new ComparableVector( newPosition, next.iterations + 1 ) )
}
}
}
def startDrain( start : Vector3 ) : Boolean = {
fluidType = null
this.start = start
for ( i <- 0 until 6 ) {
val dir = ForgeDirection.getOrientation( i )
if ( dir == TileGrate.this.getDirection ) {
val check = start.clone().add( dir )
this.navigationMap.put( check, start )
this.workingNodes.add( new ComparableVector( check, 0 ) )
fluidType = FluidUtility.getFluidFromBlock( TileGrate.this.worldObj, check )
}
}
fluidType != null
}
def tryPopulateDrainMap( tries : Int ) : Boolean = {
for ( i <- 0 until tries ) {
val check = workingNodes.poll()
if ( check == null ) {
return true
}
val checkFluid = FluidUtility.getFluidFromBlock( TileGrate.this.worldObj, check.position )
if ( checkFluid != null && fluidType.getID == checkFluid.getID ) {
addNextDrain( check )
val checkAmount = FluidUtility.getFluidAmountFromBlock( TileGrate.this.worldObj, check.position )
if ( checkAmount > 0 ) {
drainNodes.add( check )
}
}
}
drainNodes.size > 0
}
def addNextDrain( next : ComparableVector ) {
for ( i <- 0 until 6 ) {
val check = next.position.clone().add( ForgeDirection.getOrientation( i ) )
val checkFluid = FluidUtility.getFluidFromBlock( TileGrate.this.worldObj, check )
if ( checkFluid != null && fluidType.getID == checkFluid.getID ) {
if ( !navigationMap.containsKey( check ) ) {
navigationMap.put( check, next.position )
workingNodes.add( new TileGrate.ComparableVector( check, next.iterations + 1 ) )
}
}
}
}
def tryDrain( targetAmount : Int, doDrain : Boolean ) : FluidStack = {
var drainedAmount = 0
while ( !drainNodes.isEmpty ) {
val fluidCoord = drainNodes.peek()
if ( !isConnected( fluidCoord.position ) ) {
TileGrate.this.resetPath()
return new FluidStack( fluidType, drainedAmount )
}
if ( FluidUtility.getFluidFromBlock( TileGrate.this.worldObj, fluidCoord.position ) ==
null ||
this.fluidType.getID !=
FluidUtility.getFluidFromBlock( TileGrate.this.worldObj, fluidCoord.position )
.getID ) {
this.drainNodes.poll()
}
else {
val checkAmount = FluidUtility.getFluidAmountFromBlock( TileGrate.this.worldObj, fluidCoord.position )
if ( drainedAmount + checkAmount > targetAmount ) {
//break
}
if ( checkAmount == 0 ) {
this.drainNodes.poll()
}
else {
val fluidStack = FluidUtility.drainBlock( TileGrate.this.worldObj, fluidCoord.position, doDrain )
this.drainNodes.poll()
if ( fluidStack != null ) {
drainedAmount += fluidStack.amount
if ( drainedAmount >= targetAmount ) {
//break
}
}
}
}
}
TileGrate.this.resetPath()
if ( drainedAmount > 0 ) {
return new FluidStack( fluidType, drainedAmount )
}
null
}
}
}