mirror of
https://github.com/HbmMods/Hbm-s-Nuclear-Tech-GIT.git
synced 2026-01-25 10:32:49 +00:00
290 lines
9.7 KiB
Java
290 lines
9.7 KiB
Java
package com.hbm.blocks.bomb;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
|
|
import com.hbm.blocks.IBlockMulti;
|
|
import com.hbm.blocks.ITooltipProvider;
|
|
import com.hbm.blocks.ModBlocks;
|
|
import com.hbm.entity.projectile.EntityShrapnel;
|
|
import com.hbm.explosion.ExplosionNT;
|
|
import com.hbm.explosion.ExplosionNT.ExAttrib;
|
|
import com.hbm.handler.threading.PacketThreading;
|
|
import com.hbm.packet.toclient.AuxParticlePacketNT;
|
|
|
|
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 BlockContainer implements ITooltipProvider, IBlockMulti {
|
|
|
|
public BlockVolcano() {
|
|
super(Material.iron);
|
|
}
|
|
|
|
@Override
|
|
public TileEntity createNewTileEntity(World world, int meta) {
|
|
return new TileEntityVolcanoCore();
|
|
}
|
|
|
|
@Override
|
|
public int getSubCount() {
|
|
return 5;
|
|
}
|
|
|
|
@SideOnly(Side.CLIENT)
|
|
public void getSubBlocks(Item item, CreativeTabs tab, List list) {
|
|
|
|
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"));
|
|
}
|
|
|
|
public static final int META_STATIC_ACTIVE = 0;
|
|
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;
|
|
}
|
|
|
|
public static boolean isExtinguishing(int meta) {
|
|
return meta == META_STATIC_EXTINGUISHING || meta == META_GROWING_EXTINGUISHING;
|
|
}
|
|
|
|
public static class TileEntityVolcanoCore extends TileEntity {
|
|
|
|
private static List<ExAttrib> volcanoExplosion = Arrays.asList(new ExAttrib[] {ExAttrib.NODROP, ExAttrib.LAVA_V, ExAttrib.NOSOUND, ExAttrib.ALLMOD, ExAttrib.NOHURT});
|
|
private static List<ExAttrib> volcanoRadExplosion = Arrays.asList(new ExAttrib[] {ExAttrib.NODROP, ExAttrib.LAVA_R, 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, zCoord, getLava());
|
|
return;
|
|
} else if(this.isExtinguishing()) {
|
|
worldObj.setBlock(xCoord, yCoord, zCoord, getLava());
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean isRadioacitve() {
|
|
return this.getBlockType() == ModBlocks.volcano_rad_core;
|
|
}
|
|
|
|
protected Block getLava() {
|
|
if(isRadioacitve()) return ModBlocks.rad_lava_block;
|
|
return ModBlocks.volcanic_lava_block;
|
|
}
|
|
|
|
protected List<ExAttrib> getExpAttrb() {
|
|
return this.isRadioacitve() ? this.volcanoRadExplosion : this.volcanoExplosion;
|
|
}
|
|
|
|
@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("timer", 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[] {50, 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 10;
|
|
}
|
|
}
|
|
|
|
/** 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(getExpAttrb()).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(getExpAttrb()).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(getExpAttrb()).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() ? this.getLava() : 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) == this.getLava())
|
|
worldObj.setBlock(rX, rY, rZ, this.getLava());
|
|
}
|
|
|
|
/** 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, this.getLava());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/** 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;
|
|
if(this.isRadioacitve()) {
|
|
frag.setRadVolcano(true);
|
|
} else {
|
|
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");
|
|
PacketThreading.createAllAroundThreadedPacket(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));
|
|
}
|
|
}
|
|
}
|