diff --git a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractEnergy.java b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractEnergy.java index 25b8a8dd..4e925f9f 100644 --- a/src/main/java/cr0s/warpdrive/block/TileEntityAbstractEnergy.java +++ b/src/main/java/cr0s/warpdrive/block/TileEntityAbstractEnergy.java @@ -3,6 +3,7 @@ package cr0s.warpdrive.block; import java.math.BigDecimal; import java.util.HashMap; +import cr0s.warpdrive.WarpDrive; import ic2.api.energy.event.EnergyTileLoadEvent; import ic2.api.energy.event.EnergyTileUnloadEvent; import ic2.api.energy.tile.IEnergySink; @@ -72,12 +73,20 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa return (int) Math.round(energy / RF_PER_INTERNAL); } - protected static double convertInternalToEU(int energy) { - return Math.round(energy * EU_PER_INTERNAL); + protected static double convertInternalToEU_ceil(int energy) { + return Math.ceil(energy * EU_PER_INTERNAL); } - protected static int convertEUtoInternal(double amount) { - return (int) Math.round(amount / EU_PER_INTERNAL); + protected static double convertInternalToEU_floor(int energy) { + return Math.floor(energy * EU_PER_INTERNAL); + } + + protected static int convertEUtoInternal_ceil(double amount) { + return (int) Math.ceil(amount / EU_PER_INTERNAL); + } + + protected static int convertEUtoInternal_floor(double amount) { + return (int) Math.floor(amount / EU_PER_INTERNAL); } public int getEnergyStored() { @@ -174,14 +183,15 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa return ""; } return StatCollector.translateToLocalFormatted("warpdrive.energy.statusLine", - BigDecimal.valueOf(convertInternalToEU(getEnergyStored())).toPlainString(), - BigDecimal.valueOf(convertInternalToEU(getMaxEnergyStored())).toPlainString()); + BigDecimal.valueOf(convertInternalToEU_floor(getEnergyStored())).toPlainString(), + BigDecimal.valueOf(convertInternalToEU_floor(getMaxEnergyStored())).toPlainString()); } + @Override public String getStatus() { - return StatCollector.translateToLocalFormatted("warpdrive.guide.prefix", - getBlockType().getLocalizedName()) - + getEnergyStatus(); + String strEnergyStatus = getEnergyStatus(); + return super.getStatus() + + (strEnergyStatus.isEmpty() ? "" : "\n" + strEnergyStatus); } // OpenComputer callback methods @@ -251,21 +261,28 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa @Override @Optional.Method(modid = "IC2") public double getDemandedEnergy() { - return Math.max(0.0D, convertInternalToEU(getMaxEnergyStored() - getEnergyStored())); + return Math.max(0.0D, convertInternalToEU_floor(getMaxEnergyStored() - getEnergyStored())); } @Override @Optional.Method(modid = "IC2") public double injectEnergy(ForgeDirection from, double amount_EU, double voltage) { - int leftover_internal = 0; - energyStored_internal += convertEUtoInternal(amount_EU); - - if (energyStored_internal > getMaxEnergyStored()) { - leftover_internal = (energyStored_internal - getMaxEnergyStored()); - energyStored_internal = getMaxEnergyStored(); + if (WarpDriveConfig.LOGGING_ENERGY) { + WarpDrive.logger.info(this + " [IC2]injectEnergy from " + from + " amount_EU " + amount_EU + " " + voltage); + } + if (canInputEnergy(from)) { + int leftover_internal = 0; + energyStored_internal += convertEUtoInternal_floor(amount_EU); + + if (energyStored_internal > getMaxEnergyStored()) { + leftover_internal = (energyStored_internal - getMaxEnergyStored()); + energyStored_internal = getMaxEnergyStored(); + } + + return convertInternalToEU_ceil(leftover_internal); + } else { + return amount_EU; } - - return convertInternalToEU(leftover_internal); } @Override @@ -278,18 +295,24 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa @Override @Optional.Method(modid = "IC2") public double getOfferedEnergy() { - return convertInternalToEU(getPotentialEnergyOutput()); + return convertInternalToEU_floor(getPotentialEnergyOutput()); } @Override @Optional.Method(modid = "IC2") public void drawEnergy(double amount_EU) { - energyOutputDone(convertEUtoInternal(amount_EU)); + if (WarpDriveConfig.LOGGING_ENERGY) { + WarpDrive.logger.info(this + " [IC2]drawEnergy amount_EU " + amount_EU); + } + energyOutputDone(convertEUtoInternal_ceil(amount_EU)); } @Override @Optional.Method(modid = "IC2") public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection to) { + if (WarpDriveConfig.LOGGING_ENERGY) { + WarpDrive.logger.info(this + " [IC2]emitsEnergyTo receiver " + receiver + " to " + to); + } return canOutputEnergy(to); } @@ -326,6 +349,9 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa @Override @Optional.Method(modid = "CoFHCore") /* IEnergyReceiver */ public int receiveEnergy(ForgeDirection from, int maxReceive_RF, boolean simulate) { + if (WarpDriveConfig.LOGGING_ENERGY) { + WarpDrive.logger.info(this + " [CoFH]receiveEnergy from " + from + " maxReceive_RF " + maxReceive_RF + " simulate " + simulate); + } if (!canInputEnergy(from)) { return 0; } @@ -347,6 +373,9 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa @Override @Optional.Method(modid = "CoFHCore") /* IEnergyProvider */ public int extractEnergy(ForgeDirection from, int maxExtract_RF, boolean simulate) { + if (WarpDriveConfig.LOGGING_ENERGY) { + WarpDrive.logger.info(this + " [CoFH]extractEnergy from " + from + " maxExtract_RF " + maxExtract_RF + " simulate " + simulate); + } if (!canOutputEnergy(from)) { return 0; } @@ -355,7 +384,6 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa int energyExtracted_internal = Math.min(convertRFtoInternal(maxExtract_RF), potentialEnergyOutput_internal); if (!simulate) { energyOutputDone(energyExtracted_internal); - // WarpDrive.debugPrint("extractEnergy Potential " + potentialEnergyOutput_internal + " EU, Requested " + maxExtract_RF + " RF, energyExtracted_internal " + energyExtracted_internal + "(" + convertInternalToRF(energyExtracted_internal) + " RF)"); } return convertInternalToRF(energyExtracted_internal); } @@ -363,7 +391,7 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa @Override @Optional.Method(modid = "CoFHCore") /* IEnergyConnection */ public boolean canConnectEnergy(ForgeDirection from) { - return (getMaxEnergyStored() != 0) && (canInputEnergy(from) || canOutputEnergy(from)); // FIXME deadlock risk + return (getMaxEnergyStored() != 0) && (canInputEnergy(from) || canOutputEnergy(from)); // Warning: deadlock risk depending on child implementation } @Override @@ -385,13 +413,15 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa if (energyReceiver == null || worldObj.getTileEntity(xCoord + from.offsetX, yCoord + from.offsetY, zCoord + from.offsetZ) == null) { return; } + if (!canOutputEnergy(from)) { + return; + } int potentialEnergyOutput_internal = getPotentialEnergyOutput(); if (potentialEnergyOutput_internal > 0) { int energyToOutput_RF = energyReceiver.receiveEnergy(from.getOpposite(), convertInternalToRF(potentialEnergyOutput_internal), true); if (energyToOutput_RF > 0) { int energyOutputted_RF = energyReceiver.receiveEnergy(from.getOpposite(), energyToOutput_RF, false); energyOutputDone(convertRFtoInternal(energyOutputted_RF)); - // WarpDrive.debugPrint("ForcedOutputEnergy Potential " + potentialEnergyOutput_internal + " EU, Actual output " + energyOutputted_RF + " RF, simulated at " + energyToOutput_RF + " RF"); } } } @@ -443,6 +473,9 @@ public abstract class TileEntityAbstractEnergy extends TileEntityAbstractInterfa @Optional.Method(modid = "CoFHCore") private void scanForEnergyHandlers() { + if (WarpDriveConfig.LOGGING_ENERGY) { + WarpDrive.logger.info(this + " [CoFH]scanForEnergyHandlers"); + } for (ForgeDirection from : ForgeDirection.VALID_DIRECTIONS) { boolean energyReceiverFound = false; if (canConnectEnergy(from)) { diff --git a/src/main/java/cr0s/warpdrive/block/energy/BlockEnergyBank.java b/src/main/java/cr0s/warpdrive/block/energy/BlockEnergyBank.java index 7fbef2d4..371165b2 100644 --- a/src/main/java/cr0s/warpdrive/block/energy/BlockEnergyBank.java +++ b/src/main/java/cr0s/warpdrive/block/energy/BlockEnergyBank.java @@ -1,16 +1,24 @@ package cr0s.warpdrive.block.energy; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import cr0s.warpdrive.item.ItemTuningFork; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumFacing; import net.minecraft.util.IIcon; +import net.minecraft.util.StatCollector; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import cr0s.warpdrive.WarpDrive; import cr0s.warpdrive.block.BlockAbstractContainer; public class BlockEnergyBank extends BlockAbstractContainer { - private IIcon iconBuffer; + @SideOnly(Side.CLIENT) + private IIcon[] icons; public BlockEnergyBank() { super(Material.iron); @@ -23,13 +31,26 @@ public class BlockEnergyBank extends BlockAbstractContainer { } @Override - public IIcon getIcon(int side, int meta) { - return iconBuffer; + public void registerBlockIcons(IIconRegister iconRegister) { + icons = new IIcon[3]; + icons[0] = iconRegister.registerIcon("warpdrive:energy/energyBank"); + icons[1] = iconRegister.registerIcon("warpdrive:energy/energyBankInput"); + icons[2] = iconRegister.registerIcon("warpdrive:energy/energyBankOutput"); } @Override - public void registerBlockIcons(IIconRegister par1IconRegister) { - iconBuffer = par1IconRegister.registerIcon("warpdrive:energy/energyBank"); + public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity == null || !(tileEntity instanceof TileEntityEnergyBank)) { + return icons[0]; + } + + return icons[((TileEntityEnergyBank) tileEntity).getMode(EnumFacing.getFront(side))]; + } + + @Override + public IIcon getIcon(int side, int metadata) { + return icons[side == 1 ? 1 : 2]; } @Override @@ -38,11 +59,36 @@ public class BlockEnergyBank extends BlockAbstractContainer { return false; } - if (entityPlayer.getHeldItem() == null) { - TileEntity tileEntity = world.getTileEntity(x, y, z); - if (tileEntity instanceof TileEntityEnergyBank) { - WarpDrive.addChatMessage(entityPlayer, ((TileEntityEnergyBank) tileEntity).getStatus()); - return true; + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (!(tileEntity instanceof TileEntityEnergyBank)) { + return false; + } + TileEntityEnergyBank tileEntityEnergyBank = (TileEntityEnergyBank) tileEntity; + ItemStack itemStackHeld = entityPlayer.getHeldItem(); + EnumFacing facing = EnumFacing.getFront(side); + + if (itemStackHeld == null) { + WarpDrive.addChatMessage(entityPlayer, tileEntityEnergyBank.getStatus()); + return true; + } else if (itemStackHeld.getItem() instanceof ItemTuningFork) { + tileEntityEnergyBank.setMode(facing, (byte)((tileEntityEnergyBank.getMode(facing) + 1) % 3)); + switch (tileEntityEnergyBank.getMode(facing)) { + case TileEntityEnergyBank.MODE_INPUT: + WarpDrive.addChatMessage(entityPlayer, StatCollector.translateToLocalFormatted("warpdrive.guide.prefix", + getLocalizedName()) + + StatCollector.translateToLocalFormatted("warpdrive.energy.side.changedToInput", facing.name())); + return true; + case TileEntityEnergyBank.MODE_OUTPUT: + WarpDrive.addChatMessage(entityPlayer, StatCollector.translateToLocalFormatted("warpdrive.guide.prefix", + getLocalizedName()) + + StatCollector.translateToLocalFormatted("warpdrive.energy.side.changedToOutput", facing.name())); + return true; + case TileEntityEnergyBank.MODE_DISABLED: + default: + WarpDrive.addChatMessage(entityPlayer, StatCollector.translateToLocalFormatted("warpdrive.guide.prefix", + getLocalizedName()) + + StatCollector.translateToLocalFormatted("warpdrive.energy.side.changedToDisabled", facing.name())); + return true; } } diff --git a/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnergyBank.java b/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnergyBank.java index fbf1f4db..efe9cecb 100644 --- a/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnergyBank.java +++ b/src/main/java/cr0s/warpdrive/block/energy/TileEntityEnergyBank.java @@ -1,40 +1,96 @@ package cr0s.warpdrive.block.energy; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.NetworkManager; +import net.minecraft.network.Packet; +import net.minecraft.network.play.server.S35PacketUpdateTileEntity; +import net.minecraft.util.EnumFacing; import net.minecraftforge.common.util.ForgeDirection; import cr0s.warpdrive.block.TileEntityAbstractEnergy; import cr0s.warpdrive.config.WarpDriveConfig; public class TileEntityEnergyBank extends TileEntityAbstractEnergy { - + + static final byte MODE_DISABLED = 0; + static final byte MODE_INPUT = 1; + static final byte MODE_OUTPUT = 2; + private static final byte[] MODE_DEFAULT_SIDES = { MODE_INPUT, MODE_INPUT, MODE_OUTPUT, MODE_OUTPUT, MODE_OUTPUT, MODE_OUTPUT }; + private byte[] modeSide = MODE_DEFAULT_SIDES.clone(); + public TileEntityEnergyBank() { super(); IC2_sinkTier = 0; IC2_sourceTier = 0; peripheralName = "warpdriveEnergyBank"; } - + @Override public int getPotentialEnergyOutput() { return getEnergyStored(); } - + @Override protected void energyOutputDone(int energyOutput) { consumeEnergy(energyOutput, false); } - + @Override public int getMaxEnergyStored() { return WarpDriveConfig.ENERGY_BANK_MAX_ENERGY_STORED; } - + @Override public boolean canInputEnergy(ForgeDirection from) { - return true; + return modeSide[from.ordinal()] == MODE_INPUT; } - + @Override public boolean canOutputEnergy(ForgeDirection to) { - return true; + return modeSide[to.ordinal()] == MODE_OUTPUT; + } + + byte getMode(final EnumFacing facing) { + return modeSide[facing.ordinal()]; + } + + void setMode(final EnumFacing facing, final byte mode) { + modeSide[facing.ordinal()] = (byte)(mode % 3); + markDirty(); + } + + // Forge overrides + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + nbt.setByteArray("modeSide", modeSide); + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + modeSide = nbt.getByteArray("modeSide"); + if (modeSide == null || modeSide.length != 6) { + modeSide = MODE_DEFAULT_SIDES.clone(); + } + } + + @Override + public NBTTagCompound writeItemDropNBT(NBTTagCompound nbtTagCompound) { + nbtTagCompound = super.writeItemDropNBT(nbtTagCompound); + return nbtTagCompound; + } + + @Override + public Packet getDescriptionPacket() { + NBTTagCompound tagCompound = new NBTTagCompound(); + writeToNBT(tagCompound); + return new S35PacketUpdateTileEntity(xCoord, yCoord, zCoord, 1, tagCompound); + } + + @Override + public void onDataPacket(NetworkManager networkManager, S35PacketUpdateTileEntity packet) { + NBTTagCompound tagCompound = packet.func_148857_g(); + readFromNBT(tagCompound); + worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } } \ No newline at end of file diff --git a/src/main/java/cr0s/warpdrive/compat/CompatWarpDrive.java b/src/main/java/cr0s/warpdrive/compat/CompatWarpDrive.java new file mode 100644 index 00000000..8e528593 --- /dev/null +++ b/src/main/java/cr0s/warpdrive/compat/CompatWarpDrive.java @@ -0,0 +1,76 @@ +package cr0s.warpdrive.compat; + +import cr0s.warpdrive.api.IBlockTransformer; +import cr0s.warpdrive.api.ITransformation; +import cr0s.warpdrive.block.energy.TileEntityEnergyBank; +import cr0s.warpdrive.config.WarpDriveConfig; +import net.minecraft.block.Block; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +public class CompatWarpDrive implements IBlockTransformer { + + public static void register() { + WarpDriveConfig.registerBlockTransformer("WarpDrive", new CompatWarpDrive()); + } + + @Override + public boolean isApplicable(final Block block, final int metadata, final TileEntity tileEntity) { + return tileEntity instanceof TileEntityEnergyBank; + } + + @Override + public boolean isJumpReady(final Block block, final int metadata, final TileEntity tileEntity, StringBuilder reason) { + return true; + } + + @Override + public NBTBase saveExternals(final TileEntity tileEntity) { + // nothing to do + return null; + } + + @Override + public void remove(TileEntity tileEntity) { + // nothing to do + } + + private static final short[] mrot = { 0, 1, 5, 4, 2, 3, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; + + private byte[] rotate_byteArray(final byte rotationSteps, final byte[] data) { + byte[] newData = data.clone(); + for (int index = 0; index < data.length; index++) { + switch (rotationSteps) { + case 1: + newData[mrot[index]] = data[index]; + break; + case 2: + newData[mrot[mrot[index]]] = data[index]; + break; + case 3: + newData[mrot[mrot[mrot[index]]]] = data[index]; + break; + default: + break; + } + } + return newData; + } + + @Override + public int rotate(final Block block, final int metadata, NBTTagCompound nbtTileEntity, final ITransformation transformation) { + byte rotationSteps = transformation.getRotationSteps(); + + // Energy bank sides + if (nbtTileEntity.hasKey("modeSide")) { + nbtTileEntity.setByteArray("modeSide", rotate_byteArray(rotationSteps, nbtTileEntity.getByteArray("modeSide"))); + } + return metadata; + } + + @Override + public void restoreExternals(TileEntity tileEntity, ITransformation transformation, NBTBase nbtBase) { + // nothing to do + } +} diff --git a/src/main/java/cr0s/warpdrive/config/Recipes.java b/src/main/java/cr0s/warpdrive/config/Recipes.java index a5e2e9a0..904c01f3 100644 --- a/src/main/java/cr0s/warpdrive/config/Recipes.java +++ b/src/main/java/cr0s/warpdrive/config/Recipes.java @@ -1297,6 +1297,13 @@ public class Recipes { 'g', "paneGlassColorless", 'h', "blockHull2_plain")); + // Anuic Energy bank is 1 capacitive crystal + 1 MV Machine casing + 3 Power interfaces + GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(WarpDrive.blockEnergyBank), false, "pip", "pcp", "pmp", + 'c', ItemComponent.getItemStack(EnumComponentType.CAPACITIVE_CRYSTAL), + 'm', itemStackMachineCasings[1], + 'i', ItemComponent.getItemStack(EnumComponentType.COMPUTER_INTERFACE), + 'p', ItemComponent.getItemStack(EnumComponentType.POWER_INTERFACE))); + // Force field projector is 1 or 2 Electromagnetic Projector + 1 LV/MV/HV Machine casing + 1 Ender crystal + 1 Redstone for (int tier = 1; tier <= 3; tier++) { int index = tier - 1; diff --git a/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java b/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java index 4007f324..7e8489d0 100644 --- a/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java +++ b/src/main/java/cr0s/warpdrive/config/WarpDriveConfig.java @@ -157,8 +157,8 @@ public class WarpDriveConfig { public static int RADAR_SCAN_MIN_DELAY_SECONDS = 1; public static double[] RADAR_SCAN_DELAY_FACTORS_SECONDS = { 1.0, 0.001, 0.0, 0.0 }; public static int RADAR_MAX_ISOLATION_RANGE = 2; - public static int RADAR_MIN_ISOLATION_BLOCKS = 5; - public static int RADAR_MAX_ISOLATION_BLOCKS = 60; + public static int RADAR_MIN_ISOLATION_BLOCKS = 2; + public static int RADAR_MAX_ISOLATION_BLOCKS = 16; public static double RADAR_MIN_ISOLATION_EFFECT = 0.12; public static double RADAR_MAX_ISOLATION_EFFECT = 1.00; @@ -752,6 +752,8 @@ public class WarpDriveConfig { } public static void onFMLInitialization() { + CompatWarpDrive.register(); + isForgeMultipartLoaded = Loader.isModLoaded("ForgeMultipart"); if (isForgeMultipartLoaded) { isForgeMultipartLoaded = CompatForgeMultipart.register();