summaryrefslogtreecommitdiff
path: root/src/main/java/ihl/explosion
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/ihl/explosion')
-rw-r--r--src/main/java/ihl/explosion/ChunkAndWorldLoadEventHandler.java59
-rw-r--r--src/main/java/ihl/explosion/DetonatorMiniGUI.java82
-rw-r--r--src/main/java/ihl/explosion/ExplosionEntityFX.java177
-rw-r--r--src/main/java/ihl/explosion/ExplosionRenderFX.java52
-rw-r--r--src/main/java/ihl/explosion/ExplosionVectorBlockV2.java363
-rw-r--r--src/main/java/ihl/explosion/ExplosiveBlock.java252
-rw-r--r--src/main/java/ihl/explosion/ExplosiveTileEntity.java78
-rw-r--r--src/main/java/ihl/explosion/GroundRemoverItem.java105
-rw-r--r--src/main/java/ihl/explosion/IHLEntityFallingPile.java152
-rw-r--r--src/main/java/ihl/explosion/IHLEntityFallingPileRender.java51
-rw-r--r--src/main/java/ihl/explosion/PileBlock.java133
-rw-r--r--src/main/java/ihl/explosion/PileBlockRender.java285
-rw-r--r--src/main/java/ihl/explosion/PileTileEntity.java78
-rw-r--r--src/main/java/ihl/explosion/PileTileEntityRender.java187
-rw-r--r--src/main/java/ihl/explosion/WorldSavedDataBlastWave.java108
15 files changed, 2162 insertions, 0 deletions
diff --git a/src/main/java/ihl/explosion/ChunkAndWorldLoadEventHandler.java b/src/main/java/ihl/explosion/ChunkAndWorldLoadEventHandler.java
new file mode 100644
index 0000000..c2f7e0b
--- /dev/null
+++ b/src/main/java/ihl/explosion/ChunkAndWorldLoadEventHandler.java
@@ -0,0 +1,59 @@
+package ihl.explosion;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import cpw.mods.fml.common.eventhandler.SubscribeEvent;
+import ihl.IHLMod;
+import net.minecraft.world.ChunkCoordIntPair;
+import net.minecraft.world.Explosion;
+
+public class ChunkAndWorldLoadEventHandler {
+ public static ChunkAndWorldLoadEventHandler instance;
+
+ public ChunkAndWorldLoadEventHandler() {
+ instance = this;
+ }
+
+ @SubscribeEvent
+ public void onChunkLoadEvent(net.minecraftforge.event.world.ChunkEvent.Load event) {
+ if (event.getChunk().isChunkLoaded
+ && IHLMod.explosionHandler.blastWaveByDimensionId.containsKey(event.world.provider.dimensionId)) {
+ WorldSavedDataBlastWave bwdata = IHLMod.explosionHandler.blastWaveByDimensionId
+ .get(event.world.provider.dimensionId);
+ long cc = ChunkCoordIntPair.chunkXZ2Int(event.getChunk().xPosition, event.getChunk().zPosition);
+ if (bwdata.data.containsKey(cc)) {
+ Set<Integer[]> bwArraySet = bwdata.data.remove(cc);
+ int[] directionMask = new int[3];
+ Iterator<Integer[]> bwArrayI = bwArraySet.iterator();
+ Integer[] bwArray = null;
+ while (bwArrayI.hasNext()) {
+ bwArray = bwArrayI.next();
+ directionMask[0] = bwArray[5];
+ directionMask[1] = bwArray[6];
+ directionMask[2] = bwArray[7];
+ Explosion explosion = new Explosion(event.world, null, bwArray[1], bwArray[2], bwArray[3], 100f);
+ IHLMod.explosionHandler.breakBlocksAndGetDescendants(event.world, bwArray[1], bwArray[2],
+ bwArray[3], explosion, bwArray[0], bwArray[4], directionMask);
+ }
+ }
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldLoadEvent(net.minecraftforge.event.world.WorldEvent.Load event) {
+ WorldSavedDataBlastWave blastWave = (WorldSavedDataBlastWave) event.world.mapStorage
+ .loadData(WorldSavedDataBlastWave.class, "blastWave");
+ if (blastWave != null) {
+ IHLMod.explosionHandler.blastWaveByDimensionId.put(event.world.provider.dimensionId, blastWave);
+ }
+ }
+
+ @SubscribeEvent
+ public void onWorldSaveEvent(net.minecraftforge.event.world.WorldEvent.Save event) {
+ if (IHLMod.explosionHandler.blastWaveByDimensionId.containsKey(event.world.provider.dimensionId)) {
+ event.world.mapStorage.setData("blastWave",
+ IHLMod.explosionHandler.blastWaveByDimensionId.get(event.world.provider.dimensionId));
+ }
+ }
+}
diff --git a/src/main/java/ihl/explosion/DetonatorMiniGUI.java b/src/main/java/ihl/explosion/DetonatorMiniGUI.java
new file mode 100644
index 0000000..4a93050
--- /dev/null
+++ b/src/main/java/ihl/explosion/DetonatorMiniGUI.java
@@ -0,0 +1,82 @@
+package ihl.explosion;
+
+import java.awt.event.KeyEvent;
+
+import org.lwjgl.opengl.GL11;
+
+import ihl.IHLMod;
+import ihl.interfaces.ItemMiniGUI;
+import ihl.utils.IHLUtils;
+import net.minecraft.client.gui.GuiTextField;
+import net.minecraft.client.gui.inventory.GuiContainer;
+import net.minecraft.inventory.Slot;
+import net.minecraft.util.ResourceLocation;
+import net.minecraft.util.StatCollector;
+
+public class DetonatorMiniGUI extends ItemMiniGUI {
+ private static final ResourceLocation background = new ResourceLocation("ihl", "textures/gui/GUIIronWorkbench.png");
+ private int detonator_delay;
+ private GuiTextField detonatorDelayTextField;
+ private int xPos;
+ private int yPos;
+
+ public DetonatorMiniGUI(GuiContainer gui, Slot slot) {
+ super(gui, slot);
+ detonator_delay = slot.getStack().stackTagCompound.getInteger("detonator_delay");
+ xPos = this.slotBase.xDisplayPosition - 18;
+ yPos = this.slotBase.yDisplayPosition + 18;
+ detonatorDelayTextField = new GuiTextField(this.guiBase.mc.fontRenderer, xPos + TEXT_BOX_POSX,
+ yPos + TEXT_BOX_POSY, TEXT_BOX_WIDTH, 11);
+ detonatorDelayTextField.setText(Integer.toString(detonator_delay));
+ detonatorDelayTextField.setFocused(true);
+ }
+
+ @Override
+ public void displayGUI() {
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ this.guiBase.mc.renderEngine.bindTexture(background);
+ this.guiBase.drawTexturedModalRect(xPos, yPos, 0, 202, 126, HEIGHT);
+ int runnerXPos = xPos + 5 + 114 * detonator_delay / 1350;
+ this.guiBase.drawTexturedModalRect(runnerXPos, yPos + 34, 126, 202, 3, 5);
+ this.guiBase.mc.fontRenderer.drawStringWithShadow(StatCollector.translateToLocal("ihl.detonator_delay"),
+ xPos + 3, yPos + 4, 0xFFCC00);
+ this.detonatorDelayTextField.drawTextBox();
+ this.guiBase.mc.fontRenderer.drawStringWithShadow(StatCollector.translateToLocal("s"), xPos + UNITS_LABEL_POSX, yPos + 18,
+ 0xFFCC00);
+ }
+
+ @Override
+ public boolean handleMouseClick(int mouseX, int mouseY, int mouseButton) {
+ if (mouseX >= xPos + 5 && mouseX <= xPos + 119 && mouseY >= yPos + RUNNER_POSY - 1 && mouseY <= yPos + HEIGHT) {
+ this.detonator_delay = Math.max(1, Math.min(1350, (mouseX - xPos - 5) * 1350 / 114));
+ this.detonatorDelayTextField.setText(Integer.toString(detonator_delay));
+ }
+ if (mouseX >= xPos + TEXT_BOX_POSX && mouseX <= xPos + TEXT_BOX_POSX + TEXT_BOX_WIDTH && mouseY >= yPos + 3
+ && mouseY <= yPos + 3 + 11) {
+ this.detonatorDelayTextField.setFocused(true);
+ }
+ return mouseX >= xPos && mouseX <= xPos + 202 && mouseY >= yPos && mouseY <= yPos + HEIGHT;
+ }
+
+ @Override
+ public boolean handleKeyTyped(char characterTyped, int keyIndex) {
+ this.detonatorDelayTextField.textboxKeyTyped(characterTyped, keyIndex);
+ // 28 - enter; 156 - numpad enter
+ if (keyIndex == KeyEvent.VK_ACCEPT || keyIndex == KeyEvent.VK_ENTER || keyIndex == 28 || keyIndex == 156) {
+ this.detonator_delay = Math.max(1, Math.min(1350,
+ (int) (IHLUtils.parseIntSafe(this.detonatorDelayTextField.getText(), this.detonator_delay))));
+ this.detonatorDelayTextField.setText(Integer.toString(detonator_delay));
+ this.detonatorDelayTextField.setFocused(false);
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onGUIClosed() {
+ IHLMod.proxy.sendItemStackNBTTagFromClientToServerPlayer(this.guiBase.mc.thePlayer, this.slotBase.slotNumber,
+ "detonator_delay", this.detonator_delay);
+ }
+
+}
diff --git a/src/main/java/ihl/explosion/ExplosionEntityFX.java b/src/main/java/ihl/explosion/ExplosionEntityFX.java
new file mode 100644
index 0000000..ffa91fa
--- /dev/null
+++ b/src/main/java/ihl/explosion/ExplosionEntityFX.java
@@ -0,0 +1,177 @@
+package ihl.explosion;
+
+import java.util.Random;
+
+import ihl.utils.IHLMathUtils;
+import net.minecraft.client.particle.EntityFX;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.world.World;
+
+public class ExplosionEntityFX extends EntityFX {
+
+ private float radius;
+ private static final Random random = new Random();
+ private final int[] particlesMaxAge;
+ private final int[] particlesTextureIndexX;
+ private final int[] particlesTextureIndexY;
+ private final double[][] startPos;
+ private final double[][] pos;
+ private final double[][] prevPos;
+ private final float[][] motion;
+ private final int[] center;
+
+ public ExplosionEntityFX(World world, double x, double y, double z)
+ {
+ super(world, x, y, z);
+ this.renderDistanceWeight = 5.0D;
+ int numParticles = 1;
+ particlesMaxAge = new int[numParticles];
+ particlesTextureIndexX = new int[numParticles];
+ particlesTextureIndexY= new int[numParticles];
+ startPos = new double[numParticles][3];
+ pos = new double[numParticles][3];
+ prevPos = new double[numParticles][3];
+ motion = new float[numParticles][3];
+ center = new int[3];
+ }
+
+ public ExplosionEntityFX(World par1World, int centerX1, int centerY1, int centerZ1, float radius1)
+ {
+ super(par1World, centerX1, centerY1, centerZ1, 0.0D, 0.0D, 0.0D);
+ this.particleMaxAge = 100;
+ this.center = new int[3];
+ this.lastTickPosX=this.posX=this.prevPosX=this.center[0]=centerX1;
+ this.lastTickPosY=this.posY=this.prevPosY=this.center[1]=centerY1;
+ this.lastTickPosZ=this.posZ=this.prevPosZ=this.center[2]=centerZ1;
+ this.radius=radius1;
+ float r2 = radius*radius;
+ int numParticles = Math.min((int)(r2*radius/32)+64,512);
+ this.startPos = new double[numParticles][3];
+ this.pos = new double[numParticles][3];
+ this.prevPos = new double[numParticles][3];
+ this.particleScale *= 40f;
+ this.particlesMaxAge = new int[numParticles];
+ this.particlesTextureIndexX = new int[numParticles];
+ this.particlesTextureIndexY= new int[numParticles];
+ this.motion = new float[numParticles][3];
+ for(int i=0;i<numParticles;i++)
+ {
+ float fPosX = random.nextFloat()*2f-1f;
+ float fPosY = (random.nextFloat()*2f-1f)*IHLMathUtils.sqrt(1f-fPosX*fPosX);
+ float fPosZ = (random.nextFloat()*2f-1f)*IHLMathUtils.sqrt(1f-fPosX*fPosX-fPosY*fPosY);
+ fPosX *= radius1;
+ fPosY *= radius1;
+ fPosZ *= radius1;
+ prevPos[i][0] = pos[i][0] = startPos[i][0] = fPosX + centerX1;
+ prevPos[i][1] = pos[i][1] = startPos[i][1] = fPosY + centerY1;
+ prevPos[i][2] = pos[i][2] = startPos[i][2] = fPosZ + centerZ1;
+ particlesMaxAge[i] = random.nextInt(particleMaxAge-20)+16;
+ particlesTextureIndexY[i]=random.nextInt(8);
+ }
+ this.noClip = true;
+ this.renderDistanceWeight = 6.0D+radius1/2;
+ }
+
+ @Override
+ public void renderParticle(Tessellator tessellator, float interFrame, float rotationX, float rotationXZ, float rotationZ, float rotationYZ, float rotationXY)
+ {
+ for(int i=0;i<particlesMaxAge.length;i++)
+ {
+ float u1 = this.particlesTextureIndexX[i] / 16.0F;
+ float u2 = u1 + 1F / 16.0F;
+ float v1 = this.particlesTextureIndexY[i] / 8.0F;
+ float v2 = v1 + 1F / 8.0F;
+ float scale = 0.1F * this.particleScale;
+
+ float fPosX = (float)(this.prevPos[i][0] - this.prevPosX + (this.pos[i][0] - this.prevPos[i][0]) * interFrame);
+ float fPosY = (float)(this.prevPos[i][1] - this.prevPosY + (this.pos[i][1] - this.prevPos[i][1]) * interFrame);
+ float fPosZ = (float)(this.prevPos[i][2] - this.prevPosZ + (this.pos[i][2] - this.prevPos[i][2]) * interFrame);
+ tessellator.addVertexWithUV(
+ fPosX - rotationX * scale - rotationYZ * scale,
+ fPosY - rotationXZ * scale,
+ fPosZ - rotationZ * scale - rotationXY * scale,
+ u2, v2);
+ tessellator.addVertexWithUV(
+ fPosX - rotationX * scale + rotationYZ * scale,
+ fPosY + rotationXZ * scale,
+ fPosZ - rotationZ * scale + rotationXY * scale,
+ u2, v1);
+ tessellator.addVertexWithUV(
+ fPosX + rotationX * scale + rotationYZ * scale,
+ fPosY + rotationXZ * scale,
+ fPosZ + rotationZ * scale + rotationXY * scale,
+ u1, v1);
+ tessellator.addVertexWithUV(
+ fPosX + rotationX * scale - rotationYZ * scale,
+ fPosY - rotationXZ * scale,
+ fPosZ + rotationZ * scale - rotationXY * scale,
+ u1, v2);
+ }
+ }
+
+ @Override
+ public void onUpdate()
+ {
+ if (this.particleAge++ >= this.particleMaxAge)
+ {
+ this.setDead();
+ }
+ for(int i=0;i<particlesMaxAge.length;i++)
+ {
+ this.prevPos[i][0] = this.pos[i][0];
+ this.prevPos[i][1] = this.pos[i][1];
+ this.prevPos[i][2] = this.pos[i][2];
+
+ int maxFrameX = 15;
+ int frameX = this.particleAge * maxFrameX / this.particlesMaxAge[i];
+ if(frameX<=maxFrameX)
+ {
+ this.particlesTextureIndexX[i] = frameX;
+ }
+
+ if(this.startPos[i][1] < this.center[1])
+ {
+ IHLMathUtils.vector_add(this.motion[i],
+ (float)(this.center[0]-this.pos[i][0])*0.0004f,
+ 0.004f,
+ (float)(this.center[2]-this.pos[i][2])*0.0004f);
+ }
+ else
+ {
+ float[] ring = new float[] {
+ (float)(this.startPos[i][0]-this.center[0]),
+ 0f,
+ (float)(this.startPos[i][2]-this.center[2])};
+ IHLMathUtils.scale_vector_to_value(ring, radius*0.6f);
+ IHLMathUtils.vector_add(ring,
+ this.center[0],
+ (float)this.startPos[i][1]+this.particleAge*0.001f,
+ this.center[2]);
+ float[] from_point_to_ring = IHLMathUtils.vector_return_difference(ring,this.pos[i]);
+ float[] from_point_to_center = IHLMathUtils.vector_return_difference(this.center,this.pos[i]);
+ float[] tangent_to_ring = IHLMathUtils.vector_vector_multiply(from_point_to_ring, from_point_to_center);
+ float[] tangent_to_torus = IHLMathUtils.vector_vector_multiply(from_point_to_ring, tangent_to_ring);
+ IHLMathUtils.normalize_vector(tangent_to_torus);
+ IHLMathUtils.vector_add(this.motion[i],
+ from_point_to_ring[0]*0.01f + tangent_to_torus[0]*0.02f,
+ from_point_to_ring[1]*0.01f + tangent_to_torus[1]*0.02f + 0.004f,
+ from_point_to_ring[2]*0.01f + tangent_to_torus[2]*0.02f);
+ }
+ IHLMathUtils.vector_add(this.pos[i],this.motion[i]);
+ IHLMathUtils.multiply_vector_to_value(this.motion[i], 0.98f);
+ }
+ }
+
+ @Override
+ public void setParticleTextureIndex(int par1)
+ {
+ this.particleTextureIndexX = par1;
+ }
+
+ @Override
+ public boolean shouldRenderInPass(int pass)
+ {
+ return pass==1;
+ }
+
+}
diff --git a/src/main/java/ihl/explosion/ExplosionRenderFX.java b/src/main/java/ihl/explosion/ExplosionRenderFX.java
new file mode 100644
index 0000000..18bfd4f
--- /dev/null
+++ b/src/main/java/ihl/explosion/ExplosionRenderFX.java
@@ -0,0 +1,52 @@
+package ihl.explosion;
+
+import org.lwjgl.opengl.GL11;
+
+import net.minecraft.client.particle.EntityFX;
+import net.minecraft.client.renderer.ActiveRenderInfo;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.Render;
+import net.minecraft.entity.Entity;
+import net.minecraft.util.ResourceLocation;
+
+public class ExplosionRenderFX extends Render{
+ private ResourceLocation tex;
+
+public ExplosionRenderFX(String textureLocation)
+{
+ super();
+ tex = new ResourceLocation(textureLocation);
+}
+
+@Override
+public void doRender(Entity entity, double x, double y, double z,
+ float interFrame, float arg5)
+{
+ float rotationX = ActiveRenderInfo.rotationX;
+ float rotationZ = ActiveRenderInfo.rotationZ;
+ float rotationYZ = ActiveRenderInfo.rotationYZ;
+ float rotationXY = ActiveRenderInfo.rotationXY;
+ float rotationXZ = ActiveRenderInfo.rotationXZ;
+ this.renderManager.renderEngine.bindTexture(tex);
+ GL11.glPushMatrix();
+ GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
+ GL11.glTranslatef((float)x, (float)y, (float)z);
+ GL11.glDepthMask(false);
+ GL11.glEnable(GL11.GL_BLEND);
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ Tessellator tessellator = Tessellator.instance;
+ tessellator.startDrawingQuads();
+ EntityFX entityFX = (EntityFX) entity;
+ entityFX.renderParticle(tessellator, interFrame, rotationX, rotationXZ, rotationZ, rotationYZ, rotationXY);
+ tessellator.draw();
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glDepthMask(true);
+ GL11.glPopMatrix();
+}
+
+ @Override
+ protected ResourceLocation getEntityTexture(Entity arg0)
+ {
+ return tex;
+ }
+} \ No newline at end of file
diff --git a/src/main/java/ihl/explosion/ExplosionVectorBlockV2.java b/src/main/java/ihl/explosion/ExplosionVectorBlockV2.java
new file mode 100644
index 0000000..e00e19a
--- /dev/null
+++ b/src/main/java/ihl/explosion/ExplosionVectorBlockV2.java
@@ -0,0 +1,363 @@
+package ihl.explosion;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Random;
+import java.util.Set;
+
+import ihl.IHLMod;
+import ihl.utils.IHLUtils;
+import net.minecraft.block.Block;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.network.play.server.S26PacketMapChunkBulk;
+import net.minecraft.util.DamageSource;
+import net.minecraft.world.ChunkCoordIntPair;
+import net.minecraft.world.Explosion;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.world.ExplosionEvent;
+
+public class ExplosionVectorBlockV2 {
+ final Set<Integer> startVectors = new HashSet<Integer>();
+ public final int[][] directionMasks = new int[8][3];
+ public final int bits = IHLMod.config.explosionVectorSizeBits;
+ private final int maxValue = (1 << bits) - 1;
+ public final int halfValue = (1 << bits - 1) - 1;
+ private final int maxArraySize = 1 << bits * 3;
+// public final int[][] vectors = new int[maxArraySize][2];
+ public final int[][] vectors = new int[maxArraySize][0];
+ private final Set<Chunk> chunksToUpdate = new HashSet<Chunk>(64);
+ private final Map<Integer, ItemStack> cachedDrops = new HashMap<Integer, ItemStack>(128);
+ final Map<Integer, WorldSavedDataBlastWave> blastWaveByDimensionId = new HashMap<Integer, WorldSavedDataBlastWave>();
+ private final Map<ExtendedBlockStorage, Entity[]> cachedEntities = new HashMap<ExtendedBlockStorage, Entity[]>();
+ private final Random random = new Random();
+
+ public ExplosionVectorBlockV2() {
+ this.precalculateExplosion();
+ startVectors.add(0);
+ directionMasks[0] = new int[] { 1, 1, 1 };
+ directionMasks[1] = new int[] { -1, 1, 1 };
+ directionMasks[2] = new int[] { 1, -1, 1 };
+ directionMasks[3] = new int[] { 1, 1, -1 };
+ directionMasks[4] = new int[] { -1, -1, 1 };
+ directionMasks[5] = new int[] { 1, -1, -1 };
+ directionMasks[6] = new int[] { -1, 1, -1 };
+ directionMasks[7] = new int[] { -1, -1, -1 };
+ }
+
+ public int encodeXYZ(int x, int y, int z) {
+ return x << bits * 2 | y << bits | z;
+ }
+
+ public int[] decodeXYZ(int l) {
+ return new int[] { l >> bits * 2, l >> bits & maxValue, l & maxValue };
+ }
+
+ public void precalculateExplosion() {
+ for (int levelRadius = 1; levelRadius <= this.maxValue; levelRadius++)
+ for (int ix = 0; ix <= levelRadius; ix++)
+ for (int iy = 0; iy <= levelRadius; iy++) {
+ for (int iz = (ix == levelRadius || iy == levelRadius) ? 0 : levelRadius; iz <= levelRadius; iz++) {
+ int vxyz = encodeXYZ(ix, iy, iz);
+ int[] prevXYZ = new int[] { ix, iy, iz };
+ reduceCoordinate(prevXYZ, levelRadius);
+ int pvxyz = encodeXYZ(prevXYZ[0], prevXYZ[1], prevXYZ[2]);
+ findFreeSpace(pvxyz, vxyz);
+ }
+ }
+ }
+
+ private void findFreeSpace(int pvxyz, int vxyz) {
+ int[] nV = new int[vectors[pvxyz].length+1];
+ for(int i=0;i<vectors[pvxyz].length;i++){
+ nV[i]=vectors[pvxyz][i];
+ }
+ nV[vectors[pvxyz].length] = vxyz;
+ vectors[pvxyz] = nV;
+ }
+
+ private void reduceCoordinate(int[] pxyz, int levelRadius) {
+ float x = pxyz[0]+0.5f;
+ float y = pxyz[1]+0.5f;
+ float z = pxyz[2]+0.5f;
+ float rx = x/levelRadius;
+ float ry = y/levelRadius;
+ float rz = z/levelRadius;
+ while(x>=pxyz[0] && y>=pxyz[1] && z>=pxyz[2]){
+ x-=rx;
+ y-=ry;
+ z-=rz;
+ }
+ pxyz[0]=x<0?0:(int)x;
+ pxyz[1]=y<0?0:(int)y;
+ pxyz[2]=z<0?0:(int)z;
+ }
+
+ public void breakBlocksAndGetDescendants(World world, int sourceX, int sourceY, int sourceZ, Explosion explosion,
+ int ev, int power, int[] directionMask) {
+ power = this.getNewPowerAndProcessBlocks(world, ev, sourceX, sourceY, sourceZ, explosion, power, directionMask);
+ power = (int) (power * 0.94) - 1;
+ if (power > 1) {
+ if (this.vectors[ev].length==0) {
+ int[] xyz = decodeXYZ(ev);
+ int xb = xyz[0] >> bits - 1;
+ int yb = xyz[1] >> bits - 1;
+ int zb = xyz[2] >> bits - 1;
+ int hashb = xb << 2 | yb << 1 | zb;
+ xyz[0] -= xb * halfValue;
+ xyz[1] -= yb * halfValue;
+ xyz[2] -= zb * halfValue;
+ if (hashb == 0 || xb > 1 || yb > 1 || zb > 1) {
+ throw new ArithmeticException("End vectors shall be higher than half value");
+ }
+ int ev2 = encodeXYZ(xyz[0], xyz[1], xyz[2]);
+ breakBlocksAndGetDescendants(world, sourceX + xb * halfValue * directionMask[0],
+ sourceY + yb * halfValue * directionMask[1], sourceZ + zb * halfValue * directionMask[2],
+ explosion, ev2, power, directionMask);
+ } else {
+ for (int d1 : this.vectors[ev]) {
+ breakBlocksAndGetDescendants(world, sourceX, sourceY, sourceZ, explosion, d1, power,
+ directionMask);
+ }
+ }
+ }
+ }
+
+ private int getNewPowerAndProcessBlocks(World world, int ev, int sourceX, int sourceY, int sourceZ,
+ Explosion explosion, int power2, int[] directionMask) {
+ int power1 = power2;
+ int[] xyz = decodeXYZ(ev);
+ int absX = xyz[0] * directionMask[0] + sourceX;
+ int absY = xyz[1] * directionMask[1] + sourceY;
+ int absZ = xyz[2] * directionMask[2] + sourceZ;
+ if (absY < 0 || absY >= 256) {
+ return 0;
+ }
+ int absEBSX = absX >> 4;
+ int absEBSZ = absZ >> 4;
+ if (world.getChunkProvider().chunkExists(absEBSX, absEBSZ)) {
+ if (world.getChunkProvider().provideChunk(absEBSX, absEBSZ).getTopFilledSegment() + 24 >= absY) {
+ int remainingPower = this.tryDestroyBlock(world, absX, absY, absZ, sourceX, sourceY, sourceZ, power1,
+ explosion);
+ return remainingPower;
+ } else {
+ return 0;
+ }
+ } else {
+ WorldSavedDataBlastWave blastWave = null;
+ int dimensionId = world.provider.dimensionId;
+ if (this.blastWaveByDimensionId.containsKey(dimensionId)) {
+ blastWave = this.blastWaveByDimensionId.get(dimensionId);
+ } else {
+ blastWave = new WorldSavedDataBlastWave("blastWave");
+ this.blastWaveByDimensionId.put(dimensionId, blastWave);
+ }
+ long chunkXZKey = ChunkCoordIntPair.chunkXZ2Int(absEBSX, absEBSZ);
+ blastWave.scheduleExplosionEffectsOnChunkLoad(chunkXZKey, ev, sourceX, sourceY, sourceZ, power1,
+ directionMask);
+ return 0;
+ }
+ }
+
+ public int tryDestroyBlock(World world, int absX, int absY, int absZ, int sourceX, int sourceY, int sourceZ,
+ int power, Explosion explosion) {
+ Chunk chunk = world.getChunkProvider().provideChunk(absX >> 4, absZ >> 4);
+ ExtendedBlockStorage ebs = this.getEBS(chunk, absX, absY, absZ);
+ if (ebs == null) {
+ return power;
+ } else {
+ Block block = ebs.getBlockByExtId(absX & 15, absY & 15, absZ & 15);
+ if (block.getBlockHardness(world, absX, absY, absZ) < 0) {
+ return 0;
+ } else if (absX == sourceX && absY == sourceY && absZ == sourceZ) {
+ int array_index = (absY & 15) << 8 | (absZ & 15) << 4 | (absX & 15);
+ if (ebs.getBlockLSBArray()[array_index] != 0 && ebs.getBlockMSBArray() != null
+ && ebs.getBlockMSBArray().get(absX & 15, absY & 15, absZ & 15) != 0) {
+ ebs.blockRefCount--;
+ }
+ ebs.getBlockLSBArray()[array_index] = 0;
+ if (ebs.getBlockMSBArray() != null) {
+ ebs.getBlockMSBArray().set(absX & 15, absY & 15, absZ & 15, 0);
+ }
+ return power;
+ } else {
+ int remainingPower = power
+ - (int) (block.getExplosionResistance(null, world, absX, absY, absZ, sourceX, sourceY, sourceZ)
+ * 10f + 0.5f);
+ if (remainingPower >= 0) {
+ int array_index = (absY & 15) << 8 | (absZ & 15) << 4 | (absX & 15);
+ if (ebs.getBlockLSBArray()[array_index] != 0 && ebs.getBlockMSBArray() != null
+ && ebs.getBlockMSBArray().get(absX & 15, absY & 15, absZ & 15) != 0) {
+ ebs.blockRefCount--;
+ }
+ ebs.getBlockLSBArray()[array_index] = 0;
+ if (ebs.getBlockMSBArray() != null) {
+ ebs.getBlockMSBArray().set(absX & 15, absY & 15, absZ & 15, 0);
+ }
+ List<ItemStack> dropsList = block.getDrops(world, absX, absY, absZ,
+ ebs.getExtBlockMetadata(absX & 15, absY & 15, absZ & 15), 0);
+ Iterator<ItemStack> drops = dropsList.iterator();
+ while (drops.hasNext()) {
+ ItemStack drop = drops.next();
+ int key = Item.getIdFromItem(drop.getItem()) ^ (drop.getItemDamage() << 16);
+ if (this.cachedDrops.containsKey(key)) {
+ this.cachedDrops.get(key).stackSize += drop.stackSize;
+ } else {
+ this.cachedDrops.put(key, drop);
+ }
+ }
+ Entity[] entities = this.getFromOrCreateCache(world, ebs, absX, absY, absZ);
+ if (entities != null && entities[array_index] != null) {
+ entities[array_index].attackEntityFrom(DamageSource.setExplosionSource(explosion), power / 10f);
+ }
+ } else {
+ block.onNeighborBlockChange(world, absX, absY, absZ, block);
+ if (random.nextInt(8) == 0) {
+ if ((++absY & 15) != 0) {
+ int array_index = (absY & 15) << 8 | (absZ & 15) << 4 | (absX & 15);
+ if (ebs.getBlockLSBArray()[array_index] == 0 && (ebs.getBlockMSBArray() == null
+ || ebs.getBlockMSBArray().get(absX & 15, absY & 15, absZ & 15) == 0)) {
+ this.placeDrops(world, absX, absY, absZ);
+ }
+ }
+ }
+ }
+ return remainingPower;
+ }
+ }
+ }
+
+ public Entity[] getFromOrCreateCache(World world, ExtendedBlockStorage ebs, int absX, int absY, int absZ) {
+ Entity[] entities = this.cachedEntities.get(ebs);
+ if (entities == null) {
+ Chunk chunk = world.getChunkProvider().provideChunk(absX >> 4, absZ >> 4);
+ List<Entity> eList = this.getEntityList(chunk, absX, absY, absZ);
+ if (eList != null && !eList.isEmpty()) {
+ entities = new Entity[4096];
+ Iterator<Entity> eListI = eList.iterator();
+ this.cachedEntities.put(ebs, entities);
+ while (eListI.hasNext()) {
+ Entity entity = eListI.next();
+ int entityX = (int) entity.boundingBox.minX;
+ int entityY = (int) entity.boundingBox.minY;
+ int entityZ = (int) entity.boundingBox.minZ;
+ int rx = entityX & 15;
+ int ry = entityY & 15;
+ int rz = entityZ & 15;
+ int array_index = ry << 8 | rz << 4 | rx;
+ entities[array_index] = entity;
+ }
+ }
+ }
+ return entities;
+ }
+
+ public ExtendedBlockStorage getEBS(Chunk chunk, int absX, int absY, int absZ) {
+ ExtendedBlockStorage[] ebsA = chunk.getBlockStorageArray();
+ ExtendedBlockStorage ebs = ebsA[absY >> 4];
+ if (ebs != null) {
+ this.chunksToUpdate.add(chunk);
+ }
+ return ebs;
+ }
+
+ @SuppressWarnings("unchecked")
+ public List<Entity> getEntityList(Chunk chunk, int absX, int absY, int absZ) {
+ return chunk.entityLists[absY >> 4];
+ }
+
+ private void placeDrops(World world, int x, int y, int z) {
+ Iterator<Entry<Integer, ItemStack>> di = this.cachedDrops.entrySet().iterator();
+ if (di.hasNext()) {
+ Entry<Integer, ItemStack> cde = di.next();
+ while (di.hasNext()) {
+ cde = di.next();
+ }
+ ItemStack stack = cde.getValue();
+ if (stack != null && stack.getItem() != null && stack.stackSize > 0) {
+ if (stack.stackSize <= stack.getMaxStackSize()) {
+ if (stack.stackSize > 0) {
+ PileTileEntity pte = new PileTileEntity();
+ pte.xCoord = x;
+ pte.yCoord = y;
+ pte.zCoord = z;
+ pte.setWorldObj(world);
+ pte.validate();
+ pte.setContent(stack);
+ IHLUtils.setBlockAndTileEntityRaw(world, x, y, z, PileBlock.instance, pte);
+ }
+ di.remove();
+ } else {
+ ItemStack stack1 = stack.copy();
+ stack1.stackSize = stack.getMaxStackSize();
+ PileTileEntity pte = new PileTileEntity();
+ pte.content = stack1;
+ IHLUtils.setBlockAndTileEntityRaw(world, x, y, z, PileBlock.instance, pte);
+ stack.stackSize -= stack.getMaxStackSize();
+ }
+ }
+ }
+ }
+
+ public void sendChunkUpdateToPlayersInExplosionAffectedZone(World world, int sourceX, int sourceY, int sourceZ) {
+ Iterator<Chunk> ci = this.chunksToUpdate.iterator();
+ while (ci.hasNext()) {
+ Chunk chunk = ci.next();
+ chunk.generateSkylightMap();
+ Arrays.fill(chunk.updateSkylightColumns, true);
+ chunk.func_150804_b(false);
+ }
+ List<Chunk> chunks = new ArrayList<Chunk>();
+ chunks.addAll(this.chunksToUpdate);
+ for (Object player : world.playerEntities) {
+ if (player instanceof EntityPlayerMP) {
+ EntityPlayerMP playerMP = (EntityPlayerMP) player;
+ playerMP.playerNetServerHandler.sendPacket(new S26PacketMapChunkBulk(chunks));
+ }
+ }
+ this.chunksToUpdate.clear();
+ }
+
+ public void doExplosion(World world, int sourceX, int sourceY, int sourceZ, final Set<Integer> startVectors1,
+ int startPower, int[] directionMask, Explosion explosion) {
+ for (int sv : startVectors1) {
+ this.breakBlocksAndGetDescendants(world, sourceX - (directionMask[0] < 0 ? 1 : 0),
+ sourceY - (directionMask[1] < 0 ? 1 : 0), sourceZ - (directionMask[2] < 0 ? 1 : 0), explosion, sv,
+ startPower, directionMask);
+ }
+ // Free and clean resources
+ this.cachedEntities.clear();
+ }
+
+ public void doExplosion(World world, int sourceX, int sourceY, int sourceZ, final Set<Integer> startVectors1,
+ int startPower) {
+ IHLMod.log.info("Starting explosion server");
+ Explosion explosion = new Explosion(world, null, sourceX, sourceY, sourceZ, 100f);
+ if (!MinecraftForge.EVENT_BUS.post(new ExplosionEvent.Start(world, explosion))) {
+ for (int[] directionMask : directionMasks) {
+ this.doExplosion(world, sourceX, sourceY, sourceZ, startVectors1, startPower, directionMask, explosion);
+ }
+ sendChunkUpdateToPlayersInExplosionAffectedZone(world, sourceX, sourceY, sourceZ);
+ for (Entry<Integer, ItemStack> entry : this.cachedDrops.entrySet()) {
+ IHLEntityFallingPile fallingPile = new IHLEntityFallingPile(world);
+ fallingPile.setPosition(sourceX + 0.5d, sourceY + 0.5d, sourceZ + 0.5d);
+ fallingPile.setEntityItemStack(entry.getValue());
+ fallingPile.setVelocity(random.nextDouble() - 0.5d, random.nextDouble() * 2,
+ random.nextDouble() - 0.5d);
+ world.spawnEntityInWorld(fallingPile);
+ }
+ this.cachedDrops.clear();
+ }
+ }
+} \ No newline at end of file
diff --git a/src/main/java/ihl/explosion/ExplosiveBlock.java b/src/main/java/ihl/explosion/ExplosiveBlock.java
new file mode 100644
index 0000000..d6b1c71
--- /dev/null
+++ b/src/main/java/ihl/explosion/ExplosiveBlock.java
@@ -0,0 +1,252 @@
+package ihl.explosion;
+
+import java.util.List;
+
+import cpw.mods.fml.common.registry.GameRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import ic2.core.IC2;
+import ihl.IHLCreativeTab;
+import ihl.IHLModInfo;
+import ihl.items_blocks.IHLItemBlock;
+import ihl.processing.metallurgy.MuffleFurnanceTileEntity;
+import net.minecraft.block.Block;
+import net.minecraft.block.ITileEntityProvider;
+import net.minecraft.block.material.Material;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
+import net.minecraft.init.Items;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.AxisAlignedBB;
+import net.minecraft.util.IIcon;
+import net.minecraft.world.Explosion;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+
+public class ExplosiveBlock extends Block implements ITileEntityProvider{
+
+ IIcon[] textures = new IIcon[6];
+
+ public ExplosiveBlock()
+ {
+ super(Material.tnt);
+ this.setCreativeTab(IHLCreativeTab.tab);
+ this.setBlockName("ihlExplosive");
+ this.setHardness(2F);
+ this.setResistance(1F);
+ }
+
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ public void getSubBlocks(Item item, CreativeTabs par2CreativeTabs, List itemList)
+ {
+ ItemStack result = new ItemStack(item);
+ result.stackTagCompound=new NBTTagCompound();
+ result.stackTagCompound.setInteger("explosionType", 1);//0 - IC2; 1- IHL
+ result.stackTagCompound.setInteger("explosionPower", 31000);
+ itemList.add(result);
+ result = new ItemStack(item);
+ result.stackTagCompound=new NBTTagCompound();
+ result.stackTagCompound.setInteger("explosionType", 1);//0 - IC2; 1- IHL
+ result.stackTagCompound.setInteger("explosionPower", Integer.MAX_VALUE);//31000
+ itemList.add(result);
+ }
+
+ @Override
+ @SuppressWarnings("rawtypes")
+ public void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB aabb, List list, Entity entity)
+ {
+ this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 0.1F, 1.0F);
+ super.addCollisionBoxesToList(world, x, y, z, aabb, list, entity);
+ this.setBlockBounds(0.0F, 0.0F, 0.0F, 0.1F, 1.0F, 1.0F);
+ super.addCollisionBoxesToList(world, x, y, z, aabb, list, entity);
+ this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 0.1F);
+ super.addCollisionBoxesToList(world, x, y, z, aabb, list, entity);
+ this.setBlockBounds(0.9F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+ super.addCollisionBoxesToList(world, x, y, z, aabb, list, entity);
+ this.setBlockBounds(0.0F, 0.0F, 0.9F, 1.0F, 1.0F, 1.0F);
+ super.addCollisionBoxesToList(world, x, y, z, aabb, list, entity);
+ this.setBlockBoundsForItemRender();
+ }
+
+ @Override
+ public void setBlockBoundsForItemRender()
+ {
+ this.setBlockBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
+ }
+
+ public static void init()
+ {
+ GameRegistry.registerBlock(new ExplosiveBlock(), IHLItemBlock.class,"ihlExplosive");
+ GameRegistry.registerTileEntity(ExplosiveTileEntity.class, "explosiveTileEntity");
+ }
+
+ @Override
+ public void dropBlockAsItemWithChance(World world, int x, int y, int z, int meta, float chance, int flag)
+ {
+ super.dropBlockAsItemWithChance(world, x, y, z, meta, chance, flag);
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World world, int var2) {
+ return new ExplosiveTileEntity();
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void registerBlockIcons(IIconRegister par1IconRegister)
+ {
+ this.blockIcon = par1IconRegister.registerIcon(IHLModInfo.MODID + ":explosiveBlockSide");
+ this.textures[0] = par1IconRegister.registerIcon(IHLModInfo.MODID + ":explosiveBlockBottom");
+ this.textures[1] = par1IconRegister.registerIcon(IHLModInfo.MODID + ":explosiveBlockTop");
+ this.textures[2] = this.textures[3] = this.textures[4] = this.textures[5] = this.blockIcon;
+ }
+
+ @Override
+ public boolean hasTileEntity(int metadata)
+ {
+ return true;
+ }
+
+ @Override
+ public boolean onBlockActivated(World world,int x,int y,int z,EntityPlayer player,int i,float pos_x,float pos_y,float pos_z){
+ TileEntity te = world.getTileEntity(x,y,z);
+ if(IC2.platform.isSimulating() && te instanceof ExplosiveTileEntity)
+ {
+ return ((ExplosiveTileEntity)te).ignite(player);
+ }
+ return false;
+ }
+
+ @Override
+ public void onNeighborBlockChange(World world, int x, int y, int z, Block block)
+ {
+ TileEntity te = world.getTileEntity(x,y,z);
+ if(IC2.platform.isSimulating() && te instanceof ExplosiveTileEntity)
+ {
+ int[] xyz = {0,0,1,0,0,-1,0,0};
+ for(int i=2;i<xyz.length;i++)
+ {
+ if(world.getBlock(x+xyz[i-2], y+xyz[i-1], z+xyz[i])==Blocks.fire && !te.isInvalid())
+ {
+ ((ExplosiveTileEntity)te).ignite();
+ }
+ }
+ }
+ }
+
+ /**
+ * Called when the block is placed in the world.
+ */
+ @Override
+ public void onBlockPlacedBy(World world, int x, int y, int z, EntityLivingBase player, ItemStack itemStack)
+ {
+ TileEntity t = world.getTileEntity(x, y, z);
+ if(t!=null)
+ {
+ t.readFromNBT(itemStack.stackTagCompound);
+ }
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public IIcon getIcon(IBlockAccess world, int x, int y, int z, int side)
+ {
+ return this.getIcon(side, 0);
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public IIcon getIcon(int side, int meta)
+ {
+ return this.textures[side];
+ }
+
+ @Override
+ public boolean onBlockEventReceived(World world, int x, int y, int z, int metadata, int flag)
+ {
+ return true;
+ }
+
+ public enum ExplosiveType
+ {
+ MuffleFurnace("muffleFurnance",MuffleFurnanceTileEntity.class, true, new ItemStack(Items.brick));
+ ExplosiveType(String unlocalizedName1, Class<?> teclass1, boolean isNormalBlock1,ItemStack itemDroppedOnBlockDestroy1)
+ {
+ unlocalizedName=unlocalizedName1;
+ teclass=teclass1;
+ isNormalBlock=isNormalBlock1;
+ itemDroppedOnBlockDestroy=itemDroppedOnBlockDestroy1;
+ }
+ String unlocalizedName;
+ Class<?> teclass;
+ boolean isNormalBlock=true;
+ ItemStack itemDroppedOnBlockDestroy;
+ }
+
+ @Override
+ public int getRenderType()
+ {
+ return 0;
+ }
+
+ @Override
+ public boolean isOpaqueCube()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean renderAsNormalBlock()
+ {
+ return true;
+ }
+
+ @SideOnly(Side.CLIENT)
+ public IIcon getInnerTextureForBlockRenderer()
+ {
+ return this.blockIcon;
+ }
+
+ @Override
+ public boolean canDropFromExplosion(Explosion explosion)
+ {
+ return false;
+ }
+
+ @Override
+ public float getExplosionResistance(Entity entity)
+ {
+ return -1f;
+ }
+
+ @Override
+ public float getExplosionResistance(Entity entity, World world, int x, int y ,int z, double explosionX, double explosionY, double explosionZ)
+ {
+ TileEntity te = world.getTileEntity(x, y, z);
+ if(te instanceof ExplosiveTileEntity && !((ExplosiveTileEntity)te).isInvalid())
+ {
+ return -((ExplosiveTileEntity)te).explosionPower;
+ }
+ return -1f;
+ }
+
+ @Override
+ public void onBlockDestroyedByExplosion(World world, int x, int y ,int z, Explosion explosion)
+ {
+ TileEntity te = world.getTileEntity(x, y, z);
+ if(te instanceof ExplosiveTileEntity)
+ {
+ ((ExplosiveTileEntity)te).createExplosion(null);
+ }
+ }
+
+
+}
diff --git a/src/main/java/ihl/explosion/ExplosiveTileEntity.java b/src/main/java/ihl/explosion/ExplosiveTileEntity.java
new file mode 100644
index 0000000..b211d3b
--- /dev/null
+++ b/src/main/java/ihl/explosion/ExplosiveTileEntity.java
@@ -0,0 +1,78 @@
+package ihl.explosion;
+
+import ic2.core.IC2;
+import ihl.IHLMod;
+import ihl.utils.IHLMathUtils;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraftforge.oredict.OreDictionary;
+
+public class ExplosiveTileEntity extends TileEntity {
+
+ public int explosionPower = 10000;
+ private int explosionType = 1;
+ private int detonator_delay = 1;
+ private int burn_time = 0;
+ public boolean is_detonator_burning = false;
+
+ public void createExplosion(EntityPlayer player) {
+ this.invalidate();
+ int power = this.explosionPower;
+ this.explosionPower = 0;
+ IHLMod.explosionHandler.doExplosion(worldObj, xCoord, yCoord, zCoord, IHLMod.explosionHandler.startVectors,
+ power);
+ IHLMod.proxy.createExplosionEffectFromServer(worldObj, xCoord, yCoord, zCoord,
+ 32f * IHLMathUtils.sqrt(power / 16384f));
+ }
+
+ @Override
+ public boolean canUpdate() {
+ return IC2.platform.isSimulating();
+ }
+
+ @Override
+ public void updateEntity() {
+ if (is_detonator_burning) {
+ IHLMod.proxy.spawnParticleFromServer(4, worldObj, xCoord + 0.5d, yCoord + 1d, zCoord + 0.5d, 0d, 0.2d, 0d,
+ 1f);
+ if (this.burn_time++ > detonator_delay * 20) {
+ this.createExplosion(null);
+ }
+ }
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound nbt) {
+ if (nbt != null) {
+ explosionPower = nbt.getInteger("explosionPower");
+ explosionType = nbt.getInteger("explosionType");
+ detonator_delay = nbt.getInteger("detonator_delay");
+ }
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound nbt) {
+ nbt.setInteger("explosionPower", explosionPower);
+ nbt.setInteger("explosionType", explosionType);
+ nbt.setInteger("detonator_delay", detonator_delay);
+ }
+
+ public boolean ignite(EntityPlayer player) {
+ if (player != null && player.getCurrentEquippedItem() != null) {
+ for (int oid : OreDictionary.getOreIDs(player.getCurrentEquippedItem())) {
+ if (OreDictionary.getOreName(oid).matches("toolLighter")) {
+ ignite();
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public void ignite() {
+ IHLMod.proxy.playSoundEffectFromServer(0, this.worldObj, this.xCoord + 0.5D, this.yCoord + 0.5D,
+ this.zCoord + 0.5D, 10.0F, 1.0F);
+ this.is_detonator_burning = true;
+ }
+}
diff --git a/src/main/java/ihl/explosion/GroundRemoverItem.java b/src/main/java/ihl/explosion/GroundRemoverItem.java
new file mode 100644
index 0000000..ddbc884
--- /dev/null
+++ b/src/main/java/ihl/explosion/GroundRemoverItem.java
@@ -0,0 +1,105 @@
+package ihl.explosion;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import ihl.IHLCreativeTab;
+import ihl.IHLMod;
+import ihl.IHLModInfo;
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.texture.IIconRegister;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.World;
+
+public class GroundRemoverItem extends Item{
+
+ private String registryName;
+ private final Set<Block> removableBlockSet = new HashSet<Block>();
+ private final Random random = new Random();
+
+ public GroundRemoverItem(String registryName1)
+ {
+ super();
+ this.registryName=registryName1;
+ this.setCreativeTab(IHLCreativeTab.tab);
+ this.setMaxStackSize(1);
+ this.setUnlocalizedName(registryName);
+ removableBlockSet.add(Blocks.sandstone);
+ removableBlockSet.add(Blocks.sand);
+ removableBlockSet.add(Blocks.stone);
+ removableBlockSet.add(Blocks.flowing_water);
+ removableBlockSet.add(Blocks.flowing_lava);
+ removableBlockSet.add(Blocks.water);
+ removableBlockSet.add(Blocks.lava);
+ removableBlockSet.add(Blocks.clay);
+ removableBlockSet.add(Blocks.gravel);
+ removableBlockSet.add(Blocks.dirt);
+ }
+
+ public GroundRemoverItem()
+ {
+ super();
+ }
+
+ public static void init()
+ {
+ //GameRegistry.registerItem(new GroundRemoverItem("groundRemover"),"groundRemover");
+ }
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public void addInformation(ItemStack itemStack, EntityPlayer player, List info, boolean flag)
+ {
+ info.add("Vanilla block remover tool");
+ }
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void registerIcons(IIconRegister par1IconRegister)
+ {
+ this.itemIcon = par1IconRegister.registerIcon(IHLModInfo.MODID + ":vacuumSwitch");
+ }
+
+ @Override
+ public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int par7, float par8, float par9, float par10)
+ {
+ TileEntity t = world.getTileEntity(x, y, z);
+ if(world.isRemote)
+ {
+ IHLMod.proxy.createExplosionEffect(world, x, y, z, 16f);
+ }
+ return true;
+ }
+
+ @Override
+ public void onUpdate(ItemStack stack, World world, Entity entity, int slotIndex, boolean isCurrentItem)
+ {
+/* if(entity instanceof EntityPlayer && isCurrentItem && MinecraftServer.getServer().getTickCounter()%100==99)
+ {
+ int x = (int)entity.posX;
+ int y = (int)entity.posY;
+ int z = (int)entity.posZ;
+ for(int ix = x-16;ix < x+16;ix++)
+ {
+ for(int iz = z-16;iz < z+16;iz++)
+ {
+ for(int iy = 4;iy < y;iy++)
+ {
+ if(!(world.getBlock(ix, iy, iz) instanceof BlockOre || world.getBlock(ix, iy, iz) instanceof IHLFluidBlock))
+ {
+ world.setBlockToAir(ix, iy, iz);
+ }
+ }
+ }
+ }
+ }*/
+ }
+}
diff --git a/src/main/java/ihl/explosion/IHLEntityFallingPile.java b/src/main/java/ihl/explosion/IHLEntityFallingPile.java
new file mode 100644
index 0000000..79973d8
--- /dev/null
+++ b/src/main/java/ihl/explosion/IHLEntityFallingPile.java
@@ -0,0 +1,152 @@
+package ihl.explosion;
+
+import ihl.utils.IHLUtils;
+import net.minecraft.block.material.Material;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.item.EntityItem;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.item.ItemStack;
+import net.minecraft.network.play.server.S23PacketBlockChange;
+import net.minecraft.util.MathHelper;
+import net.minecraft.world.World;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.event.entity.item.ItemExpireEvent;
+
+public class IHLEntityFallingPile extends EntityItem{
+
+ public IHLEntityFallingPile(World world) {
+ super(world);
+ }
+
+ @Override
+ public void onUpdate()
+ {
+ ItemStack stack = this.getDataWatcher().getWatchableObjectItemStack(10);
+ if (stack != null && stack.getItem() != null)
+ {
+ if (stack.getItem().onEntityItemUpdate(this))
+ {
+ return;
+ }
+ }
+
+ if (this.getEntityItem() == null)
+ {
+ this.setDead();
+ }
+ else
+ {
+ this.onEntityUpdate();
+
+ if (this.delayBeforeCanPickup > 0)
+ {
+ --this.delayBeforeCanPickup;
+ }
+
+ this.prevPosX = this.posX;
+ this.prevPosY = this.posY;
+ this.prevPosZ = this.posZ;
+ this.motionY -= 0.03999999910593033D;
+ this.noClip = this.func_145771_j(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, this.posZ);
+ this.moveEntity(this.motionX, this.motionY, this.motionZ);
+ boolean flag = (int)this.prevPosX != (int)this.posX || (int)this.prevPosY != (int)this.posY || (int)this.prevPosZ != (int)this.posZ;
+
+ if (flag || this.ticksExisted % 25 == 0)
+ {
+ if (this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)).getMaterial() == Material.lava)
+ {
+ this.motionY = 0.20000000298023224D;
+ this.motionX = (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F);
+ this.motionZ = (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F);
+ this.playSound("random.fizz", 0.4F, 2.0F + this.rand.nextFloat() * 0.4F);
+ }
+
+ }
+
+ this.motionX *= 0.98D;
+ this.motionY *= 0.98D;
+ this.motionZ *= 0.98D;
+
+ if (this.onGround)
+ {
+ this.motionY *= -0.5D;
+ }
+
+ ++this.age;
+
+ ItemStack item = this.getEntityItem();
+
+ if (!this.worldObj.isRemote &&
+ (this.age >= lifespan || this.onGround))
+ {
+ if (item != null)
+ {
+ ItemExpireEvent event = new ItemExpireEvent(this, (item.getItem() == null ? 6000 : item.getItem().getEntityLifespan(item, worldObj)));
+ if (MinecraftForge.EVENT_BUS.post(event))
+ {
+ lifespan += event.extraLife;
+ }
+ else
+ {
+ int x = (int)(this.boundingBox.minX);
+ int y = (int)(this.boundingBox.minY);
+ int z = (int)(this.boundingBox.minZ);
+ int i=1;
+ do
+ {
+ int[] xz = new int[] {0,0,1,0,-1,0};
+ if(i<xz.length)
+ {
+ if(IHLUtils.isBlockCanBeReplaced(worldObj, x+xz[i-1], y, z+xz[i]))
+ {
+ x+=xz[i-1];
+ z+=xz[i];
+ if(IHLUtils.isBlockCanBeReplaced(worldObj, x, y-1, z))
+ {
+ this.setPosition(x+0.5d, y-0.5d, z+0.5d);
+ return;
+ }
+ PileTileEntity pte = new PileTileEntity();
+ pte.content=this.getEntityItem();
+ IHLUtils.setBlockAndTileEntityRaw(worldObj, x, y, z, PileBlock.instance, pte);
+ for(Object player:worldObj.playerEntities)
+ {
+ if(player instanceof EntityPlayerMP)
+ {
+ EntityPlayerMP playerMP = (EntityPlayerMP)player;
+ playerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(x,y,z,worldObj));
+ }
+ }
+
+ break;
+ }
+ else
+ {
+ i++;
+ }
+ }
+ else
+ {
+ i=1;
+ y++;
+ }
+ }
+ while(!IHLUtils.isBlockCanBeReplaced(worldObj, x, y, z) && y < 254);
+ this.setDead();
+ }
+ }
+ else
+ {
+ this.setDead();
+ }
+ }
+
+ if (item != null && item.stackSize <= 0)
+ {
+ this.setDead();
+ }
+ }
+ }
+
+ public void applyEntityCollision(Entity entity){}
+}
diff --git a/src/main/java/ihl/explosion/IHLEntityFallingPileRender.java b/src/main/java/ihl/explosion/IHLEntityFallingPileRender.java
new file mode 100644
index 0000000..02cca5d
--- /dev/null
+++ b/src/main/java/ihl/explosion/IHLEntityFallingPileRender.java
@@ -0,0 +1,51 @@
+package ihl.explosion;
+import java.util.Random;
+
+import org.lwjgl.opengl.GL11;
+
+import ihl.utils.IHLItemRenderer;
+import net.minecraft.client.renderer.entity.Render;
+import net.minecraft.client.renderer.entity.RenderManager;
+import net.minecraft.client.renderer.texture.TextureMap;
+import net.minecraft.entity.Entity;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.ResourceLocation;
+
+public class IHLEntityFallingPileRender extends Render{
+
+ private final IHLItemRenderer itemRenderer;
+ private final Random random = new Random(400);
+
+ public IHLEntityFallingPileRender()
+ {
+ super();
+ this.itemRenderer=new IHLItemRenderer(true);
+ }
+
+ @Override
+ public void doRender(Entity entity, double x, double y, double z, float arg4, float arg5)
+ {
+ GL11.glTranslated(x, y, z);
+ random.setSeed(entity.getEntityId());
+ IHLEntityFallingPile fp = (IHLEntityFallingPile) entity;
+ ItemStack stack = fp.getEntityItem();
+ for (int i = 0; i < 16; i++)
+ {
+ GL11.glPushMatrix();
+ GL11.glRotatef(90f,random.nextFloat()*2f-1f,random.nextFloat()*2f-1f,random.nextFloat()*2f-1f);
+ float tx = random.nextFloat()-0.5f;
+ float ty = random.nextFloat()-0.5f;
+ float tz = random.nextFloat()-0.5f;
+ GL11.glTranslatef(tx, ty, tz);
+ itemRenderer.doRender(RenderManager.instance,stack, 0, 0, 0);
+ GL11.glTranslatef(-tx, -ty, tz);
+ GL11.glPopMatrix();
+ }
+ }
+
+ @Override
+ protected ResourceLocation getEntityTexture(Entity arg0) {
+ return TextureMap.locationItemsTexture;
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/ihl/explosion/PileBlock.java b/src/main/java/ihl/explosion/PileBlock.java
new file mode 100644
index 0000000..f9ea862
--- /dev/null
+++ b/src/main/java/ihl/explosion/PileBlock.java
@@ -0,0 +1,133 @@
+package ihl.explosion;
+
+import java.util.ArrayList;
+
+import cpw.mods.fml.common.registry.GameRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import ihl.IHLModInfo;
+import ihl.items_blocks.IHLItemBlock;
+import net.minecraft.block.Block;
+import net.minecraft.block.ITileEntityProvider;
+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.IIcon;
+import net.minecraft.world.IBlockAccess;
+import net.minecraft.world.World;
+
+public class PileBlock extends Block implements ITileEntityProvider
+{
+ public static PileBlock instance;
+ public static int id;
+ protected PileBlock(Material material) {
+ super(material);
+ this.setBlockName("pileBlock");
+ this.setBlockTextureName("tubBronzeIcon");
+ instance = this;
+ this.setBlockBounds(0f, 0f, 0f, 1f, 0.5f, 1f);
+ }
+
+ @Override
+ public void onNeighborBlockChange(World world, int x, int y, int z, Block block)
+ {
+ if(!world.isRemote)
+ {
+ PileTileEntity pte = (PileTileEntity)world.getTileEntity(x, y, z);
+ pte.checkAndFall();
+ }
+ }
+
+ @Override
+ public int getRenderType()
+ {
+ return PileBlockRender.renderId;
+ }
+
+ @Override
+ public TileEntity createNewTileEntity(World word, int metadata) {
+ return new PileTileEntity();
+ }
+
+ public static void init()
+ {
+ GameRegistry.registerBlock(new PileBlock(Material.sand), IHLItemBlock.class,"pileBlock");
+ GameRegistry.registerTileEntity(PileTileEntity.class, "pileBlockTileEntity");
+ id = Block.getIdFromBlock(instance);
+ }
+
+ @Override
+ public boolean isOpaqueCube()
+ {
+ return false;
+ }
+
+ @Override
+ public boolean renderAsNormalBlock()
+ {
+ return false;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void registerBlockIcons(IIconRegister par1IconRegister)
+ {
+ this.blockIcon = par1IconRegister.registerIcon(IHLModInfo.MODID + ":pileTextureSpace");
+ }
+
+ @Override
+ public boolean onBlockActivated(World world,int x,int y,int z,EntityPlayer entityPlayer,int i,float pos_x,float pos_y,float pos_z)
+ {
+ if(!world.isRemote && world.getTileEntity(x,y,z) instanceof PileTileEntity)
+ {
+ PileTileEntity te = (PileTileEntity)world.getTileEntity(x,y,z);
+ if(entityPlayer.inventory.addItemStackToInventory(te.content))
+ {
+ te.content=null;
+ world.setBlockToAir(x, y, z);
+ entityPlayer.inventoryContainer.detectAndSendChanges();
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void onBlockHarvested(World world,int x,int y,int z,int meta, EntityPlayer entityPlayer)
+ {
+ if(!world.isRemote && world.getTileEntity(x,y,z) instanceof PileTileEntity)
+ {
+ PileTileEntity te = (PileTileEntity)world.getTileEntity(x,y,z);
+ if(entityPlayer.inventory.addItemStackToInventory(te.content))
+ {
+ te.content=null;
+ entityPlayer.inventoryContainer.detectAndSendChanges();
+ }
+ }
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public IIcon getIcon(IBlockAccess world, int x,int y,int z,int meta)
+ {
+ if(world.getTileEntity(x,y,z) instanceof PileTileEntity)
+ {
+ PileTileEntity te = (PileTileEntity)world.getTileEntity(x,y,z);
+ if(te.content!=null)
+ {
+ return te.content.getIconIndex();
+ }
+ }
+ return this.blockIcon;
+ }
+
+ @Override
+ public void dropBlockAsItemWithChance(World world, int x, int y, int z, int meta, float chance, int flag){}
+
+ @Override
+ public ArrayList<ItemStack> getDrops(World world, int x, int y, int z, int meta, int fortune) {
+ return new ArrayList<ItemStack>();
+ }
+}
diff --git a/src/main/java/ihl/explosion/PileBlockRender.java b/src/main/java/ihl/explosion/PileBlockRender.java
new file mode 100644
index 0000000..c5c8060
--- /dev/null
+++ b/src/main/java/ihl/explosion/PileBlockRender.java
@@ -0,0 +1,285 @@
+package ihl.explosion;
+
+import org.lwjgl.opengl.GL11;
+
+import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
+import cpw.mods.fml.client.registry.RenderingRegistry;
+import ihl.utils.IHLMathUtils;
+import net.minecraft.block.Block;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.world.IBlockAccess;
+import net.minecraftforge.common.util.ForgeDirection;
+
+public class PileBlockRender implements ISimpleBlockRenderingHandler {
+ public static int renderId;
+ public final PileTileEntityRender pileTileEntityRender;
+
+ public PileBlockRender() {
+ renderId = RenderingRegistry.getNextAvailableRenderId();
+ pileTileEntityRender = new PileTileEntityRender(this);
+ }
+
+ @Override
+ public int getRenderId() {
+ return renderId;
+ }
+
+ @Override
+ public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderblocks) {
+ Tessellator tessellator = Tessellator.instance;
+ block.setBlockBoundsForItemRender();
+ renderblocks.setRenderBoundsFromBlock(block);
+ GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F);
+ GL11.glTranslatef(-0.5F, -0.5F, -0.5F);
+ tessellator.startDrawingQuads();
+ tessellator.setNormal(0.0F, -1.0F, 0.0F);
+ renderblocks.renderFaceYNeg(block, 0.0D, 0.0D, 0.0D,
+ renderblocks.getBlockIconFromSideAndMetadata(block, 0, metadata));
+ tessellator.draw();
+ tessellator.startDrawingQuads();
+ tessellator.setNormal(0.0F, 1.0F, 0.0F);
+ renderblocks.renderFaceYPos(block, 0.0D, 0.0D, 0.0D,
+ renderblocks.getBlockIconFromSideAndMetadata(block, 1, metadata));
+ tessellator.draw();
+ tessellator.startDrawingQuads();
+ tessellator.setNormal(0.0F, 0.0F, -1.0F);
+ renderblocks.renderFaceZNeg(block, 0.0D, 0.0D, 0.0D,
+ renderblocks.getBlockIconFromSideAndMetadata(block, 2, metadata));
+ tessellator.draw();
+ tessellator.startDrawingQuads();
+ tessellator.setNormal(0.0F, 0.0F, 1.0F);
+ renderblocks.renderFaceZPos(block, 0.0D, 0.0D, 0.0D,
+ renderblocks.getBlockIconFromSideAndMetadata(block, 3, metadata));
+ tessellator.draw();
+ tessellator.startDrawingQuads();
+ tessellator.setNormal(-1.0F, 0.0F, 0.0F);
+ renderblocks.renderFaceXNeg(block, 0.0D, 0.0D, 0.0D,
+ renderblocks.getBlockIconFromSideAndMetadata(block, 4, metadata));
+ tessellator.draw();
+ tessellator.startDrawingQuads();
+ tessellator.setNormal(1.0F, 0.0F, 0.0F);
+ renderblocks.renderFaceXPos(block, 0.0D, 0.0D, 0.0D,
+ renderblocks.getBlockIconFromSideAndMetadata(block, 5, metadata));
+ tessellator.draw();
+ GL11.glTranslatef(0.5F, 0.5F, 0.5F);
+ }
+
+ @Override
+ public boolean renderWorldBlock(IBlockAccess blockAccess, int x, int y, int z, Block block, int meta,
+ RenderBlocks blockRenderer) {
+ TileEntity te = blockAccess.getTileEntity(x, y, z);
+ if (te instanceof PileTileEntity) {
+ PileTileEntity pte = (PileTileEntity) te;
+ long itemHash = getItemStackHash(pte.content);
+ if (this.pileTileEntityRender.subIconIdMap.containsKey(itemHash)) {
+ Tessellator tessellator = Tessellator.instance;
+ int subIconId = this.pileTileEntityRender.subIconIdMap.get(itemHash);
+ int[][][] brightness = new int[3][3][3];
+ this.generateBrightnessMatrix(blockAccess, x, y, z, brightness);
+ tessellator.setColorOpaque_F(1f, 1f, 1f);
+ boolean[] blocksViewAround = this.getBlocksViewAround(blockAccess, x, y, z);
+ if (blocksViewAround[0] && blocksViewAround[1] && blocksViewAround[2] && blocksViewAround[3]) {
+ this.addFlatTop(tessellator, x, y, z, brightness, subIconId);
+ } else if (!blocksViewAround[0] && blocksViewAround[1] && blocksViewAround[2] && blocksViewAround[3]) {
+ this.addSlope(tessellator, x, y, z, 0, brightness, subIconId);
+ } else if (blocksViewAround[0] && !blocksViewAround[1] && blocksViewAround[2] && blocksViewAround[3]) {
+ this.addSlope(tessellator, x, y, z, 1, brightness, subIconId);
+ } else if (blocksViewAround[0] && blocksViewAround[1] && !blocksViewAround[2] && blocksViewAround[3]) {
+ this.addSlope(tessellator, x, y, z, 2, brightness, subIconId);
+ } else if (blocksViewAround[0] && blocksViewAround[1] && blocksViewAround[2] && !blocksViewAround[3]) {
+ this.addSlope(tessellator, x, y, z, 3, brightness, subIconId);
+ }
+ // 2-sided piramid
+ else if (blocksViewAround[0] && blocksViewAround[1] && !blocksViewAround[2] && !blocksViewAround[3]) {
+ this.addTwoSidedPyramid(tessellator, x, y, z, 2, brightness, subIconId);
+ } else if (!blocksViewAround[0] && blocksViewAround[1] && blocksViewAround[2] && !blocksViewAround[3]) {
+ this.addTwoSidedPyramid(tessellator, x, y, z, 3, brightness, subIconId);
+ } else if (!blocksViewAround[0] && !blocksViewAround[1] && blocksViewAround[2] && blocksViewAround[3]) {
+ this.addTwoSidedPyramid(tessellator, x, y, z, 0, brightness, subIconId);
+ } else if (blocksViewAround[0] && !blocksViewAround[1] && !blocksViewAround[2] && blocksViewAround[3]) {
+ this.addTwoSidedPyramid(tessellator, x, y, z, 1, brightness, subIconId);
+ } else {
+ this.addPyramid(tessellator, x, y, z, brightness, subIconId);
+ }
+ if (!blockAccess.getBlock(x, y - 1, z).isOpaqueCube()) {
+ this.addBottom(tessellator, x, y, z, brightness, subIconId);
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ private boolean[] getBlocksViewAround(IBlockAccess blockAccess, int x, int y, int z) {
+ // +Z
+ // ^
+ // [ ][0][ ]
+ // [3][x][1] ->+X
+ // [ ][2][ ]
+ return new boolean[] { blockAccess.getBlock(x, y, z + 1).isOpaqueCube(),
+ blockAccess.getBlock(x + 1, y, z).isOpaqueCube(), blockAccess.getBlock(x, y, z - 1).isOpaqueCube(),
+ blockAccess.getBlock(x - 1, y, z).isOpaqueCube(), };
+ }
+
+ private void addBottom(Tessellator tessellator, int x, int y, int z, int[][][] brightness, int subIconId) {
+ double[][] quad1 = new double[4][3];
+ quad1[0] = new double[] { 0D, 0D, 1D };
+ quad1[1] = new double[] { 0D, 0D, 0D };
+ quad1[2] = new double[] { 1D, 0D, 0D };
+ quad1[3] = new double[] { 1D, 0D, 1D };
+ this.addQuad(tessellator, quad1, x, y, z, ForgeDirection.UP, brightness, subIconId);
+ }
+
+ private void addFlatTop(Tessellator tessellator, int x, int y, int z, int[][][] brightness, int subIconId) {
+ double[][] quad1 = new double[4][3];
+ double height = 0.9D;
+ quad1[0] = new double[] { 1D, height, 0D };
+ quad1[1] = new double[] { 0D, height, 0D };
+ quad1[2] = new double[] { 0D, height, 1D };
+ quad1[3] = new double[] { 1D, height, 1D };
+ this.addQuad(tessellator, quad1, x, y, z, ForgeDirection.UP, brightness, subIconId);
+ }
+
+ private void addSlope(Tessellator tessellator, int x, int y, int z, int rotation,
+ int[][][] brightness, int subIconId) {
+ double[][] quad = new double[4][3];
+ quad[0] = new double[] { 1D,1D, 0D }; // +X -Z
+ quad[1] = new double[] { 0D, 1D, 0D }; // -X -Z
+ quad[2] = new double[] { 0D, 0D, 1D }; // -X +Z
+ quad[3] = new double[] { 1D, 0D, 1D };
+ while (rotation-- > 0) {
+ rotateQuadByYAxis(quad);
+ }
+ this.addQuad(tessellator, quad, x, y, z, ForgeDirection.UP, brightness, subIconId);
+ }
+
+ private void addTwoSidedPyramid(Tessellator tessellator, int x, int y, int z, int rotation,
+ int[][][] brightness, int subIconId) {
+ double[][] quad = new double[4][3];
+ quad[0] = new double[] { 1D, 0D, 0D }; // +X -Z
+ quad[1] = new double[] { 0D, 1D, 0D }; // -X -Z
+ quad[2] = new double[] { 0D, 0D, 1D }; // -X +Z
+ quad[3] = new double[] { 1D, 0D, 1D };
+ while (rotation-- > 0) {
+ rotateQuadByYAxis(quad);
+ }
+ this.addQuad(tessellator, quad, x, y, z, ForgeDirection.UP, brightness, subIconId);
+ }
+
+ private void addPyramid(Tessellator tessellator, int x, int y, int z, int[][][] brightness, int subIconId) {
+ double[][] quad1 = new double[4][3];
+ double[][] quad2 = new double[4][3];
+ double pileHeight = 0.3D;
+ quad1[0] = new double[] { 1D, 0D, 1D };
+ quad1[1] = new double[] { 1D, 0D, 0D };
+ quad1[2] = new double[] { 0D, 0D, 0D };
+ quad1[3] = new double[] { 0.5D, pileHeight, 0.5D };
+ quad2 = copyAndRotateQuadByYAxis(quad1,2);
+ this.addQuad(tessellator, quad1, x, y, z, ForgeDirection.UP, brightness, subIconId);
+ this.addQuad(tessellator, quad2, x, y, z, ForgeDirection.UP, brightness, subIconId);
+ }
+
+ private void rotateQuadByYAxis(double[][] quad) {
+ for (double[] v : quad) {
+ double newV2 = 1 - v[0];
+ v[0] = v[2];
+ v[2] = newV2;
+ }
+ }
+
+ private double[][] copyAndRotateQuadByYAxis(double[][] quad, int rotation) {
+ double[][] quadOut = new double[4][3];
+ for (int i = 0; i < quad.length * 3; i++) {
+ quadOut[i / 3][i % 3] = quad[i / 3][i % 3];
+ }
+
+ while (rotation-- > 0) {
+ rotateQuadByYAxis(quadOut);
+ }
+ return quadOut;
+ }
+
+ private void addQuad(Tessellator tessellator, double[][] quad, int x, int y, int z, ForgeDirection uvmapping,
+ int[][][] brightness, int subIconId) {
+ int iu = 0;
+ int iv = 2;
+ if (uvmapping.offsetY == 0) {
+ iv = 1;
+ if (uvmapping.offsetZ == 0) {
+ iu = 2;
+ }
+ }
+ float[] normal = IHLMathUtils.get_triangle_normal(quad);
+ float minu = pileTileEntityRender.getSubIconMinU(subIconId);
+ float minv = pileTileEntityRender.getSubIconMinV(subIconId);
+ float du = pileTileEntityRender.getSubIconDU(subIconId);
+ float dv = pileTileEntityRender.getSubIconDV(subIconId);
+
+ double u1 = minu + quad[0][iu] * du;
+ double u2 = minu + quad[1][iu] * du;
+ double u3 = minu + quad[2][iu] * du;
+ double u4 = minu + quad[3][iu] * du;
+ double v1 = minv + quad[0][iv] * dv;
+ double v2 = minv + quad[1][iv] * dv;
+ double v3 = minv + quad[2][iv] * dv;
+ double v4 = minv + quad[3][iv] * dv;
+
+ tessellator.setNormal(normal[0], normal[1], normal[2]);
+ tessellator.setBrightness(this.getBrightness(quad[0], brightness));
+ tessellator.addVertexWithUV(x + quad[0][0], y + quad[0][1], z + quad[0][2], u1, v1);
+ tessellator.setBrightness(this.getBrightness(quad[1], brightness));
+ tessellator.addVertexWithUV(x + quad[1][0], y + quad[1][1], z + quad[1][2], u2, v2);
+ tessellator.setBrightness(this.getBrightness(quad[2], brightness));
+ tessellator.addVertexWithUV(x + quad[2][0], y + quad[2][1], z + quad[2][2], u3, v3);
+ tessellator.setBrightness(this.getBrightness(quad[3], brightness));
+ tessellator.addVertexWithUV(x + quad[3][0], y + quad[3][1], z + quad[3][2], u4, v4);
+ }
+
+ public long getItemStackHash(ItemStack stack) {
+ if (stack == null) {
+ return 0;
+ }
+ return ((long) Item.getIdFromItem(stack.getItem()) << 31 ^ stack.getItemDamage());
+ }
+
+ private void generateBrightnessMatrix(IBlockAccess blockAccess, int x, int y, int z, int[][][] brightness) {
+ for (int ix = -1; ix <= 1; ix++)
+ for (int iy = -1; iy <= 1; iy++)
+ for (int iz = -1; iz <= 1; iz++) {
+ Block block = blockAccess.getBlock(ix + x, iy + y, iz + z);
+ if (block != null && block != Blocks.air) {
+ brightness[ix + 1][iy + 1][iz + 1] = block.getMixedBrightnessForBlock(blockAccess, ix + x,
+ iy + y, iz + z);
+ } else {
+ brightness[ix + 1][iy + 1][iz + 1] = block.getMixedBrightnessForBlock(blockAccess, x, y, z);
+ }
+ }
+ }
+
+ private int getBrightness(double v[], int[][][] brightness) {
+ int x1 = v[0] < 0.5d ? 0 : 1;
+ int x2 = x1 + 1;
+ int y1 = v[1] < 0.5d ? 0 : 1;
+ int y2 = y1 + 1;
+ int z1 = v[2] < 0.5d ? 0 : 1;
+ int z2 = z1 + 1;
+ float dx = v[0] < 0.5d ? (float) v[0] * 2f : (float) v[0] * 2f - 1f;
+ float dy = v[1] < 0.5d ? (float) v[1] * 2f : (float) v[1] * 2f - 1f;
+ float dz = v[2] < 0.5d ? (float) v[2] * 2f : (float) v[2] * 2f - 1f;
+ int brightness1 = brightness[x1][y1][z1];
+ int brightness2 = brightness[x2][y2][z2];
+ float d = IHLMathUtils.sqrt(dx * dx + dy * dy + dz * dz);
+ return (int) (brightness1 * (1f - d) * 0.8f + brightness2 * d * 0.8f + brightness[1][1][1] * 0.2f) & 16711935;
+ }
+
+ @Override
+ public boolean shouldRender3DInInventory(int arg0) {
+ return true;
+ }
+}
diff --git a/src/main/java/ihl/explosion/PileTileEntity.java b/src/main/java/ihl/explosion/PileTileEntity.java
new file mode 100644
index 0000000..67f430a
--- /dev/null
+++ b/src/main/java/ihl/explosion/PileTileEntity.java
@@ -0,0 +1,78 @@
+package ihl.explosion;
+
+import ic2.core.IC2;
+import ihl.IHLMod;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.init.Blocks;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
+import net.minecraft.tileentity.TileEntity;
+
+public class PileTileEntity extends TileEntity {
+ public ItemStack content = new ItemStack(Blocks.sandstone);
+ private boolean firstTick = true;
+
+ @Override
+ public boolean canUpdate() {
+ return IC2.platform.isRendering();
+ }
+
+ @Override
+ public void updateEntity() {
+ if (firstTick && this.content != null) {
+ if (this.worldObj.isRemote) {
+ IHLMod.proxy.requestTileEntityInitdataFromClientToServer(xCoord, yCoord, zCoord);
+ } else {
+ checkAndFall();
+ }
+ firstTick = false;
+ }
+ }
+
+ public void setContent(ItemStack other) {
+ this.content = other;
+ }
+
+ public boolean checkAndFall() {
+ Block underblock = this.worldObj.getBlock(xCoord, yCoord - 1, zCoord);
+ if (underblock.isAir(worldObj, xCoord, yCoord - 1, zCoord) || underblock == Blocks.air
+ || underblock.getCollisionBoundingBoxFromPool(worldObj, xCoord, yCoord - 1, zCoord) == null) {
+ IHLEntityFallingPile fallingPile = new IHLEntityFallingPile(worldObj);
+ fallingPile.setPosition(xCoord + 0.5d, yCoord + 0.5d, zCoord + 0.5d);
+ fallingPile.setEntityItemStack(content);
+ this.worldObj.setBlockToAir(xCoord, yCoord, zCoord);
+ this.worldObj.spawnEntityInWorld(fallingPile);
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound nbttagcompound) {
+ super.readFromNBT(nbttagcompound);
+ this.content = ItemStack.loadItemStackFromNBT(nbttagcompound.getCompoundTag("content"));
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound nbttagcompound) {
+ super.writeToNBT(nbttagcompound);
+ NBTTagCompound contentNBT = new NBTTagCompound();
+ this.content.writeToNBT(contentNBT);
+ nbttagcompound.setTag("content", contentNBT);
+ }
+
+ public void updateBlockRender() {
+ Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(xCoord, yCoord, zCoord);
+ }
+
+ @Override
+ public void onDataPacket(NetworkManager net, S35PacketUpdateTileEntity pkt) {
+ this.readFromNBT(pkt.func_148857_g());
+ if (checkAndFall()) {
+ Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(xCoord, yCoord, zCoord);
+ }
+ }
+}
diff --git a/src/main/java/ihl/explosion/PileTileEntityRender.java b/src/main/java/ihl/explosion/PileTileEntityRender.java
new file mode 100644
index 0000000..56fc72f
--- /dev/null
+++ b/src/main/java/ihl/explosion/PileTileEntityRender.java
@@ -0,0 +1,187 @@
+package ihl.explosion;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import org.lwjgl.opengl.Display;
+import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL30;
+import org.lwjgl.util.glu.GLU;
+
+import ihl.IHLMod;
+import ihl.utils.IHLItemRenderer;
+import net.minecraft.block.Block;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.OpenGlHelper;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.entity.RenderManager;
+import net.minecraft.client.renderer.texture.TextureMap;
+import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
+import net.minecraft.item.ItemBlock;
+import net.minecraft.item.ItemStack;
+import net.minecraft.tileentity.TileEntity;
+import net.minecraft.util.IIcon;
+
+public class PileTileEntityRender extends TileEntitySpecialRenderer {
+
+ private int fb = -1;
+ private final int textureWidth = 64;
+ private final int textureHeight = 64;
+ private final PileBlockRender pileBlockRender;
+ public final Map<Long, Integer> subIconIdMap = new HashMap<Long, Integer>();
+ private int nextAvailableId = -1;
+ private boolean framebufferReady = false;
+ private Minecraft mc;
+ private final IHLItemRenderer ihlItemRenderer = new IHLItemRenderer(false);
+ private final Random random = new Random();
+
+ public PileTileEntityRender(PileBlockRender pileBlockRender1) {
+ pileBlockRender = pileBlockRender1;
+ mc = Minecraft.getMinecraft();
+ }
+
+ public void renderAModelAt(PileTileEntity tile, double x, double y, double z, float f) {
+ ItemStack stack = tile.content;
+ if (!framebufferReady) {
+ this.generateFrameBuffer();
+ Minecraft.getMinecraft().entityRenderer.setupCameraTransform(f, 0);
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
+ } else if (stack != null) {
+ long hash = this.pileBlockRender.getItemStackHash(stack);
+ if (!subIconIdMap.containsKey(hash)) {
+
+ subIconIdMap.put(hash, ++nextAvailableId);
+ this.preparetexture();
+ this.drawTexture(tile, nextAvailableId);
+ Minecraft.getMinecraft().entityRenderer.setupCameraTransform(f, 0);
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
+ tile.updateBlockRender();
+ }
+ }
+ }
+
+ private void generateFrameBuffer() {
+ fb = GL30.glGenFramebuffers();
+ this.preparetexture();
+ if (GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER) != GL30.GL_FRAMEBUFFER_COMPLETE) {
+ IHLMod.log.error("Something went wrong while creating frame buffer!");
+ IHLMod.log.error(GL30.glCheckFramebufferStatus(GL30.GL_FRAMEBUFFER));
+ } else {
+ IHLMod.log.info("FrameBuffer loaded correctly!");
+ }
+ this.framebufferReady = true;
+ }
+
+ private void preparetexture() {
+ GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fb);
+ int texture = Minecraft.getMinecraft().renderEngine.getTexture(TextureMap.locationBlocksTexture)
+ .getGlTextureId();
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
+ GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, texture, 0);
+ }
+
+ private void drawTexture(PileTileEntity tile, int subIconId) {
+ IIcon picon = PileBlock.instance.getIcon(0, 0);
+ float minu = picon.getMinU();
+ float minv = picon.getMinV();
+ float maxu = picon.getMaxU();
+ float maxv = picon.getMaxV();
+ int iconwidth = picon.getIconWidth();
+ int iconheight = picon.getIconHeight();
+ float du = maxu - minu;
+ float dv = maxv - minv;
+ int iconNumU = picon.getIconWidth()/this.textureWidth;
+ int posu = (int) (minu * iconwidth / du) + subIconId % iconNumU * textureWidth;
+ int posv = (int) (minv * iconheight / dv) + subIconId / iconNumU * textureHeight;
+
+ GL11.glViewport(posu, posv, textureWidth, textureHeight);
+ GL11.glMatrixMode(GL11.GL_PROJECTION);
+ GL11.glLoadIdentity();
+ GL11.glOrtho(-1d, 1d, -1d, 1d, 0.05F, this.mc.gameSettings.renderDistanceChunks * 32F);
+ GL11.glMatrixMode(GL11.GL_MODELVIEW);
+ GL11.glLoadIdentity();
+ ItemStack stack = tile.content;
+ GL11.glTranslatef(0, 0, -1f);
+ GLU.gluLookAt(0, 0, 0, -32f/* x reference */, 0f/* y reference */, 0f/* z reference */, 0.0f, 1.0f, 0.0f);
+ GL11.glColor4f(1f, 1f, 1f, 1f);
+ GL11.glRotatef(90f, 0, 1f, 0);
+ GL11.glScalef(2f, 2f, 2f);
+ OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 0xf0, 0xf0);
+ if (stack.getItem() instanceof ItemBlock) {
+ Block block = ((ItemBlock) stack.getItem()).field_150939_a;
+ IIcon icon = block.getIcon(0, stack.getItemDamage());
+ double u1 = (double) icon.getInterpolatedU(0D);
+ double u2 = (double) icon.getInterpolatedU(16.0D);
+ double v1 = (double) icon.getInterpolatedV(0D);
+ double v2 = (double) icon.getInterpolatedV(16.0D);
+ Tessellator tessellator = Tessellator.instance;
+ bindTexture(TextureMap.locationBlocksTexture);
+ tessellator.startDrawingQuads();
+ tessellator.setColorOpaque_F(1f, 1f, 1f);
+ tessellator.addVertexWithUV(-0.5, -0.5, 0, u1, v1);
+ tessellator.addVertexWithUV(0.5, -0.5, 0, u1, v2);
+ tessellator.addVertexWithUV(0.5, 0.5, 0, u2, v2);
+ tessellator.addVertexWithUV(-0.5, 0.5, 0, u2, v1);
+ tessellator.draw();
+ }
+ for (int i = 0; i < 128; i++) {
+ GL11.glPushMatrix();
+ float tx = random.nextFloat() - 0.5f;
+ float ty = random.nextFloat() - 0.5f;
+ GL11.glTranslatef(tx, ty, 0);
+ this.ihlItemRenderer.doRender(RenderManager.instance, stack, 0f, 0f, 0f);
+ GL11.glTranslatef(-tx, -ty, 0);
+ GL11.glPopMatrix();
+ }
+ GL11.glViewport(0, 0, Display.getWidth(), Display.getHeight());
+ }
+
+ public float getSubIconMinU(int index)
+ {
+ IIcon picon = PileBlock.instance.getIcon(0, 0);
+ int iconNumU = picon.getIconWidth()/this.textureWidth;
+ float minu = picon.getMinU();
+ float maxu = picon.getMaxU();
+ float du = (maxu - minu)/iconNumU;
+ return minu + index%iconNumU*du;
+ }
+
+ public float getSubIconMinV(int index)
+ {
+ IIcon picon = PileBlock.instance.getIcon(0, 0);
+ int iconNumU = picon.getIconWidth()/this.textureWidth;
+ int iconNumV = picon.getIconHeight()/this.textureHeight;
+ float minv = picon.getMinV();
+ float maxv = picon.getMaxV();
+ float dv = (maxv - minv)/iconNumV;
+ return minv + index/iconNumU*dv;
+ }
+ public float getSubIconDU(int index)
+ {
+ IIcon picon = PileBlock.instance.getIcon(0, 0);
+ int iconNumU = picon.getIconWidth()/this.textureWidth;
+ float minu = picon.getMinU();
+ float maxu = picon.getMaxU();
+ float du = (maxu - minu)/iconNumU;
+ return du;
+ }
+
+ public float getSubIconDV(int index)
+ {
+ IIcon picon = PileBlock.instance.getIcon(0, 0);
+ int iconNumV = picon.getIconHeight()/this.textureHeight;
+ float minv = picon.getMinV();
+ float maxv = picon.getMaxV();
+ float dv = (maxv - minv)/iconNumV;
+ return dv;
+ }
+
+
+
+ @Override
+ public void renderTileEntityAt(TileEntity par1TileEntity, double par2, double par4, double par6, float par8) {
+ this.renderAModelAt((PileTileEntity) par1TileEntity, par2, par4, par6, par8);
+ }
+
+} \ No newline at end of file
diff --git a/src/main/java/ihl/explosion/WorldSavedDataBlastWave.java b/src/main/java/ihl/explosion/WorldSavedDataBlastWave.java
new file mode 100644
index 0000000..73019b9
--- /dev/null
+++ b/src/main/java/ihl/explosion/WorldSavedDataBlastWave.java
@@ -0,0 +1,108 @@
+package ihl.explosion;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.world.WorldSavedData;
+
+public class WorldSavedDataBlastWave extends WorldSavedData {
+ Map<Long,Set<Integer[]>> data = new HashMap<Long,Set<Integer[]>>(256);
+
+ public WorldSavedDataBlastWave(String name)
+ {
+ super(name);
+ }
+
+ @Override
+ public void readFromNBT(NBTTagCompound nbt)
+ {
+ if(nbt.hasKey("entryList"))
+ {
+ NBTTagList entryList=nbt.getTagList("entryList", 10);
+ for(int i=0;i<entryList.tagCount();i++)
+ {
+ NBTTagCompound chunk = entryList.getCompoundTagAt(i);
+ long chunkXZKey = chunk.getLong("chunkXZKey");
+ NBTTagList blastWaveList = chunk.getTagList("blastWaveList", 10);
+ Set<Integer[]> blastWaveArraySet= new HashSet<Integer[]>();
+ for(int i1=0;i1<blastWaveList.tagCount();i1++)
+ {
+ NBTTagCompound blastWave = blastWaveList.getCompoundTagAt(i1);
+ Integer[] blastWaveArray = new Integer[5];
+ blastWaveArray[0]=blastWave.getInteger("ev");
+ blastWaveArray[1]=blastWave.getInteger("sourceX");
+ blastWaveArray[2]=blastWave.getInteger("sourceY");
+ blastWaveArray[3]=blastWave.getInteger("sourceZ");
+ blastWaveArray[4]=blastWave.getInteger("power");
+ blastWaveArray[5]=blastWave.getInteger("directionX");
+ blastWaveArray[6]=blastWave.getInteger("directionY");
+ blastWaveArray[7]=blastWave.getInteger("directionZ");
+ blastWaveArraySet.add(blastWaveArray);
+ }
+ data.put(chunkXZKey, blastWaveArraySet);
+ }
+ }
+ }
+
+ @Override
+ public void writeToNBT(NBTTagCompound nbt)
+ {
+ NBTTagList entryList = new NBTTagList();
+ Iterator<Entry<Long, Set<Integer[]>>> dataESI = data.entrySet().iterator();
+ while(dataESI.hasNext())
+ {
+ Entry<Long, Set<Integer[]>> dataEntry = dataESI.next();
+ Iterator<Integer[]> bwArrayI = dataEntry.getValue().iterator();
+ NBTTagCompound chunk = new NBTTagCompound();
+ NBTTagList blastWaveList = new NBTTagList();
+ while(bwArrayI.hasNext())
+ {
+ NBTTagCompound blastWave = new NBTTagCompound();
+ Integer[] bwArray = bwArrayI.next();
+ blastWave.setInteger("ev", bwArray[0]);
+ blastWave.setInteger("sourceX", bwArray[1]);
+ blastWave.setInteger("sourceY", bwArray[2]);
+ blastWave.setInteger("sourceZ", bwArray[3]);
+ blastWave.setInteger("power", bwArray[4]);
+ blastWave.setInteger("directionX", bwArray[5]);
+ blastWave.setInteger("directionY", bwArray[6]);
+ blastWave.setInteger("directionZ", bwArray[7]);
+ blastWaveList.appendTag(blastWave);
+ }
+ chunk.setTag("blastWaveList", blastWaveList);
+ chunk.setLong("chunkHash", dataEntry.getKey());
+ entryList.appendTag(chunk);
+ }
+ nbt.setTag("entryList", entryList);
+ }
+
+ public void scheduleExplosionEffectsOnChunkLoad(long chunkXZKey, int ev, int sourceX, int sourceY, int sourceZ, int power1, int[] directionMask)
+ {
+ Set<Integer[]> waves;
+ if(data.containsKey(chunkXZKey))
+ {
+ waves=data.get(chunkXZKey);
+ }
+ else
+ {
+ waves=new HashSet<Integer[]>(1024);
+ data.put(chunkXZKey, waves);
+ }
+ Integer[] wave = new Integer[8];
+ wave[0]=ev;
+ wave[1]=sourceX;
+ wave[2]=sourceY;
+ wave[3]=sourceZ;
+ wave[4]=power1;
+ wave[5]=directionMask[0];
+ wave[6]=directionMask[1];
+ wave[7]=directionMask[2];
+ waves.add(wave);
+ }
+}