Merge pull request #1862 from Prototik/builder-fluid

Make Builder support fluids via containers/pipes
This commit is contained in:
SpaceToad 2014-06-02 18:16:10 +02:00
commit fd926ff0e0
23 changed files with 408 additions and 202 deletions

View file

@ -6,29 +6,26 @@
* License 1.0, or MMPL. Please check the contents of the license located in
* http://www.mod-buildcraft.com/MMPL-1.0.txt
*/
package buildcraft.builders.schematics;
package buildcraft.api.blueprints;
import java.util.LinkedList;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidContainerRegistry;
import buildcraft.api.blueprints.IBuilderContext;
import buildcraft.api.blueprints.SchematicBlock;
import net.minecraftforge.fluids.FluidStack;
public class SchematicFluid extends SchematicBlock {
private final ItemStack bucketStack;
private final ItemStack fluidItem;
public SchematicFluid(ItemStack bucketStack) {
this.bucketStack = bucketStack;
public SchematicFluid(FluidStack fluidStack) {
this.fluidItem = new ItemStack(fluidStack.getFluid().getBlock(), 1);
}
@Override
public void writeRequirementsToWorld(IBuilderContext context, LinkedList<ItemStack> requirements) {
if (meta == 0) {
requirements.add(bucketStack.copy());
requirements.add(fluidItem);
}
}
@ -74,11 +71,9 @@ public class SchematicFluid extends SchematicBlock {
public LinkedList<ItemStack> getStacksToDisplay(
LinkedList<ItemStack> stackConsumed) {
ItemStack s = new ItemStack(FluidContainerRegistry
.getFluidForFilledItem(bucketStack).getFluid().getBlock());
LinkedList<ItemStack> result = new LinkedList<ItemStack>();
result.add(s);
result.add(fluidItem);
return result;
}

View file

@ -8,6 +8,7 @@
*/
package buildcraft.api.blueprints;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.HashSet;
@ -16,12 +17,16 @@ import net.minecraft.block.Block;
import net.minecraft.block.ITileEntityProvider;
import net.minecraft.entity.Entity;
import net.minecraft.init.Blocks;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import buildcraft.api.core.JavaTools;
public final class SchematicRegistry {
public static double BREAK_ENERGY = 10;
@ -45,40 +50,75 @@ public final class SchematicRegistry {
}
private static class SchematicConstructor {
Class<? extends SchematicEntity> clas;
Object [] params;
}
public final Class<? extends Schematic> clazz;
public final Object[] params;
public static void registerSchematicBlock (Block block, Class clas, Object ... params) {
explicitSchematicBlocks.add(block);
internalRegisterSchematicBlock(block, clas, params);
}
private final Constructor constructor;
private static void internalRegisterSchematicBlock (Block block, Class clas, Object ... params) {
if (schematicBlocks.containsKey(block)) {
throw new RuntimeException("Block " + Block.blockRegistry.getNameForObject(block)
+ " is already associated with a schematic.");
SchematicConstructor(Class<? extends Schematic> clazz, Object[] params) throws IllegalArgumentException {
this.clazz = clazz;
this.params = params;
this.constructor = findConstructor();
}
SchematicConstructor c = new SchematicConstructor ();
c.clas = clas;
c.params = params;
public Schematic newInstance() throws IllegalAccessException, InvocationTargetException, InstantiationException {
return (Schematic) constructor.newInstance(params);
}
schematicBlocks.put(block, c);
private Constructor findConstructor() throws IllegalArgumentException {
for (Constructor<?> c : clazz.getConstructors()) {
Class<?>[] typesSignature = c.getParameterTypes();
if (typesSignature.length != params.length) {
// non-matching constructor count arguments, skip
continue;
}
boolean valid = true;
for (int i = 0; i < params.length; i++) {
if (params[i] == null) {
// skip checking for null parameters
continue;
}
Class<?> paramClass = params[i].getClass();
if (!(typesSignature[i].isAssignableFrom(paramClass)
|| (typesSignature[i] == int.class && paramClass == Integer.class)
|| (typesSignature[i] == double.class && paramClass == Double.class)
|| (typesSignature[i] == boolean.class && paramClass == Boolean.class))) {
// constructor has non assignable parameters skip constructor...
valid = false;
break;
}
}
if (!valid) {
continue;
}
return c;
}
throw new IllegalArgumentException("Could not find matching constructor for class " + clazz);
}
}
public static void registerSchematicBlock(Block block, Class<? extends Schematic> clazz, Object... params) {
explicitSchematicBlocks.add(block);
internalRegisterSchematicBlock(block, clazz, params);
}
private static void internalRegisterSchematicBlock(Block block, Class<? extends Schematic> clazz, Object... params) {
if (schematicBlocks.containsKey(block)) {
throw new RuntimeException("Block " + Block.blockRegistry.getNameForObject(block) + " is already associated with a schematic.");
}
schematicBlocks.put(block, new SchematicConstructor(clazz, params));
}
public static void registerSchematicEntity(
Class<? extends Entity> entityClass,
Class<? extends SchematicEntity> schematicClass, Object... params) {
SchematicConstructor c = new SchematicConstructor ();
c.clas = schematicClass;
c.params = params;
schematicEntities.put(entityClass, c);
if (schematicEntities.containsKey(entityClass)) {
throw new RuntimeException("Entity " + entityClass.getName() + " is already associated with a schematic.");
}
schematicEntities.put(entityClass, new SchematicConstructor(schematicClass, params));
}
public static SchematicBlock newSchematicBlock (Block block) {
public static SchematicBlock newSchematicBlock(Block block) {
if (block == Blocks.air) {
return null;
}
@ -87,24 +127,27 @@ public final class SchematicRegistry {
if (block instanceof ITileEntityProvider) {
internalRegisterSchematicBlock(block, SchematicTile.class);
} else {
internalRegisterSchematicBlock(block, SchematicBlock.class);
Fluid fluid = FluidRegistry.lookupFluidForBlock(block);
if (fluid != null) {
internalRegisterSchematicBlock(block, SchematicFluid.class, new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME));
} else {
internalRegisterSchematicBlock(block, SchematicBlock.class);
}
}
}
try {
SchematicConstructor c = schematicBlocks.get(block);
SchematicBlock s = (SchematicBlock) c.clas.getConstructors() [0].newInstance(c.params);
SchematicBlock s = (SchematicBlock) c.newInstance();
s.block = block;
return s;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (SecurityException e) {
} catch (InstantiationException e) {
e.printStackTrace();
}
@ -118,45 +161,39 @@ public final class SchematicRegistry {
try {
SchematicConstructor c = schematicEntities.get(entityClass);
SchematicEntity s = (SchematicEntity) c.clas.getConstructors() [0].newInstance(c.params);
SchematicEntity s = (SchematicEntity) c.newInstance();
s.entity = entityClass;
return s;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (SecurityException e) {
} catch (InstantiationException e) {
e.printStackTrace();
}
return null;
}
public static void declareBlueprintSupport (String modid) {
public static void declareBlueprintSupport(String modid) {
modsSupporting.add(modid);
}
public static boolean isExplicitlySupported (Block block) {
String modid = Block.blockRegistry.getNameForObject(block).split(":") [0];
return explicitSchematicBlocks.contains(block) || modsSupporting.contains(modid);
public static boolean isExplicitlySupported(Block block) {
return explicitSchematicBlocks.contains(block) || modsSupporting.contains(Block.blockRegistry.getNameForObject(block).split(":", 2)[0]);
}
public static boolean isAllowedForBuilding (Block block) {
public static boolean isAllowedForBuilding(Block block) {
String name = Block.blockRegistry.getNameForObject(block);
String modid = name.split(":") [0];
return !modsForbidden.contains(modid) && !blocksForbidden.contains(name);
return !blocksForbidden.contains(name) && !modsForbidden.contains(name.split(":", 2)[0]);
}
public static void readConfiguration (Configuration conf) {
Property excludedMods = conf.get(Configuration.CATEGORY_GENERAL, "builder.excludedMods", new String [0],
public static void readConfiguration(Configuration conf) {
Property excludedMods = conf.get(Configuration.CATEGORY_GENERAL, "builder.excludedMods", new String[0],
"mods that should be excluded from the builder.");
Property excludedBlocks = conf.get(Configuration.CATEGORY_GENERAL, "builder.excludedBlocks", new String [0],
Property excludedBlocks = conf.get(Configuration.CATEGORY_GENERAL, "builder.excludedBlocks", new String[0],
"blocks that should be excluded from the builder.");
for (String id : excludedMods.getStringList()) {
@ -177,6 +214,6 @@ public final class SchematicRegistry {
}
static {
modsSupporting.add ("minecraft");
modsSupporting.add("minecraft");
}
}

View file

@ -91,6 +91,7 @@ gate.trigger.pipe.wire.inactive=%s Pipe Signal Off
gate.trigger.timer=%s Sec Timer
gui.building.resources=Building Resources
gui.building.fluids=Fluid Tanks
gui.del=Del
gui.filling.resources=Filling Resources
gui.inventory=Inventory

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View file

@ -92,7 +92,6 @@ import buildcraft.builders.schematics.SchematicFactoryEntity;
import buildcraft.builders.schematics.SchematicFactoryMask;
import buildcraft.builders.schematics.SchematicFarmland;
import buildcraft.builders.schematics.SchematicFire;
import buildcraft.builders.schematics.SchematicFluid;
import buildcraft.builders.schematics.SchematicGlassPane;
import buildcraft.builders.schematics.SchematicGravel;
import buildcraft.builders.schematics.SchematicHanging;
@ -320,11 +319,6 @@ public class BuildCraftBuilders extends BuildCraftMod {
SchematicRegistry.registerSchematicBlock(Blocks.redstone_lamp, SchematicRedstoneLamp.class);
SchematicRegistry.registerSchematicBlock(Blocks.lit_redstone_lamp, SchematicRedstoneLamp.class);
SchematicRegistry.registerSchematicBlock(Blocks.water, SchematicFluid.class, new ItemStack(Items.water_bucket));
SchematicRegistry.registerSchematicBlock(Blocks.flowing_water, SchematicFluid.class, new ItemStack(Items.water_bucket));
SchematicRegistry.registerSchematicBlock(Blocks.lava, SchematicFluid.class, new ItemStack(Items.lava_bucket));
SchematicRegistry.registerSchematicBlock(Blocks.flowing_lava, SchematicFluid.class, new ItemStack(Items.lava_bucket));
SchematicRegistry.registerSchematicBlock(Blocks.glass_pane, SchematicGlassPane.class);
SchematicRegistry.registerSchematicBlock(Blocks.stained_glass_pane, SchematicGlassPane.class);

View file

@ -30,6 +30,7 @@ import buildcraft.BuildCraftBuilders;
import buildcraft.api.tools.IToolWrench;
import buildcraft.core.CreativeTabBuildCraft;
import buildcraft.core.GuiIds;
import buildcraft.core.fluids.FluidUtils;
import buildcraft.core.utils.Utils;
public class BlockBuilder extends BlockContainer {
@ -75,6 +76,9 @@ public class BlockBuilder extends BlockContainer {
return false;
}
TileEntity tile = world.getTileEntity(i, j, k);
TileBuilder builder = tile instanceof TileBuilder ? (TileBuilder) tile : null;
Item equipped = entityplayer.getCurrentEquippedItem() != null ? entityplayer.getCurrentEquippedItem().getItem() : null;
if (equipped instanceof IToolWrench && ((IToolWrench) equipped).canWrench(entityplayer, i, j, k)) {
@ -99,6 +103,8 @@ public class BlockBuilder extends BlockContainer {
world.markBlockForUpdate(i, j, k);
((IToolWrench) equipped).wrenchUsed(entityplayer, i, j, k);
return true;
} else if (builder != null && FluidUtils.handleRightClick(builder, ForgeDirection.UNKNOWN, entityplayer, true, false)) {
return true;
} else {
if (!world.isRemote) {

View file

@ -22,6 +22,11 @@ import net.minecraft.world.WorldSettings.GameType;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import buildcraft.BuildCraftBuilders;
import buildcraft.api.blueprints.BuildingPermission;
@ -40,19 +45,30 @@ import buildcraft.core.blueprints.BptBuilderBase;
import buildcraft.core.blueprints.BptBuilderBlueprint;
import buildcraft.core.blueprints.BptBuilderTemplate;
import buildcraft.core.blueprints.BptContext;
import buildcraft.core.fluids.Tank;
import buildcraft.core.fluids.TankManager;
import buildcraft.core.inventory.InvUtils;
import buildcraft.core.inventory.SimpleInventory;
import buildcraft.core.network.RPC;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.network.RPCMessageInfo;
import buildcraft.core.network.RPCSide;
public class TileBuilder extends TileAbstractBuilder implements IMachine {
public class TileBuilder extends TileAbstractBuilder implements IMachine, IFluidHandler {
private static int POWER_ACTIVATION = 50;
@NetworkData
public Box box = new Box();
public PathIterator currentPathIterator;
public Tank[] fluidTanks = new Tank[] {
new Tank("fluid1", FluidContainerRegistry.BUCKET_VOLUME * 8, this),
new Tank("fluid2", FluidContainerRegistry.BUCKET_VOLUME * 8, this),
new Tank("fluid3", FluidContainerRegistry.BUCKET_VOLUME * 8, this),
new Tank("fluid4", FluidContainerRegistry.BUCKET_VOLUME * 8, this)
};
@NetworkData
public TankManager<Tank> fluidTank = new TankManager<Tank>(fluidTanks);
private SimpleInventory inv = new SimpleInventory(28, "Builder", 64);
private BptBuilderBase bluePrintBuilder;
@ -493,6 +509,7 @@ public class TileBuilder extends TileAbstractBuilder implements IMachine {
}
done = nbttagcompound.getBoolean("done");
fluidTank.readFromNBT(nbttagcompound);
// The rest of load has to be done upon initialize.
initNBT = (NBTTagCompound) nbttagcompound.getCompoundTag("bptBuilder").copy();
@ -523,6 +540,7 @@ public class TileBuilder extends TileAbstractBuilder implements IMachine {
}
nbttagcompound.setBoolean("done", done);
fluidTank.writeToNBT(nbttagcompound);
NBTTagCompound bptNBT = new NBTTagCompound();
@ -603,7 +621,7 @@ public class TileBuilder extends TileAbstractBuilder implements IMachine {
@Override
public boolean manageFluids() {
return false;
return true;
}
@Override
@ -724,4 +742,83 @@ public class TileBuilder extends TileAbstractBuilder implements IMachine {
}
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
return false;
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
return null;
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
return null;
}
public boolean drainBuild(FluidStack fluidStack, boolean realDrain) {
for (Tank tank : fluidTanks) {
if (tank.getFluidType() == fluidStack.getFluid()) {
return tank.getFluidAmount() >= fluidStack.amount && tank.drain(fluidStack.amount, realDrain).amount > 0;
}
}
return false;
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
Fluid fluid = resource.getFluid();
Tank emptyTank = null;
for (Tank tank : fluidTanks) {
Fluid type = tank.getFluidType();
if (type == fluid) {
int used = tank.fill(resource, doFill);
if (used > 0 && doFill) {
sendNetworkUpdate();
}
return used;
} else if (emptyTank == null && tank.isEmpty()) {
emptyTank = tank;
}
}
if (emptyTank != null) {
int used = emptyTank.fill(resource, doFill);
if (used > 0 && doFill) {
sendNetworkUpdate();
}
return used;
}
return 0;
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid) {
boolean emptyAvailable = false;
for (Tank tank : fluidTanks) {
Fluid type = tank.getFluidType();
if (type == fluid) {
return !tank.isFull();
} else if (!emptyAvailable) {
emptyAvailable = tank.isEmpty();
}
}
return emptyAvailable;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) {
return fluidTank.getTankInfo(from);
}
@RPC(RPCSide.SERVER)
public void eraseFluidTank(int id, RPCMessageInfo info) {
if (id < 0 || id >= fluidTanks.length) {
return;
}
if (isUseableByPlayer(info.sender) && info.sender.getDistanceSq(xCoord, yCoord, zCoord) <= 64) {
fluidTanks[id].setFluid(null);
sendNetworkUpdate();
}
}
}

View file

@ -12,34 +12,38 @@ import java.util.Collection;
import org.lwjgl.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import buildcraft.builders.TileBuilder;
import buildcraft.core.DefaultProps;
import buildcraft.core.fluids.Tank;
import buildcraft.core.gui.AdvancedSlot;
import buildcraft.core.gui.GuiAdvancedInterface;
import buildcraft.core.network.RPCHandler;
import buildcraft.core.utils.StringUtils;
public class GuiBuilder extends GuiAdvancedInterface {
private static final ResourceLocation TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/builder.png");
private static final ResourceLocation BLUEPRINT_TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/builder_blueprint.png");
private static final ResourceLocation FOREGROUND_TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/builder_foreground.png");
private IInventory playerInventory;
private TileBuilder builder;
private int inventoryRows = 6;
private GuiButton selectedButton;
public GuiBuilder(IInventory playerInventory, TileBuilder builder) {
super(new ContainerBuilder(playerInventory, builder), builder, TEXTURE);
super(new ContainerBuilder(playerInventory, builder), builder, BLUEPRINT_TEXTURE);
this.playerInventory = playerInventory;
this.builder = builder;
xSize = 176;
ySize = 225;
slots = new AdvancedSlot[7 * 4];
slots = new AdvancedSlot[6 * 4];
for (int i = 0; i < 7; ++i) {
for (int i = 0; i < 6; ++i) {
for (int j = 0; j < 4; ++j) {
slots[i * 4 + j] = new ItemSlot(179 + j * 18, 18 + i * 18);
}
@ -50,11 +54,11 @@ public class GuiBuilder extends GuiAdvancedInterface {
protected void drawGuiContainerForegroundLayer(int par1, int par2) {
super.drawGuiContainerForegroundLayer(par1, par2);
String title = StringUtils.localize("tile.builderBlock.name");
fontRendererObj.drawString(title, getCenteredOffset(title), 12, 0x404040);
drawCenteredString(StringUtils.localize("tile.builderBlock.name"), 178 / 2, 16, 0x404040);
fontRendererObj.drawString(StringUtils.localize("gui.building.resources"), 8, 60, 0x404040);
fontRendererObj.drawString(StringUtils.localize("gui.inventory"), 8, ySize - 97, 0x404040);
fontRendererObj.drawString(StringUtils.localize("gui.needed"), 185, 7, 0x404040);
fontRendererObj.drawString(StringUtils.localize("gui.needed"), 178, 7, 0x404040);
fontRendererObj.drawString(StringUtils.localize("gui.building.fluids"), 178, 133, 0x404040);
drawForegroundSelection(par1, par2);
}
@ -62,19 +66,9 @@ public class GuiBuilder extends GuiAdvancedInterface {
@Override
protected void drawGuiContainerBackgroundLayer(float f, int x, int y) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
int j = (width - xSize) / 2;
int k = (height - ySize) / 2;
int realXSize = 0;
// if (builder.isBuildingBlueprint()) {
mc.renderEngine.bindTexture(BLUEPRINT_TEXTURE);
realXSize = 256;
// } else {
// mc.renderEngine.bindTexture(TEXTURE);
// realXSize = 176;
// }
drawTexturedModalRect(j, k, 0, 0, realXSize, ySize);
mc.renderEngine.bindTexture(BLUEPRINT_TEXTURE);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, 256, ySize);
for (int s = 0; s < slots.length; ++s) {
((ItemSlot) slots[s]).stack = null;
@ -96,5 +90,68 @@ public class GuiBuilder extends GuiAdvancedInterface {
}
drawBackgroundSlots();
for (int i = 0; i < builder.fluidTanks.length; i++) {
Tank tank = builder.fluidTanks[i];
drawFluid(tank.getFluid(), guiLeft + 179 + 18 * i, guiTop + 145, 16, 47, tank.getCapacity());
}
mc.renderEngine.bindTexture(FOREGROUND_TEXTURE);
for (int i = 0; i < builder.fluidTanks.length; i++) {
drawTexturedModalRect(guiLeft + 179 + 18 * i, guiTop + 145, 0, 54, 16, 47);
}
}
@Override
public void initGui() {
super.initGui();
for (int i = 0; i < 4; i++) {
buttonList.add(new BuilderEraseButton(i, guiLeft + 178 + 18 * i, guiTop + 197, 18, 18));
}
}
@Override
protected void mouseMovedOrUp(int mouseX, int mouseY, int eventType) {
super.mouseMovedOrUp(mouseX, mouseY, eventType);
if (this.selectedButton != null && eventType == 0) {
this.selectedButton.mouseReleased(mouseX, mouseY);
this.selectedButton = null;
}
}
private class BuilderEraseButton extends GuiButton {
private boolean clicked;
public BuilderEraseButton(int id, int x, int y, int width, int height) {
super(id, x, y, width, height, null);
}
@Override
public boolean mousePressed(Minecraft mc, int x, int y) {
if (super.mousePressed(mc, x, y)) {
selectedButton = this;
clicked = true;
RPCHandler.rpcServer(builder, "eraseFluidTank", id);
return true;
} else {
return false;
}
}
@Override
public void mouseReleased(int x, int y) {
super.mouseReleased(x, y);
clicked = false;
}
@Override
public void drawButton(Minecraft mc, int x, int y) {
// hovered
this.field_146123_n = x >= this.xPosition && y >= this.yPosition && x < this.xPosition + this.width && y < this.yPosition + this.height;
mc.renderEngine.bindTexture(FOREGROUND_TEXTURE);
drawTexturedModalRect(xPosition, yPosition, 0, (clicked ? 1 : this.field_146123_n ? 2 : 0) * 18, 18, 18);
mouseDragged(mc, x, y);
}
}
}

View file

@ -19,12 +19,17 @@ import java.util.TreeSet;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraft.world.WorldSettings.GameType;
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 buildcraft.api.blueprints.Schematic;
import buildcraft.api.blueprints.SchematicBlock;
@ -35,6 +40,7 @@ import buildcraft.api.core.BuildCraftAPI;
import buildcraft.api.core.IInvSlot;
import buildcraft.api.core.StackKey;
import buildcraft.builders.TileAbstractBuilder;
import buildcraft.builders.TileBuilder;
import buildcraft.core.BlockIndex;
import buildcraft.core.blueprints.BuildingSlotBlock.Mode;
import buildcraft.core.inventory.InventoryCopy;
@ -45,6 +51,7 @@ import buildcraft.core.utils.BlockUtil;
public class BptBuilderBlueprint extends BptBuilderBase {
public LinkedList<ItemStack> neededItems = new LinkedList<ItemStack>();
public LinkedList<FluidStack> neededFluids = new LinkedList<FluidStack>();
protected TreeSet<Integer> builtEntities = new TreeSet<Integer>();
@ -422,14 +429,27 @@ public class BptBuilderBlueprint extends BptBuilderBase {
}
for (ItemStack reqStk : tmpReq) {
boolean itemBlock = reqStk.getItem() instanceof ItemBlock;
Fluid fluid = itemBlock ? FluidRegistry.lookupFluidForBlock(((ItemBlock) reqStk.getItem()).field_150939_a) : null;
if (fluid != null && builder instanceof TileBuilder && ((TileBuilder) builder).drainBuild(new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME), true)) {
continue;
}
for (IInvSlot slotInv : InventoryIterator.getIterable(new InventoryCopy(builder), ForgeDirection.UNKNOWN)) {
if (!builder.isBuildingMaterialSlot(slotInv.getIndex())) {
continue;
}
ItemStack invStk = slotInv.getStackInSlot();
if (invStk == null || invStk.stackSize == 0) {
continue;
}
if (invStk != null && invStk.stackSize > 0 && StackHelper.isCraftingEquivalent(reqStk, invStk, true)) {
FluidStack fluidStack = fluid != null ? FluidContainerRegistry.getFluidForFilledItem(invStk) : null;
boolean compatibleContainer = fluidStack != null && fluidStack.getFluid() == fluid && fluidStack.amount >= FluidContainerRegistry.BUCKET_VOLUME;
if (StackHelper.isCraftingEquivalent(reqStk, invStk, true) || compatibleContainer) {
try {
stacksUsed.add(slot.useItem(context, reqStk, slotInv));
} catch (Throwable t) {
@ -485,6 +505,13 @@ public class BptBuilderBlueprint extends BptBuilderBase {
boolean smallStack = reqStk.stackSize == 1;
ItemStack usedStack = reqStk;
boolean itemBlock = reqStk.getItem() instanceof ItemBlock;
Fluid fluid = itemBlock ? FluidRegistry.lookupFluidForBlock(((ItemBlock) reqStk.getItem()).field_150939_a) : null;
if (fluid != null && builder instanceof TileBuilder && ((TileBuilder) builder).drainBuild(new FluidStack(fluid, FluidContainerRegistry.BUCKET_VOLUME), true)) {
continue;
}
for (IInvSlot slotInv : InventoryIterator.getIterable(builder, ForgeDirection.UNKNOWN)) {
if (!builder.isBuildingMaterialSlot(slotInv.getIndex())) {
continue;
@ -492,7 +519,14 @@ public class BptBuilderBlueprint extends BptBuilderBase {
ItemStack invStk = slotInv.getStackInSlot();
if (invStk != null && invStk.stackSize > 0 && StackHelper.isCraftingEquivalent(reqStk, invStk, true)) {
if (invStk == null || invStk.stackSize == 0) {
continue;
}
FluidStack fluidStack = fluid != null ? FluidContainerRegistry.getFluidForFilledItem(invStk) : null;
boolean fluidFound = fluidStack != null && fluidStack.getFluid() == fluid && fluidStack.amount >= FluidContainerRegistry.BUCKET_VOLUME;
if (fluidFound || StackHelper.isCraftingEquivalent(reqStk, invStk, true)) {
try {
usedStack = slot.getSchematic().useItem(context, reqStk, slotInv);
slot.addStackConsumed (usedStack);
@ -524,6 +558,7 @@ public class BptBuilderBlueprint extends BptBuilderBase {
public void recomputeNeededItems() {
neededItems.clear();
neededFluids.clear();
HashMap<StackKey, Integer> computeStacks = new HashMap<StackKey, Integer>();
@ -589,31 +624,12 @@ public class BptBuilderBlueprint extends BptBuilderBase {
for (Entry<StackKey, Integer> e : computeStacks.entrySet()) {
ItemStack newStack = e.getKey().stack.copy();
newStack.stackSize = e.getValue();
neededItems.add(newStack);
}
LinkedList<ItemStack> sortedList = new LinkedList<ItemStack>();
for (ItemStack toInsert : neededItems) {
int index = 0;
boolean didInsert = false;
for (ItemStack inserted : sortedList) {
if (inserted.stackSize < toInsert.stackSize) {
sortedList.add(index, toInsert);
didInsert = true;
break;
}
index++;
}
if (!didInsert) {
sortedList.addLast(toInsert);
}
}
Collections.sort (neededItems, new Comparator<ItemStack>() {
@Override
public int compare(ItemStack o1, ItemStack o2) {

View file

@ -34,7 +34,7 @@ public final class FluidUtils {
}
public static boolean handleRightClick(IFluidHandler tank, ForgeDirection side, EntityPlayer player, boolean fill, boolean drain) {
if (player == null) {
if (player == null || tank == null) {
return false;
}
ItemStack current = player.inventory.getCurrentItem();

View file

@ -18,8 +18,9 @@ import net.minecraftforge.fluids.FluidTank;
import buildcraft.core.gui.tooltips.ToolTip;
import buildcraft.core.gui.tooltips.ToolTipLine;
import buildcraft.core.network.INBTSerializable;
public class Tank extends FluidTank {
public class Tank extends FluidTank implements INBTSerializable {
public int colorRenderCache = 0xFFFFFF;
protected final ToolTip toolTip = new ToolTip() {
@ -61,6 +62,9 @@ public class Tank extends FluidTank {
@Override
public final FluidTank readFromNBT(NBTTagCompound nbt) {
if (nbt.hasKey(name)) {
// allow to read empty tanks
setFluid(null);
NBTTagCompound tankData = nbt.getCompoundTag(name);
super.readFromNBT(tankData);
readTankFromNBT(tankData);
@ -89,4 +93,16 @@ public class Tank extends FluidTank {
}
toolTip.add(new ToolTipLine(String.format(Locale.ENGLISH, "%,d / %,d", amount, getCapacity())));
}
@Override
public NBTTagCompound serializeNBT() {
NBTTagCompound nbt = new NBTTagCompound();
writeToNBT(nbt);
return nbt;
}
@Override
public void serializeNBT(NBTTagCompound nbt) {
readFromNBT(nbt);
}
}

View file

@ -27,7 +27,9 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
public class TankManager<T extends Tank> extends ForwardingList<T> implements IFluidHandler, List<T> {
import buildcraft.core.network.INBTSerializable;
public class TankManager<T extends Tank> extends ForwardingList<T> implements IFluidHandler, List<T>, INBTSerializable {
private List<T> tanks = new ArrayList<T>();
@ -139,4 +141,16 @@ public class TankManager<T extends Tank> extends ForwardingList<T> implements IF
}
}
}
@Override
public NBTTagCompound serializeNBT() {
NBTTagCompound nbt = new NBTTagCompound();
writeToNBT(nbt);
return nbt;
}
@Override
public void serializeNBT(NBTTagCompound nbt) {
readFromNBT(nbt);
}
}

View file

@ -17,6 +17,8 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
@ -24,6 +26,8 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fluids.FluidStack;
import buildcraft.core.DefaultProps;
import buildcraft.core.gui.slots.IPhantomSlot;
import buildcraft.core.gui.tooltips.IToolTipProvider;
@ -114,6 +118,49 @@ public abstract class GuiBuildCraft extends GuiContainer {
}
}
public void drawFluid(FluidStack fluid, int x, int y, int width, int height, int maxCapacity) {
if (fluid == null || fluid.getFluid() == null) {
return;
}
IIcon icon = fluid.getFluid().getIcon(fluid);
mc.renderEngine.bindTexture(TextureMap.locationBlocksTexture);
RenderUtils.setGLColorFromInt(fluid.getFluid().getColor(fluid));
int fullX = width / 16;
int fullY = height / 16;
int lastX = width - fullX * 16;
int lastY = height - fullY * 16;
int level = fluid.amount * height / maxCapacity;
int fullLvl = (height - level) / 16;
int lastLvl = (height - level) - fullLvl * 16;
for (int i = 0; i < fullX; i++) {
for (int j = 0; j < fullY; j++) {
if (j >= fullLvl) {
drawCutIcon(icon, x + i * 16, y + j * 16, 16, 16, j == fullLvl ? lastLvl : 0);
}
}
}
for (int i = 0; i < fullX; i++) {
drawCutIcon(icon, x + i * 16, y + fullY * 16, 16, lastY, fullLvl == fullY ? lastLvl : 0);
}
for (int i = 0; i < fullY; i++) {
if (i >= fullLvl) {
drawCutIcon(icon, x + fullX * 16, y + i * 16, lastX, 16, i == fullLvl ? lastLvl : 0);
}
}
drawCutIcon(icon, x + fullX * 16, y + fullY * 16, lastX, lastY, fullLvl == fullY ? lastLvl : 0);
}
//The magic is here
private void drawCutIcon(IIcon icon, int x, int y, int width, int height, int cut) {
Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
tess.addVertexWithUV(x, y + height, zLevel, icon.getMinU(), icon.getInterpolatedV(height));
tess.addVertexWithUV(x + width, y + height, zLevel, icon.getInterpolatedU(width), icon.getInterpolatedV(height));
tess.addVertexWithUV(x + width, y + cut, zLevel, icon.getInterpolatedU(width), icon.getInterpolatedV(cut));
tess.addVertexWithUV(x, y + cut, zLevel, icon.getMinU(), icon.getInterpolatedV(cut));
tess.draw();
}
@Override
protected void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
@ -143,6 +190,10 @@ public abstract class GuiBuildCraft extends GuiContainer {
ledgerManager.drawLedgers(x, y);
}
public void drawCenteredString(String string, int xCenter, int yCenter, int textColor) {
fontRendererObj.drawString(string, xCenter - fontRendererObj.getStringWidth(string) / 2, yCenter - fontRendererObj.FONT_HEIGHT / 2, textColor);
}
protected int getCenteredOffset(String string) {
return getCenteredOffset(string, xSize);
}

View file

@ -11,7 +11,6 @@ package buildcraft.core.network;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedList;
@ -112,8 +111,6 @@ public final class RPCHandler {
PacketRPCTile packet = handlers.get (tile.getClass().getName()).createRCPPacket(tile, method, actuals);
if (packet != null) {
ArrayList<PacketRPCTile> packets = packet.breakIntoSmallerPackets(30 * 1024);
for (PacketRPCTile p : packet.breakIntoSmallerPackets(MAX_PACKET_SIZE)) {
BuildCraftCore.instance.sendToServer(p);
}

View file

@ -38,10 +38,10 @@ public class GuiHandler implements IGuiHandler {
switch (id) {
case GuiIds.ENGINE_IRON:
return new GuiCombustionEngine(player.inventory, engine);
return new GuiCombustionEngine(player.inventory, (TileEngineIron) engine);
case GuiIds.ENGINE_STONE:
return new GuiStoneEngine(player.inventory, engine);
return new GuiStoneEngine(player.inventory, (TileEngineStone) engine);
default:
return null;

View file

@ -411,8 +411,6 @@ public abstract class TileEngine extends TileBuildCraft implements ISidedBattery
/* STATE INFORMATION */
public abstract boolean isBurning();
public abstract int getScaledBurnTime(int scale);
@Override
public PowerReceiver getPowerReceiver(ForgeDirection side) {
return powerHandler.getPowerReceiver();

View file

@ -111,11 +111,6 @@ public class TileEngineCreative extends TileEngine {
return isRedstonePowered;
}
@Override
public int getScaledBurnTime(int scale) {
return 0;
}
@Override
public float explosionRange() {
return 0;

View file

@ -254,12 +254,6 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan
}
}
@Override
public int getScaledBurnTime(int i) {
return this.tankFuel.getFluid() != null ? (int) (((float) this.tankFuel.getFluid().amount / (float) MAX_LIQUID) * i)
: 0;
}
@Override
public void readFromNBT(NBTTagCompound data) {
super.readFromNBT(data);
@ -280,11 +274,6 @@ public class TileEngineIron extends TileEngineWithInventory implements IFluidHan
}
public int getScaledCoolant(int i) {
return tankCoolant.getFluid() != null ? (int) (((float) tankCoolant.getFluid().amount / (float) MAX_LIQUID) * i)
: 0;
}
@Override
public void getGUINetworkData(int id, int value) {
super.getGUINetworkData(id, value);

View file

@ -104,7 +104,6 @@ public class TileEngineStone extends TileEngineWithInventory {
}
}
@Override
public int getScaledBurnTime(int i) {
return (int) (((float) burnTime / (float) totalBurnTime) * i);
}

View file

@ -87,9 +87,4 @@ public class TileEngineWood extends TileEngine {
public boolean isBurning() {
return isRedstonePowered;
}
@Override
public int getScaledBurnTime(int i) {
return 0;
}
}

View file

@ -8,26 +8,18 @@
*/
package buildcraft.energy.gui;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fluids.FluidStack;
import buildcraft.core.DefaultProps;
import buildcraft.core.render.RenderUtils;
import buildcraft.core.utils.StringUtils;
import buildcraft.energy.TileEngineIron;
import buildcraft.energy.TileEngineWithInventory;
public class GuiCombustionEngine extends GuiEngine {
private static final ResourceLocation TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/combustion_engine_gui.png");
private static final ResourceLocation BLOCK_TEXTURE = TextureMap.locationBlocksTexture;
public GuiCombustionEngine(InventoryPlayer inventoryplayer, TileEngineWithInventory tileEngine) {
public GuiCombustionEngine(InventoryPlayer inventoryplayer, TileEngineIron tileEngine) {
super(new ContainerEngine(inventoryplayer, tileEngine), tileEngine, TEXTURE);
}
@ -45,52 +37,10 @@ public class GuiCombustionEngine extends GuiEngine {
int j = (width - xSize) / 2;
int k = (height - ySize) / 2;
TileEngineIron engine = (TileEngineIron) tile;
drawFluid(engine.getFuel(), engine.getScaledBurnTime(58), j + 104, k + 19, 16, 58);
drawFluid(engine.getCoolant(), engine.getScaledCoolant(58), j + 122, k + 19, 16, 58);
mc.renderEngine.bindTexture(TEXTURE);
drawTexturedModalRect(j + 104, k + 19, 176, 0, 16, 60);
drawTexturedModalRect(j + 122, k + 19, 176, 0, 16, 60);
}
private void drawFluid(FluidStack fluid, int level, int x, int y, int width, int height) {
if (fluid == null || fluid.getFluid() == null) {
return;
}
IIcon icon = fluid.getFluid().getIcon(fluid);
mc.renderEngine.bindTexture(BLOCK_TEXTURE);
RenderUtils.setGLColorFromInt(fluid.getFluid().getColor(fluid));
int fullX = width / 16;
int fullY = height / 16;
int lastX = width - fullX * 16;
int lastY = height - fullY * 16;
int fullLvl = (height - level) / 16;
int lastLvl = (height - level) - fullLvl * 16;
for (int i = 0; i < fullX; i++) {
for (int j = 0; j < fullY; j++) {
if (j >= fullLvl) {
drawCutIcon(icon, x + i * 16, y + j * 16, 16, 16, j == fullLvl ? lastLvl : 0);
}
}
}
for (int i = 0; i < fullX; i++) {
drawCutIcon(icon, x + i * 16, y + fullY * 16, 16, lastY, fullLvl == fullY ? lastLvl : 0);
}
for (int i = 0; i < fullY; i++) {
if (i >= fullLvl) {
drawCutIcon(icon, x + fullX * 16, y + i * 16, lastX, 16, i == fullLvl ? lastLvl : 0);
}
}
drawCutIcon(icon, x + fullX * 16, y + fullY * 16, lastX, lastY, fullLvl == fullY ? lastLvl : 0);
}
//The magic is here
private void drawCutIcon(IIcon icon, int x, int y, int width, int height, int cut) {
Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
tess.addVertexWithUV(x, y + height, zLevel, icon.getMinU(), icon.getInterpolatedV(height));
tess.addVertexWithUV(x + width, y + height, zLevel, icon.getInterpolatedU(width), icon.getInterpolatedV(height));
tess.addVertexWithUV(x + width, y + cut, zLevel, icon.getInterpolatedU(width), icon.getInterpolatedV(cut));
tess.addVertexWithUV(x, y + cut, zLevel, icon.getMinU(), icon.getInterpolatedV(cut));
tess.draw();
drawFluid(engine.getFuel(), j + 104, k + 19, 16, 58, TileEngineIron.MAX_LIQUID);
drawFluid(engine.getCoolant(), j + 122, k + 19, 16, 58, TileEngineIron.MAX_LIQUID);
mc.renderEngine.bindTexture(TEXTURE);
drawTexturedModalRect(j + 104, k + 19, 176, 0, 16, 60);
drawTexturedModalRect(j + 122, k + 19, 176, 0, 16, 60);
}
}

View file

@ -15,14 +15,13 @@ import net.minecraft.util.ResourceLocation;
import buildcraft.core.DefaultProps;
import buildcraft.core.utils.StringUtils;
import buildcraft.energy.TileEngine;
import buildcraft.energy.TileEngineWithInventory;
import buildcraft.energy.TileEngineStone;
public class GuiStoneEngine extends GuiEngine {
private static final ResourceLocation TEXTURE = new ResourceLocation("buildcraft", DefaultProps.TEXTURE_PATH_GUI + "/steam_engine_gui.png");
public GuiStoneEngine(InventoryPlayer inventoryplayer, TileEngineWithInventory tileEngine) {
public GuiStoneEngine(InventoryPlayer inventoryplayer, TileEngineStone tileEngine) {
super(new ContainerEngine(inventoryplayer, tileEngine), tileEngine, TEXTURE);
}
@ -42,7 +41,7 @@ public class GuiStoneEngine extends GuiEngine {
int k = (height - ySize) / 2;
drawTexturedModalRect(j, k, 0, 0, xSize, ySize);
TileEngine engine = (TileEngine) tile;
TileEngineStone engine = (TileEngineStone) tile;
if (engine.getScaledBurnTime(12) > 0) {
int l = engine.getScaledBurnTime(12);