/*
* Copyright (c) CovertJaguar, 2014 http://railcraft.info
*
* This code is the property of CovertJaguar
* and may only be used with explicit written
* permission unless otherwise specified on the
* license page at http://railcraft.info/wiki/info:license.
*/
package mods.railcraft.common.blocks.machine.alpha;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import mods.railcraft.common.blocks.RailcraftBlocks;
import net.minecraft.world.biome.BiomeGenBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.inventory.Slot;
import net.minecraft.util.IIcon;
import net.minecraftforge.common.util.ForgeDirection;
import mods.railcraft.common.blocks.machine.IEnumMachine;
import mods.railcraft.common.blocks.machine.MultiBlockPattern;
import mods.railcraft.common.blocks.machine.TileMultiBlock;
import mods.railcraft.common.blocks.machine.TileTank;
import mods.railcraft.common.gui.EnumGui;
import mods.railcraft.common.gui.GuiHandler;
import mods.railcraft.common.gui.slots.SlotWaterOrEmpty;
import mods.railcraft.common.plugins.forge.LocalizationPlugin;
import mods.railcraft.common.fluids.FluidHelper;
import mods.railcraft.common.util.inventory.InvTools;
import mods.railcraft.common.util.inventory.wrappers.InventoryMapper;
import mods.railcraft.common.fluids.Fluids;
import mods.railcraft.common.fluids.TankManager;
import mods.railcraft.common.fluids.tanks.FilteredTank;
import mods.railcraft.common.util.misc.Game;
import mods.railcraft.common.util.misc.ITileFilter;
import net.minecraft.inventory.ISidedInventory;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidHandler;
/**
*
* @author CovertJaguar <http://www.railcraft.info>
*/
public class TileTankWater extends TileTank implements ISidedInventory {
public static void placeWaterTank(World world, int x, int y, int z, int water) {
for (MultiBlockPattern pattern : TileTankWater.patterns) {
Map<Character, Integer> blockMapping = new HashMap<Character, Integer>();
blockMapping.put('B', EnumMachineAlpha.TANK_WATER.ordinal());
TileEntity tile = pattern.placeStructure(world, x, y, z, RailcraftBlocks.getBlockMachineAlpha(), blockMapping);
if (tile instanceof TileTankWater) {
TileTankWater master = (TileTankWater) tile;
master.tank.setFluid(Fluids.WATER.get(water));
}
return;
}
}
private final static int OUTPUT_RATE = 40;
private final static int TANK_CAPACITY = FluidHelper.BUCKET_VOLUME * 400;
private final static int REFILL_INTERVAL = 8;
private final static float REFILL_RATE = 10f;
private final static float REFILL_PENALTY_INSIDE = 0.5f;
private final static float REFILL_PENALTY_SNOW = 0.5f;
private final static float REFILL_BOOST_RAIN = 3.0f;
private final static byte REFILL_RATE_MIN = 1;
private final static int SLOT_INPUT = 0;
private final static int SLOT_OUTPUT = 1;
private final static int[] SLOTS = InvTools.buildSlotArray(0, 2);
private final static ForgeDirection[] LIQUID_OUTPUTS = {ForgeDirection.DOWN, ForgeDirection.EAST, ForgeDirection.WEST, ForgeDirection.NORTH, ForgeDirection.SOUTH};
private final static ITileFilter LIQUID_OUTPUT_FILTER = new ITileFilter() {
@Override
public boolean matches(TileEntity tile) {
if (tile instanceof TileTank)
return false;
else if (tile instanceof IFluidHandler)
return true;
return false;
}
};
private final static List<MultiBlockPattern> patterns = new ArrayList<MultiBlockPattern>();
private IInventory invInput = new InventoryMapper(this, SLOT_INPUT, 1);
private IInventory invOutput = new InventoryMapper(this, SLOT_OUTPUT, 1);
private final FilteredTank tank;
static {
char[][][] map = {
{
{'O', 'O', 'O', 'O', 'O'},
{'O', 'O', 'O', 'O', 'O'},
{'O', 'O', 'O', 'O', 'O'},
{'O', 'O', 'O', 'O', 'O'},
{'O', 'O', 'O', 'O', 'O'}
},
{
{'O', 'O', 'O', 'O', 'O'},
{'O', 'B', 'B', 'B', 'O'},
{'O', 'B', 'B', 'B', 'O'},
{'O', 'B', 'B', 'B', 'O'},
{'O', 'O', 'O', 'O', 'O'}
},
{
{'O', 'O', 'O', 'O', 'O'},
{'O', 'B', 'B', 'B', 'O'},
{'O', 'B', 'A', 'B', 'O'},
{'O', 'B', 'B', 'B', 'O'},
{'O', 'O', 'O', 'O', 'O'}
},
{
{'O', 'O', 'O', 'O', 'O'},
{'O', 'B', 'B', 'B', 'O'},
{'O', 'B', 'B', 'B', 'O'},
{'O', 'B', 'B', 'B', 'O'},
{'O', 'O', 'O', 'O', 'O'}
},
{
{'O', 'O', 'O', 'O', 'O'},
{'O', 'O', 'O', 'O', 'O'},
{'O', 'O', 'O', 'O', 'O'},
{'O', 'O', 'O', 'O', 'O'},
{'O', 'O', 'O', 'O', 'O'}
},};
patterns.add(new MultiBlockPattern(map, 2, 1, 2));
}
public TileTankWater() {
super("gui.tank.water", 2, patterns);
tank = new FilteredTank(TANK_CAPACITY, Fluids.WATER.get(), this);
tankManager.add(tank);
}
@Override
public IEnumMachine getMachineType() {
return EnumMachineAlpha.TANK_WATER;
}
@Override
public String getTitle() {
return LocalizationPlugin.translate("railcraft.gui.tank.water");
}
@Override
public Slot getInputSlot(IInventory inv, int id, int x, int y) {
return new SlotWaterOrEmpty(inv, id, x, y);
}
@Override
public boolean blockActivated(EntityPlayer player, int side) {
if (Game.isHost(worldObj)) {
if (isStructureValid() && FluidHelper.handleRightClick(getTankManager(), ForgeDirection.getOrientation(side), player, true, true))
return true;
} else if (FluidHelper.isContainer(player.inventory.getCurrentItem()))
return true;
return super.blockActivated(player, side);
}
@Override
public void updateEntity() {
super.updateEntity();
if (Game.isHost(getWorld())) {
if (isMaster()) {
if (worldObj.provider.dimensionId != -1 && clock % REFILL_INTERVAL == 0) {
float rate = REFILL_RATE;
BiomeGenBase biome = worldObj.getBiomeGenForCoords(xCoord, zCoord);
float humidity = biome.rainfall;
rate *= humidity;
// String debug = "Biome=" + biome.biomeName + ", Humidity=" + humidity;
boolean outside = false;
for (int x = xCoord - 1; x <= xCoord + 1; x++) {
for (int z = zCoord - 1; z <= zCoord + 1; z++) {
outside = worldObj.canBlockSeeTheSky(x, yCoord + 3, z);
// System.out.println(x + ", " + (yCoord + 3) + ", " + z);
if (outside)
break;
}
}
// debug += ", Outside=" + outside;
if (!outside)
rate *= REFILL_PENALTY_INSIDE;
else if (worldObj.isRaining())
if (biome.getEnableSnow())
rate *= REFILL_PENALTY_SNOW; // debug += ", Snow=true";
else
rate *= REFILL_BOOST_RAIN; // debug += ", Rain=true";
int rateFinal = MathHelper.floor_float(rate);
if (rateFinal < REFILL_RATE_MIN)
rateFinal = REFILL_RATE_MIN;
// debug += ", Refill=" + rateFinal;
// System.out.println(debug);
FluidStack fillStack = Fluids.WATER.get(rateFinal);
fill(ForgeDirection.UP, fillStack, true);
}
if (clock % FluidHelper.BUCKET_FILL_TIME == 0)
FluidHelper.processContainers(tankManager.get(0), this, SLOT_INPUT, SLOT_OUTPUT);
}
TankManager tMan = getTankManager();
if (tMan != null)
tMan.outputLiquid(tileCache, LIQUID_OUTPUT_FILTER, LIQUID_OUTPUTS, 0, OUTPUT_RATE);
}
}
@Override
public boolean openGui(EntityPlayer player) {
TileMultiBlock mBlock = getMasterBlock();
if (mBlock != null) {
GuiHandler.openGui(EnumGui.TANK, player, worldObj, mBlock.xCoord, mBlock.yCoord, mBlock.zCoord);
return true;
}
return false;
}
@Override
public IIcon getIcon(int side) {
return EnumMachineAlpha.TANK_WATER.getTexture(side);
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
if (from != ForgeDirection.UP || resource == null || !Fluids.WATER.is(resource))
return 0;
return super.fill(from, resource, doFill);
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
if (resource == null || !Fluids.WATER.is(resource))
return null;
return super.drain(from, resource.amount, doDrain);
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid) {
return from == ForgeDirection.UP && Fluids.WATER.is(fluid);
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
return from != ForgeDirection.UP && Fluids.WATER.is(fluid);
}
@Override
public int[] getAccessibleSlotsFromSide(int side) {
return SLOTS;
}
@Override
public boolean canInsertItem(int slot, ItemStack stack, int side) {
return isItemValidForSlot(slot, stack);
}
@Override
public boolean canExtractItem(int slot, ItemStack stack, int side) {
return slot == SLOT_OUTPUT;
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
switch (slot) {
case SLOT_INPUT:
return FluidHelper.isEmptyContainer(stack) || FluidHelper.containsFluid(stack, Fluids.WATER.get());
}
return false;
}
}