diff --git a/src/main/java/com/hbm/blocks/ModBlocks.java b/src/main/java/com/hbm/blocks/ModBlocks.java index bb9c059d0..9bc08f493 100644 --- a/src/main/java/com/hbm/blocks/ModBlocks.java +++ b/src/main/java/com/hbm/blocks/ModBlocks.java @@ -3321,7 +3321,7 @@ public class ModBlocks { GameRegistry.registerBlock(balefire, balefire.getUnlocalizedName()); GameRegistry.registerBlock(fire_digamma, fire_digamma.getUnlocalizedName()); GameRegistry.registerBlock(digamma_matter, digamma_matter.getUnlocalizedName()); - GameRegistry.registerBlock(volcano_core, ItemBlockVolcano.class, volcano_core.getUnlocalizedName()); + register(volcano_core); //AMS GameRegistry.registerBlock(ams_base, ams_base.getUnlocalizedName()); diff --git a/src/main/java/com/hbm/blocks/bomb/BlockVolcano.java b/src/main/java/com/hbm/blocks/bomb/BlockVolcano.java index 639e11ba8..3bf7e352e 100644 --- a/src/main/java/com/hbm/blocks/bomb/BlockVolcano.java +++ b/src/main/java/com/hbm/blocks/bomb/BlockVolcano.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.List; import java.util.Random; +import com.hbm.blocks.ITooltipProvider; import com.hbm.blocks.ModBlocks; import com.hbm.entity.projectile.EntityShrapnel; import com.hbm.explosion.ExplosionNT; @@ -15,29 +16,52 @@ import cpw.mods.fml.common.network.NetworkRegistry.TargetPoint; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; import net.minecraft.block.material.Material; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; -public class BlockVolcano extends Block { +public class BlockVolcano extends BlockContainer implements ITooltipProvider { public BlockVolcano() { super(Material.iron); } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return new TileEntityVolcanoCore(); + } @SideOnly(Side.CLIENT) public void getSubBlocks(Item item, CreativeTabs tab, List list) { - for(int i = 0; i < 4; ++i) { + for(int i = 0; i < 5; ++i) { list.add(new ItemStack(item, 1, i)); } } - + @Override + public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) { + + int meta = stack.getItemDamage(); + + if(meta == META_SMOLDERING) { + list.add(EnumChatFormatting.GOLD + "SHIELD VOLCANO"); + return; + } + + list.add(BlockVolcano.isGrowing(meta) ? (EnumChatFormatting.RED + "DOES GROW") : (EnumChatFormatting.DARK_GRAY + "DOES NOT GROW")); + list.add(BlockVolcano.isExtinguishing(meta) ? (EnumChatFormatting.RED + "DOES EXTINGUISH") : (EnumChatFormatting.DARK_GRAY + "DOES NOT EXTINGUISH")); + } + + /*@Override public int tickRate(World world) { return 5; } @@ -62,7 +86,7 @@ public class BlockVolcano extends Block { updateVolcano(world, x, y, z, rand, meta); } - } + }*/ private void blastMagmaChannel(World world, int x, int y, int z, Random rand) { @@ -149,6 +173,7 @@ public class BlockVolcano extends Block { public static final int META_STATIC_EXTINGUISHING = 1; public static final int META_GROWING_ACTIVE = 2; public static final int META_GROWING_EXTINGUISHING = 3; + public static final int META_SMOLDERING = 4; public static boolean isGrowing(int meta) { return meta == META_GROWING_ACTIVE || meta == META_GROWING_EXTINGUISHING; @@ -181,4 +206,202 @@ public class BlockVolcano extends Block { return 0; } + + public static class TileEntityVolcanoCore extends TileEntity { + + private static List volcanoExplosion = Arrays.asList(new ExAttrib[] {ExAttrib.NODROP, ExAttrib.LAVA_V, ExAttrib.NOSOUND, ExAttrib.ALLMOD, ExAttrib.NOHURT}); + + public int volcanoTimer; + + @Override + public void updateEntity() { + + if(!worldObj.isRemote) { + this.volcanoTimer++; + + if(this.volcanoTimer % 10 == 0) { + //if that type has a vertical channel, blast it open and raise the magma + if(this.hasVerticalChannel()) { + this.blastMagmaChannel(); + this.raiseMagma(); + } + + double magmaChamber = this.magmaChamberSize(); + if(magmaChamber > 0) this.blastMagmaChamber(magmaChamber); + + Object[] melting = this.surfaceMeltingParams(); + if(melting != null) this.meltSurface((int)melting[0], (double)melting[1], (double)melting[2]); + + //self-explanatory + if(this.isSpewing()) this.spawnBlobs(); + if(this.isSmoking()) this.spawnSmoke(); + + //generates a 3x3x3 cube of lava + this.surroundLava(); + } + + if(this.volcanoTimer >= this.getUpdateRate()) { + this.volcanoTimer = 0; + + if(this.shouldGrow()) { + worldObj.setBlock(xCoord, yCoord + 1, zCoord, this.getBlockType(), this.getBlockMetadata(), 3); + worldObj.setBlock(xCoord, yCoord + 1, zCoord, ModBlocks.volcanic_lava_block); + return; + } else if(this.isExtinguishing()) { + worldObj.setBlock(xCoord, yCoord + 1, zCoord, ModBlocks.volcanic_lava_block); + return; + } + } + } + } + + @Override + public void readFromNBT(NBTTagCompound nbt) { + super.readFromNBT(nbt); + this.volcanoTimer = nbt.getInteger("timer"); + } + + @Override + public void writeToNBT(NBTTagCompound nbt) { + super.writeToNBT(nbt); + nbt.setInteger("tier", this.volcanoTimer); + } + + private boolean shouldGrow() { + return isGrowing() && yCoord < 200; + } + + private boolean isGrowing() { + int meta = this.getBlockMetadata(); + return meta == META_GROWING_ACTIVE || meta == META_GROWING_EXTINGUISHING; + } + + private boolean isExtinguishing() { + int meta = this.getBlockMetadata(); + return meta == META_STATIC_EXTINGUISHING || meta == META_GROWING_EXTINGUISHING; + } + + private boolean isSmoking() { + return this.getBlockMetadata() != META_SMOLDERING; + } + + private boolean isSpewing() { + return this.getBlockMetadata() != META_SMOLDERING; + } + + private boolean hasVerticalChannel() { + return this.getBlockMetadata() != META_SMOLDERING; + } + + private double magmaChamberSize() { + return this.getBlockMetadata() == META_SMOLDERING ? 15 : 0; + } + + /* count per tick, radius, depth */ + private Object[] surfaceMeltingParams() { + return this.getBlockMetadata() == META_SMOLDERING ? new Object[] {2, 50D, 10D} : null; + } + + private int getUpdateRate() { + switch(this.getBlockMetadata()) { + case META_STATIC_EXTINGUISHING: return 60 * 60 * 20; //once per hour + case META_GROWING_ACTIVE: + case META_GROWING_EXTINGUISHING: return 60 * 60 * 20 / 250; //250x per hour + default: return 1; + } + } + + /* TODO */ + private boolean doesPyroclastic() { + return false; + } + + private double getPyroclasticRange() { + return 0D; + } + + /** Causes two magma explosions, one from bedrock to the core and one from the core to 15 blocks above. */ + private void blastMagmaChannel() { + ExplosionNT explosion = new ExplosionNT(worldObj, null, xCoord + 0.5, yCoord + worldObj.rand.nextInt(15) + 1.5, zCoord + 0.5, 7); + explosion.addAllAttrib(volcanoExplosion).explode(); + ExplosionNT explosion2 = new ExplosionNT(worldObj, null, xCoord + 0.5 + worldObj.rand.nextGaussian() * 3, worldObj.rand.nextInt(yCoord + 1), zCoord + 0.5 + worldObj.rand.nextGaussian() * 3, 10); + explosion2.addAllAttrib(volcanoExplosion).explode(); + } + + /** Causes two magma explosions at a random position around the core, one at normal and one at half range. */ + private void blastMagmaChamber(double size) { + + for(int i = 0; i < 2; i++) { + double dist = size / (double) (i + 1); + ExplosionNT explosion = new ExplosionNT(worldObj, null, xCoord + 0.5 + worldObj.rand.nextGaussian() * dist, yCoord + 0.5 + worldObj.rand.nextGaussian() * dist, zCoord + 0.5 + worldObj.rand.nextGaussian() * dist, 7); + explosion.addAllAttrib(volcanoExplosion).explode(); + } + } + + /** Randomly selects surface blocks and converts them into lava if solid or air if not solid. */ + private void meltSurface(int count, double radius, double depth) { + + for(int i = 0; i < count; i++) { + int x = (int) Math.floor(xCoord + worldObj.rand.nextGaussian() * radius); + int z = (int) Math.floor(zCoord + worldObj.rand.nextGaussian() * radius); + //gaussian distribution makes conversions more likely on the surface and rarer at the bottom + int y = worldObj.getHeightValue(x, z) + 1 - (int) Math.floor(Math.abs(worldObj.rand.nextGaussian() * depth)); + + Block b = worldObj.getBlock(x, y, z); + + if(!b.isAir(worldObj, x, y, z) && b.getExplosionResistance(null) < Blocks.obsidian.getExplosionResistance(null)) { + //turn into lava if solid block, otherwise just break + worldObj.setBlock(x, y, z, b.isNormalCube() ? ModBlocks.volcanic_lava_block : Blocks.air); + } + } + } + + /** Increases the magma level in a small radius around the core. */ + private void raiseMagma() { + + int rX = xCoord - 10 + worldObj.rand.nextInt(21); + int rY = yCoord + worldObj.rand.nextInt(11); + int rZ = zCoord - 10 + worldObj.rand.nextInt(21); + + if(worldObj.getBlock(rX, rY, rZ) == Blocks.air && worldObj.getBlock(rX, rY - 1, rZ) == ModBlocks.volcanic_lava_block) + worldObj.setBlock(rX, rY, rZ, ModBlocks.volcanic_lava_block); + } + + /** Creates a 3x3x3 lava sphere around the core. */ + private void surroundLava() { + + for(int i = -1; i <= 1; i++) { + for(int j = -1; j <= 1; j++) { + for(int k = -1; k <= 1; k++) { + + if(i != 0 || j != 0 || k != 0) { + worldObj.setBlock(xCoord + i, yCoord + j, zCoord + k, ModBlocks.volcanic_lava_block); + } + } + } + } + } + + /** Spews specially tagged shrapnels which create volcanic lava and monoxide clouds. */ + private void spawnBlobs() { + + for(int i = 0; i < 3; i++) { + EntityShrapnel frag = new EntityShrapnel(worldObj); + frag.setLocationAndAngles(xCoord + 0.5, yCoord + 1.5, zCoord + 0.5, 0.0F, 0.0F); + frag.motionY = 1D + worldObj.rand.nextDouble(); + frag.motionX = worldObj.rand.nextGaussian() * 0.2D; + frag.motionZ = worldObj.rand.nextGaussian() * 0.2D; + frag.setVolcano(true); + worldObj.spawnEntityInWorld(frag); + } + } + + /** I SEE SMOKE, AND WHERE THERE'S SMOKE THERE'S FIRE! */ + private void spawnSmoke() { + NBTTagCompound dPart = new NBTTagCompound(); + dPart.setString("type", "vanillaExt"); + dPart.setString("mode", "volcano"); + PacketDispatcher.wrapper.sendToAllAround(new AuxParticlePacketNT(dPart, xCoord + 0.5, yCoord + 10, zCoord + 0.5), new TargetPoint(worldObj.provider.dimensionId, xCoord + 0.5, yCoord + 10, zCoord + 0.5, 250)); + } + } } diff --git a/src/main/java/com/hbm/items/block/ItemBlockVolcano.java b/src/main/java/com/hbm/items/block/ItemBlockVolcano.java deleted file mode 100644 index 40e7ea8c5..000000000 --- a/src/main/java/com/hbm/items/block/ItemBlockVolcano.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.hbm.items.block; - -import java.util.List; - -import com.hbm.blocks.bomb.BlockVolcano; - -import net.minecraft.block.Block; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.item.ItemBlock; -import net.minecraft.item.ItemStack; -import net.minecraft.util.EnumChatFormatting; - -public class ItemBlockVolcano extends ItemBlock { - - public ItemBlockVolcano(Block block) { - super(block); - this.setMaxDamage(0); - this.setHasSubtypes(true); - } - - public int getMetadata(int meta) { - return meta; - } - - @Override - public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean bool) { - - int meta = stack.getItemDamage(); - - list.add(BlockVolcano.isGrowing(meta) ? (EnumChatFormatting.RED + "DOES GROW") : (EnumChatFormatting.DARK_GRAY + "DOES NOT GROW")); - list.add(BlockVolcano.isExtinguishing(meta) ? (EnumChatFormatting.RED + "DOES EXTINGUISH") : (EnumChatFormatting.DARK_GRAY + "DOES NOT EXTINGUISH")); - } -} diff --git a/src/main/java/com/hbm/tileentity/TileMappings.java b/src/main/java/com/hbm/tileentity/TileMappings.java index b98da7dd4..b9cac98db 100644 --- a/src/main/java/com/hbm/tileentity/TileMappings.java +++ b/src/main/java/com/hbm/tileentity/TileMappings.java @@ -2,6 +2,7 @@ package com.hbm.tileentity; import java.util.HashMap; +import com.hbm.blocks.bomb.BlockVolcano.TileEntityVolcanoCore; import com.hbm.blocks.generic.BlockBobble.TileEntityBobble; import com.hbm.blocks.generic.BlockEmitter.TileEntityEmitter; import com.hbm.blocks.generic.BlockLoot.TileEntityLoot; @@ -224,6 +225,7 @@ public class TileMappings { put(TileEntityNukeN2.class, "tileentity_nuke_n2"); put(TileEntityNukeCustom.class, "tileentity_nuke_custom"); put(TileEntityCharge.class, "tileentity_explosive_charge"); + put(TileEntityVolcanoCore.class, "tileentity_volcano_core"); } private static void putTurrets() {