diff --git a/src/main/java/cr0s/warpdrive/block/BlockAbstractContainer.java b/src/main/java/cr0s/warpdrive/block/BlockAbstractContainer.java index 43ccff2c..c46216d0 100644 --- a/src/main/java/cr0s/warpdrive/block/BlockAbstractContainer.java +++ b/src/main/java/cr0s/warpdrive/block/BlockAbstractContainer.java @@ -1,5 +1,9 @@ package cr0s.warpdrive.block; +import cpw.mods.fml.common.Optional; +import cr0s.warpdrive.config.WarpDriveConfig; +import defense.api.IEMPBlock; +import defense.api.IExplosion; import net.minecraft.block.Block; import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; @@ -14,7 +18,10 @@ import cr0s.warpdrive.WarpDrive; import cr0s.warpdrive.api.IBlockUpdateDetector; import net.minecraftforge.common.util.ForgeDirection; -public abstract class BlockAbstractContainer extends BlockContainer { +@Optional.InterfaceList({ + @Optional.Interface(iface = "defense.api.IEMPBlock", modid = "DefenseTech") +}) +public abstract class BlockAbstractContainer extends BlockContainer implements IEMPBlock { protected boolean isRotating = false; protected BlockAbstractContainer(Material material) { @@ -160,4 +167,24 @@ public abstract class BlockAbstractContainer extends BlockContainer { ((IBlockUpdateDetector) tileEntity).updatedNeighbours(); } } + + @Optional.Method(modid = "DefenseTech") + public void onEMP(World world, int x, int y, int z, IExplosion explosiveEMP) { + if (WarpDriveConfig.LOGGING_WEAPON) { + WarpDrive.logger.info("EMP received at " + x + " " + y + " " + z + " from " + explosiveEMP + " with energy " + explosiveEMP.getEnergy() + " and radius " + explosiveEMP.getRadius()); + } + // EMP tower = 3k Energy, 60 radius + // EMP explosive = 3k Energy, 50 radius + onEMP(world, x, y, z, explosiveEMP.getRadius() / 100.0F); + } + + public void onEMP(World world, final int x, final int y, final int z, final float efficiency) { + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof TileEntityAbstractEnergy) { + TileEntityAbstractEnergy tileEntityAbstractEnergy = (TileEntityAbstractEnergy) tileEntity; + if (tileEntityAbstractEnergy.getMaxEnergyStored() > 0) { + tileEntityAbstractEnergy.consumeEnergy(Math.round(tileEntityAbstractEnergy.getEnergyStored() * efficiency), false); + } + } + } } diff --git a/src/main/java/cr0s/warpdrive/block/forcefield/BlockAbstractForceField.java b/src/main/java/cr0s/warpdrive/block/forcefield/BlockAbstractForceField.java index d7eaf16a..6dfb463b 100644 --- a/src/main/java/cr0s/warpdrive/block/forcefield/BlockAbstractForceField.java +++ b/src/main/java/cr0s/warpdrive/block/forcefield/BlockAbstractForceField.java @@ -3,6 +3,7 @@ package cr0s.warpdrive.block.forcefield; import cr0s.warpdrive.block.BlockAbstractContainer; import cr0s.warpdrive.config.WarpDriveConfig; import net.minecraft.block.material.Material; +import net.minecraft.world.World; public abstract class BlockAbstractForceField extends BlockAbstractContainer { protected byte tier; @@ -23,4 +24,9 @@ public abstract class BlockAbstractForceField extends BlockAbstractContainer { protected boolean canSilkHarvest() { return false; } + + @Override + public void onEMP(World world, final int x, final int y, final int z, final float efficiency) { + super.onEMP(world, x, y, z, efficiency * (1.0F - 0.2F * (tier - 1))); + } } diff --git a/src/main/java/cr0s/warpdrive/block/forcefield/BlockForceField.java b/src/main/java/cr0s/warpdrive/block/forcefield/BlockForceField.java index ecafc41e..b458fbc0 100644 --- a/src/main/java/cr0s/warpdrive/block/forcefield/BlockForceField.java +++ b/src/main/java/cr0s/warpdrive/block/forcefield/BlockForceField.java @@ -9,6 +9,7 @@ import cr0s.warpdrive.config.WarpDriveConfig; import cr0s.warpdrive.data.ForceFieldSetup; import cr0s.warpdrive.data.EnumPermissionNode; import cr0s.warpdrive.data.Vector3; +import cr0s.warpdrive.data.VectorI; import cr0s.warpdrive.render.RenderBlockForceField; import net.minecraft.block.Block; import net.minecraft.block.BlockGlass; @@ -221,6 +222,20 @@ public class BlockForceField extends BlockAbstractForceField implements IDamageR return 0; } + private void downgrade(World world, final int x, final int y, final int z) { + if (tier > 1) { + TileEntityForceFieldProjector tileEntityForceFieldProjector = getProjector(world, x, y, z); + world.setBlock(x, y, z, WarpDrive.blockForceFields[tier - 2], (world.getBlockMetadata(x, y, z) + 1) % 16, 2); + TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof TileEntityForceField) { + ((TileEntityForceField) tileEntity).setProjector(new VectorI(tileEntityForceFieldProjector)); + } + + } else { + world.setBlockToAir(x, y, z); + } + } + private double log_explosionX; private double log_explosionY = -1; private double log_explosionZ; @@ -306,22 +321,21 @@ public class BlockForceField extends BlockAbstractForceField implements IDamageR @Override public void onBlockExploded(World world, int x, int y, int z, Explosion explosion) { - if (tier > 0) { - world.setBlock(x, y, z, WarpDrive.blockForceFields[tier - 1], (world.getBlockMetadata(x, y, z) + 1) % 16, 2); - super.onBlockDestroyedByExplosion(world, x, y, z, explosion); - return; - } + downgrade(world, x, y, z); super.onBlockExploded(world, x, y, z, explosion); } + public void onEMP(World world, final int x, final int y, final int z, final float efficiency) { + if (efficiency > 0.0F) { + downgrade(world, x, y, z); + } + // already handled => no ancestor call + } + @Override public void onBlockDestroyedByExplosion(World world, int x, int y, int z, Explosion explosion) { // (block is already set to air by caller, see IC2 iTNT for example) - if (tier > 1) { - world.setBlock(x, y, z, WarpDrive.blockForceFields[tier - 2], (world.getBlockMetadata(x, y, z) + 1) % 16, 2); - super.onBlockDestroyedByExplosion(world, x, y, z, explosion); - return; - } + downgrade(world, x, y, z); super.onBlockDestroyedByExplosion(world, x, y, z, explosion); } diff --git a/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceField.java b/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceField.java index 3afc86be..70e6ef7d 100644 --- a/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceField.java +++ b/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceField.java @@ -102,10 +102,12 @@ public class TileEntityForceField extends TileEntityAbstractBase { ForceFieldSetup forceFieldSetup = getForceFieldSetup(); if (forceFieldSetup != null) { cache_beamFrequency = forceFieldSetup.beamFrequency; - cache_blockCamouflage = forceFieldSetup.getCamouflageBlock(); - cache_metadataCamouflage = forceFieldSetup.getCamouflageMetadata(); - cache_colorMultiplierCamouflage = forceFieldSetup.getCamouflageColorMultiplier(); - cache_lightCamouflage = forceFieldSetup.getCamouflageLight(); + if (getBlockMetadata() == forceFieldSetup.getCamouflageMetadata()) { + cache_blockCamouflage = forceFieldSetup.getCamouflageBlock(); + cache_metadataCamouflage = forceFieldSetup.getCamouflageMetadata(); + cache_colorMultiplierCamouflage = forceFieldSetup.getCamouflageColorMultiplier(); + cache_lightCamouflage = forceFieldSetup.getCamouflageLight(); + } } worldObj.markBlockForUpdate(xCoord, yCoord, zCoord); } @@ -119,16 +121,16 @@ public class TileEntityForceField extends TileEntityAbstractBase { return tileEntityForceFieldProjector; } else if (tileEntityForceFieldProjector.isPartOfForceField(new VectorI(this))) { - if (tileEntityForceFieldProjector.isOn()) { - return tileEntityForceFieldProjector; - } else { - // projector is disabled or out of power - worldObj.setBlockToAir(xCoord, yCoord, zCoord); - if (WarpDriveConfig.LOGGING_FORCEFIELD) { - WarpDrive.logger.info("Removed a force field from an offline projector at " - + (worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName()) + " " + xCoord + " " + yCoord + " " + zCoord); - } - } + if (tileEntityForceFieldProjector.isOn()) { + return tileEntityForceFieldProjector; + } else { + // projector is disabled or out of power + worldObj.setBlockToAir(xCoord, yCoord, zCoord); + if (WarpDriveConfig.LOGGING_FORCEFIELD) { + WarpDrive.logger.info("Removed a force field from an offline projector at " + + (worldObj == null ? "~NULL~" : worldObj.getWorldInfo().getWorldName()) + " " + xCoord + " " + yCoord + " " + zCoord); + } + } } } } diff --git a/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java b/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java index 8f97cfcd..983a5351 100644 --- a/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java +++ b/src/main/java/cr0s/warpdrive/block/forcefield/TileEntityForceFieldProjector.java @@ -343,7 +343,8 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField Block block; boolean doProjectThisBlock; - while (countScanned < countMaxScanned && countPlaced < countMaxPlaced + while ( countScanned < countMaxScanned + && countPlaced < countMaxPlaced && consumeEnergy(Math.max(forceFieldSetup.scanEnergyCost, forceFieldSetup.placeEnergyCost), true)) { if (iteratorForcefield == null || !iteratorForcefield.hasNext()) { iteratorForcefield = calculated_forceField.iterator(); @@ -388,9 +389,10 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField // recover force field blocks if (block instanceof BlockForceField) { - // remove block if its missing a valid tile entity TileEntity tileEntity = vector.getTileEntity(worldObj); if (!(tileEntity instanceof TileEntityForceField)) { + // missing a valid tile entity + // => force a new placement worldObj.setBlockToAir(vector.x, vector.y, vector.z); block = Blocks.air; @@ -398,18 +400,24 @@ public class TileEntityForceFieldProjector extends TileEntityAbstractForceField TileEntityForceField tileEntityForceField = ((TileEntityForceField)tileEntity); TileEntityForceFieldProjector tileEntityForceFieldProjector = tileEntityForceField.getProjector(); if (tileEntityForceFieldProjector == null) { - // orphan force field, probably from an explosion => recover it + // orphan force field, probably from an explosion + // => recover it tileEntityForceField.setProjector(new VectorI(this)); tileEntityForceField.cache_blockCamouflage = forceFieldSetup.getCamouflageBlock(); tileEntityForceField.cache_metadataCamouflage = forceFieldSetup.getCamouflageMetadata(); worldObj.setBlockMetadataWithNotify(vector.x, vector.y, vector.z, tileEntityForceField.cache_metadataCamouflage, 2); - } else if ( tileEntityForceFieldProjector == this - && ( tileEntityForceField.cache_blockCamouflage != forceFieldSetup.getCamouflageBlock() - || tileEntityForceField.cache_metadataCamouflage != forceFieldSetup.getCamouflageMetadata() ) ) { - // camouflage changed while chunk was loaded or de-synchronisation => force a new placement - worldObj.setBlockToAir(vector.x, vector.y, vector.z); - block = Blocks.air; + } else if (tileEntityForceFieldProjector == this) {// this is ours + if ( tileEntityForceField.cache_blockCamouflage != forceFieldSetup.getCamouflageBlock() + || tileEntityForceField.cache_metadataCamouflage != forceFieldSetup.getCamouflageMetadata() + || block != WarpDrive.blockForceFields[tier - 1] + || vector.getBlockMetadata(worldObj) != metadataForceField ) { + // camouflage changed while chunk wasn't loaded or de-synchronisation + // force field downgraded during explosion + // => force a new placement + worldObj.setBlockToAir(vector.x, vector.y, vector.z); + block = Blocks.air; + } } } }