Started converting TileGrate to scala
This commit is contained in:
parent
c734a80f5d
commit
8aadbab7b5
4 changed files with 478 additions and 689 deletions
|
@ -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,9 +56,9 @@ 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 = _
|
||||
|
@ -76,14 +71,11 @@ object Archaic {
|
|||
|
||||
}
|
||||
|
||||
@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 )
|
||||
Settings.config.load()
|
||||
ArchaicBlocks.blockEngineeringTable = contentRegistry.newBlock( classOf[ TileEngineeringTable ] )
|
||||
|
@ -101,22 +93,19 @@ class Archaic {
|
|||
ArchaicItems.itemHandCrank = contentRegistry.createItem( classOf[ ItemHandCrank ] )
|
||||
ArchaicItems.itemImprint = contentRegistry.createItem( classOf[ ItemImprint ] )
|
||||
ArchaicItems.itemHammer = contentRegistry.createItem( classOf[ ItemHammer ] )
|
||||
modproxies.applyModule(classOf[Waila], true)
|
||||
Settings.config.save()
|
||||
proxy.preInit()
|
||||
modproxies.preInit()
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
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)
|
||||
ResonantTab.itemStack = new ItemStack( ArchaicBlocks.blockEngineeringTable )
|
||||
if ( OreDictionary.getOres( "cobblestone" ) == null ) {
|
||||
OreDictionary.registerOre( "cobblestone", Blocks.cobblestone )
|
||||
}
|
||||
|
@ -158,6 +147,5 @@ class Archaic {
|
|||
"stickWood" ) ) )
|
||||
GameRegistry.registerCraftingHandler( new CrateCraftingHandler() )
|
||||
proxy.postInit()
|
||||
modproxies.postInit()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,13 +15,11 @@ import resonant.lib.content.prefab.TRotatable
|
|||
import resonantinduction.core.Reference
|
||||
import universalelectricity.core.transform.vector.Vector3
|
||||
|
||||
object TileTurntable
|
||||
{
|
||||
object TileTurntable {
|
||||
var top : IIcon = null
|
||||
}
|
||||
|
||||
class TileTurntable extends SpatialBlock(Material.piston) with TRotatable with RenderRotatedTexture
|
||||
{
|
||||
class TileTurntable extends SpatialBlock( Material.piston ) with TRotatable with RenderRotatedTexture {
|
||||
textureName = "turntable_side"
|
||||
tickRandomly = true
|
||||
rotationMask = Integer.parseInt( "111111", 2 ).toByte
|
||||
|
@ -29,22 +27,19 @@ class TileTurntable extends SpatialBlock(Material.piston) with TRotatable with R
|
|||
override def tickRate( par1World : World ) : Int = 5
|
||||
|
||||
@SideOnly( Side.CLIENT )
|
||||
override def registerIcons(iconReg: IIconRegister)
|
||||
{
|
||||
override def registerIcons( iconReg : IIconRegister ) {
|
||||
super.registerIcons( iconReg )
|
||||
TileTurntable.top = iconReg.registerIcon( Reference.prefix + "turntable" )
|
||||
}
|
||||
|
||||
override def update()
|
||||
{
|
||||
override def update() {
|
||||
updateTurntableState( world, x, y, z )
|
||||
}
|
||||
|
||||
@SideOnly( Side.CLIENT )
|
||||
override def getIcon( access : IBlockAccess, side : Int ) : IIcon =
|
||||
{
|
||||
if (side == metadata)
|
||||
{
|
||||
if ( side == metadata ) {
|
||||
return TileTurntable.top
|
||||
}
|
||||
|
||||
|
@ -54,38 +49,30 @@ class TileTurntable extends SpatialBlock(Material.piston) with TRotatable with R
|
|||
@SideOnly( Side.CLIENT )
|
||||
override def getIcon( side : Int, meta : Int ) : IIcon =
|
||||
{
|
||||
if (side == 1)
|
||||
{
|
||||
if ( side == 1 ) {
|
||||
return TileTurntable.top
|
||||
}
|
||||
return getIcon
|
||||
}
|
||||
|
||||
override def onNeighborChanged(block: Block)
|
||||
{
|
||||
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
|
||||
{
|
||||
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])
|
||||
{
|
||||
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)
|
||||
{
|
||||
else if ( block != null ) {
|
||||
block.rotateBlock( world, position.xi, position.yi, position.zi, facing.getOpposite )
|
||||
}
|
||||
|
||||
|
@ -93,8 +80,7 @@ class TileTurntable extends SpatialBlock(Material.piston) with TRotatable with R
|
|||
world.playSoundEffect( x + 0.5D, y + 0.5D, z + 0.5D, "tile.piston.in", 0.5F, world.rand.nextFloat * 0.15F + 0.6F )
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
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" ) )
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue