diff options
| author | Foghrye4 <foghrye4@gmail.com> | 2017-01-27 11:32:28 +0300 |
|---|---|---|
| committer | Foghrye4 <foghrye4@gmail.com> | 2017-01-27 11:32:28 +0300 |
| commit | 2db8e30b1d2151fdde5d08a6c06aef55f0c397d2 (patch) | |
| tree | e8cd0022f3a30a5c952092e0ea4c7ffdafcdf7bb /ihl/explosion | |
| parent | ffe23313fb7421b0a1849b420baf708999023f7b (diff) | |
License, readme and stuff
Diffstat (limited to 'ihl/explosion')
| -rw-r--r-- | ihl/explosion/ChunkAndWorldLoadEventHandler.java | 72 | ||||
| -rw-r--r-- | ihl/explosion/DetonatorMiniGUI.java | 83 | ||||
| -rw-r--r-- | ihl/explosion/ExplosionEntityFX.java | 177 | ||||
| -rw-r--r-- | ihl/explosion/ExplosionRenderFX.java | 51 | ||||
| -rw-r--r-- | ihl/explosion/ExplosionVectorBlockV2.java | 552 | ||||
| -rw-r--r-- | ihl/explosion/ExplosiveBlock.java | 252 | ||||
| -rw-r--r-- | ihl/explosion/ExplosiveTileEntity.java | 85 | ||||
| -rw-r--r-- | ihl/explosion/GroundRemoverItem.java | 106 | ||||
| -rw-r--r-- | ihl/explosion/IHLEntityFallingPile.java | 152 | ||||
| -rw-r--r-- | ihl/explosion/IHLEntityFallingPileRender.java | 52 | ||||
| -rw-r--r-- | ihl/explosion/PileBlock.java | 125 | ||||
| -rw-r--r-- | ihl/explosion/PileBlockRender.java | 342 | ||||
| -rw-r--r-- | ihl/explosion/PileTileEntity.java | 91 | ||||
| -rw-r--r-- | ihl/explosion/PileTileEntityRender.java | 160 | ||||
| -rw-r--r-- | ihl/explosion/WorldSavedDataBlastWave.java | 108 |
15 files changed, 2408 insertions, 0 deletions
diff --git a/ihl/explosion/ChunkAndWorldLoadEventHandler.java b/ihl/explosion/ChunkAndWorldLoadEventHandler.java new file mode 100644 index 0000000..d52672c --- /dev/null +++ b/ihl/explosion/ChunkAndWorldLoadEventHandler.java @@ -0,0 +1,72 @@ +package ihl.explosion; + +import ihl.IHLMod; + +import java.util.Iterator; +import java.util.Set; + +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.Explosion; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; + +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[] svset = new int[bwArraySet.size()]; + int[] directionMask = new int[3]; + int i=0; + Iterator<Integer[]> bwArrayI = bwArraySet.iterator(); + Integer[] bwArray = null; + while(bwArrayI.hasNext()) + { + bwArray=bwArrayI.next(); + svset[i]=bwArray[0]; + i++; + directionMask[0]=bwArray[5]; + directionMask[1]=bwArray[6]; + directionMask[2]=bwArray[7]; + IHLMod.explosionHandler.setPower(bwArray[0], bwArray[4]); + } +/* IHLMod.log.info("Doing schleduled explosion. Direction: ("+ + directionMask[0]+";"+directionMask[1]+";"+directionMask[2]+") "+ + "svset.length"+svset.length);*/ + IHLMod.explosionHandler.doExplosion(event.world, bwArray[1], bwArray[2], bwArray[3], svset, directionMask, new Explosion(event.world, null, bwArray[1], bwArray[2], bwArray[3], 100f)); + IHLMod.explosionHandler.sendChunkUpdateToPlayersInExplosionAffectedZone(event.world, bwArray[1], bwArray[2], bwArray[3]); + } + } + } + + @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/ihl/explosion/DetonatorMiniGUI.java b/ihl/explosion/DetonatorMiniGUI.java new file mode 100644 index 0000000..c969983 --- /dev/null +++ b/ihl/explosion/DetonatorMiniGUI.java @@ -0,0 +1,83 @@ +package ihl.explosion; + +import java.awt.event.KeyEvent; +import org.lwjgl.opengl.GL11; + +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; +import ihl.IHLMod; +import ihl.interfaces.ItemMiniGUI; +import ihl.utils.IHLUtils; + +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+78, yPos+3, 28, 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, 25); + int runnerXPos=xPos+5+114*detonator_delay/1350; + this.guiBase.drawTexturedModalRect(runnerXPos, yPos+18, 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+110, yPos+4, 0xFFCC00); + } + + @Override + public boolean handleMouseClick(int mouseX, int mouseY, int mouseButton) + { + if(mouseX>=xPos+5 && mouseX<=xPos+119 && mouseY>=yPos+17 && mouseY<=yPos+24) + { + this.detonator_delay=Math.max(1, Math.min(1350,(mouseX-xPos-5)*1350/114)); + this.detonatorDelayTextField.setText(Integer.toString(detonator_delay)); + } + if(mouseX>=xPos+78 && mouseX<=xPos+78+28 && mouseY>=yPos+3 && mouseY<=yPos+3+11) + { + this.detonatorDelayTextField.setFocused(true); + } + return mouseX>=xPos && mouseX<=xPos+202 && mouseY>=yPos && mouseY<=yPos+25; + } + + @Override + public boolean handleKeyTyped(char characterTyped, int keyIndex) + { + this.detonatorDelayTextField.textboxKeyTyped(characterTyped, keyIndex); + if(keyIndex==KeyEvent.VK_ACCEPT || keyIndex==KeyEvent.VK_ENTER || keyIndex==28 || keyIndex==156)//28 - enter;156 - numpad enter + { + 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/ihl/explosion/ExplosionEntityFX.java b/ihl/explosion/ExplosionEntityFX.java new file mode 100644 index 0000000..38e1034 --- /dev/null +++ b/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 = (int)(r2*radius/32)+64;
+ 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/ihl/explosion/ExplosionRenderFX.java b/ihl/explosion/ExplosionRenderFX.java new file mode 100644 index 0000000..da42d4e --- /dev/null +++ b/ihl/explosion/ExplosionRenderFX.java @@ -0,0 +1,51 @@ +package ihl.explosion;
+
+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;
+import org.lwjgl.opengl.GL11;
+
+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/ihl/explosion/ExplosionVectorBlockV2.java b/ihl/explosion/ExplosionVectorBlockV2.java new file mode 100644 index 0000000..5d94609 --- /dev/null +++ b/ihl/explosion/ExplosionVectorBlockV2.java @@ -0,0 +1,552 @@ +package ihl.explosion;
+
+import ihl.IHLMod;
+import ihl.utils.IHLUtils;
+
+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.Set;
+import java.util.Map.Entry;
+
+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;
+
+public class ExplosionVectorBlockV2
+{
+ public int[] startVectors = new int[1];
+ private final int[][] directionMasks = new int[8][3];
+ private final int bits = 8;
+ private final int maxValue = (1<<bits)-1;
+ private final int maxArraySize = (1<<bits*3)-1;
+ public final int[][] vectors = new int[maxArraySize][2];
+ public final float[] explosionPowerDampingFactor = new float[maxArraySize];
+ public final int[] explosionPower = new int[maxArraySize];
+ public final int[] cachedBlockHardness = new int[maxArraySize];
+ public final int[] cachedFluidBlocks = new int[maxArraySize];
+ public Map<Integer,List<ItemStack>> cachedBlockDrops = new HashMap<Integer, List<ItemStack>>(128);
+ public final List<int[]> dropBlocksPos = new ArrayList<int[]>(64);
+ public Set<Chunk> chunksToUpdate=new HashSet<Chunk>(64);
+ public Map<Integer,ItemStack> cachedDrops = new HashMap<Integer, ItemStack>(128);
+ public Set<Integer> dropBlocks = new HashSet<Integer>();
+ public Map<Integer,WorldSavedDataBlastWave> blastWaveByDimensionId = new HashMap<Integer, WorldSavedDataBlastWave>();
+ private Entity[] cachedEntities = new Entity[maxArraySize];
+
+ public ExplosionVectorBlockV2()
+ {
+ this.precalculateExplosion();
+ 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};
+ Arrays.fill(cachedBlockHardness,-1);
+ }
+
+ private int encodeXYZ(int x, int y, int z)
+ {
+ return x<<bits*2|y<<bits|z;
+ }
+
+ private int[] decodeXYZ(int l)
+ {
+ return new int[] {l>>bits*2,l>>bits&maxValue,l&maxValue};
+ }
+
+ public void precalculateExplosion()
+ {
+ startVectors[0]=0;
+ explosionPowerDampingFactor[0]=1f;
+ 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);
+ float df = (float)(prevXYZ[0]*prevXYZ[0]+prevXYZ[1]*prevXYZ[1]+prevXYZ[2]*prevXYZ[2]+64)/(float)(ix*ix+iy*iy+iz*iz+64);
+ explosionPowerDampingFactor[vxyz]=df;
+ }
+ }
+
+ private void findFreeSpace(int pvxyz,int vxyz)
+ {
+ if(vectors[pvxyz][0]==0)
+ {
+ vectors[pvxyz][0]=vxyz;
+ }
+ else if(vectors[pvxyz][1]==0)
+ {
+ vectors[pvxyz][1]=vxyz;
+ }
+ else
+ {
+ findFreeSpace(vectors[pvxyz][0],vxyz);
+ }
+ }
+
+ private void reduceCoordinate(int[] pxyz, int levelRadius)
+ {
+ if(Math.abs(pxyz[0])+Math.abs(pxyz[1])+Math.abs(pxyz[2])>Math.round(levelRadius*1.8f))
+ {
+ pxyz[0]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[0]);
+ pxyz[1]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[1]);
+ pxyz[2]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[2]);
+ }
+ else if(Math.abs(pxyz[0])<=Math.abs(pxyz[1]) && Math.abs(pxyz[0])<=Math.abs(pxyz[2]))
+ {
+ pxyz[1]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[1]);
+ pxyz[2]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[2]);
+ }
+ else if(Math.abs(pxyz[1])<=Math.abs(pxyz[0]) && Math.abs(pxyz[1])<=Math.abs(pxyz[2]))
+ {
+ pxyz[0]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[0]);
+ pxyz[2]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[2]);
+ }
+ else if(Math.abs(pxyz[2])<=Math.abs(pxyz[0]) && Math.abs(pxyz[2])<=Math.abs(pxyz[1]))
+ {
+ pxyz[1]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[1]);
+ pxyz[0]=IHLUtils.reduceVariableByAbsoluteValue(pxyz[0]);
+ }
+ }
+
+ public void setPower(int[] sv2, int power1)
+ {
+ for(int ev:sv2)
+ {
+ this.setPower(ev, power1);
+ }
+ }
+
+ public void setPower(int ev, int power1) {
+ this.explosionPower[ev]=power1;
+ }
+
+ public int[] breakBlocksAndGetDescendants(World world, int sourceX,int sourceY,int sourceZ, Explosion explosion, int ev, int[] directionMask)
+ {
+ int power1 = explosionPower[ev];
+ power1 = this.getNewPowerAndProcessBlocks(world, ev, sourceX, sourceY, sourceZ, explosion, power1, directionMask);
+ power1 = (int)(power1*explosionPowerDampingFactor[ev])-1;
+ if(power1<=1 || this.vectors[ev][0]==0)
+ {
+ return null;
+ }
+ else
+ {
+ for(int d1:this.vectors[ev])
+ {
+ if(d1!=0)
+ {
+ explosionPower[d1]=power1;
+ }
+ }
+ return this.vectors[ev];
+ }
+ }
+
+ 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 explosionResistance = this.getBlockResistance(world, ev, absX, absY, absZ, sourceX, sourceY, sourceZ, explosion, directionMask);
+ if(explosionResistance>=power1)
+ {
+ if(this.cachedFluidBlocks[ev]!=0)
+ {
+ //IHLMod.log.info("Schleduling update for "+Block.getBlockById(this.cachedFluidBlocks[ev]).getUnlocalizedName());
+ Block block = Block.getBlockById(this.cachedFluidBlocks[ev]);
+ block.onNeighborBlockChange(world, absX, absY, absZ, block);
+ }
+ else
+ {
+ this.dropBlocksPos.add(new int[] {absX, absY+1, absZ});
+ }
+ return 0;
+ }
+ else
+ {
+ power1-=explosionResistance;
+ this.onBlockDestroy(world, ev, absX, absY, absZ, power1, explosion);
+ return power1;
+ }
+ }
+ 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 getBlockResistance(World world, int ev, int absX, int absY, int absZ, int sourceX, int sourceY, int sourceZ, Explosion explosion, int[] directionMask)
+ {
+ if(this.cachedBlockHardness[ev]!=-1)
+ {
+ return this.cachedBlockHardness[ev];
+ }
+ else
+ {
+ this.precacheEBSBlocks(world, absX, absY, absZ, sourceX, sourceY, sourceZ, explosion, directionMask);
+ return this.cachedBlockHardness[ev];
+ }
+ }
+
+ public void precacheEBSBlocks(World world, int absX, int absY, int absZ, int sourceX, int sourceY, int sourceZ, Explosion explosion, int[] directonMask)
+ {
+ Chunk chunk = world.getChunkProvider().provideChunk(absX>>4, absZ>>4);
+ List<Entity> eList = this.getEntityList(chunk, absX, absY, absZ);
+ if(eList!=null)
+ {
+ Iterator<Entity> eListI = eList.iterator();
+ 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 - sourceX) * directonMask[0];
+ int ry = (entityY - sourceY) * directonMask[1];
+ int rz = (entityZ - sourceZ) * directonMask[2];
+ int ev = this.encodeXYZ(rx, ry, rz);
+ if(rx >= 0 && ry >= 0 && rz >= 0 && ev>=0 && ev<this.maxArraySize)
+ {
+ this.cachedEntities[ev]=entity;
+ }
+ }
+ }
+ ExtendedBlockStorage ebs = this.getEBS(chunk, absX, absY, absZ);
+ if(ebs==null)
+ {
+ for(int i4=0;i4<4096;i4++)
+ {
+ int blockWorldX = (i4 & 15)|(absX & 0xFFFFFFF0);
+ int blockWorldY = ((i4>>8) & 15)|(absY & 0xFFFFFFF0);
+ int blockWorldZ = ((i4>>4) & 15)|(absZ & 0xFFFFFFF0);
+
+ int rx = (blockWorldX - sourceX) * directonMask[0];
+ int ry = (blockWorldY - sourceY) * directonMask[1];
+ int rz = (blockWorldZ - sourceZ) * directonMask[2];
+
+ int ev = this.encodeXYZ(rx, ry, rz);
+ if(rx >= 0 && ry >= 0 && rz >= 0 && ev>=0 && ev<this.maxArraySize)
+ {
+ this.cachedBlockHardness[ev]=0;
+ }
+ }
+ }
+ else
+ {
+ byte[] lbsArray = ebs.getBlockLSBArray();
+ for(int i4=0;i4<lbsArray.length;i4++)
+ {
+ int var4 = lbsArray[i4] & 255;
+ if (ebs.getBlockMSBArray() != null)
+ {
+ var4 |= ebs.getBlockMSBArray().get(i4 & 15, (i4>>8) & 15, (i4>>4) & 15) << 8;
+ }
+ int blockWorldX = (i4 & 15)|(absX & 0xFFFFFFF0);
+ int blockWorldY = ((i4>>8) & 15)|(absY & 0xFFFFFFF0);
+ int blockWorldZ = ((i4>>4) & 15)|(absZ & 0xFFFFFFF0);
+ int rx = (blockWorldX - sourceX) * directonMask[0];
+ int ry = (blockWorldY - sourceY) * directonMask[1];
+ int rz = (blockWorldZ - sourceZ) * directonMask[2];
+
+ int ev = this.encodeXYZ(rx, ry, rz);
+ if(rx >= 0 && ry >= 0 && rz >= 0 && ev>=0 && ev<this.maxArraySize)
+ {
+ Block block = Block.getBlockById(var4);
+ if(block.canDropFromExplosion(explosion))
+ {
+ List<ItemStack> dropsList = (block.getDrops(world, blockWorldX, blockWorldY, blockWorldZ, ebs.getExtBlockMetadata(i4 & 15, (i4>>8) & 15, (i4>>4) & 15), 0));
+ if(dropsList!=null)
+ {
+ this.cachedBlockDrops.put(ev, dropsList);
+ }
+ }
+ if(block.getBlockHardness(world, blockWorldX, blockWorldY, blockWorldZ)<0)
+ {
+ this.cachedBlockHardness[ev]=Integer.MAX_VALUE;
+ }
+ else if(ev==0 && directonMask[0]+directonMask[1]+directonMask[2]==3)
+ {
+ this.cachedBlockHardness[ev]=0;
+ }
+ else
+ {
+ int br=Math.round(block.getExplosionResistance(null, world, blockWorldX, blockWorldY, blockWorldZ, sourceX, sourceY, sourceZ)*10f);
+ this.cachedBlockHardness[ev]=br;
+ }
+ if(block.getMaterial().isLiquid())
+ {
+ this.cachedFluidBlocks[ev]=var4;
+ }
+ }
+ }
+ }
+ }
+
+ 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];
+ }
+
+
+ public void onBlockDestroy(World world, int ev, int absX,int absY,int absZ, int power, Explosion explosion)
+ {
+ Chunk chunk = world.getChunkProvider().provideChunk(absX>>4, absZ>>4);
+ ExtendedBlockStorage ebs = this.getEBS(chunk, absX, absY, absZ);
+ if(ebs==null || ebs.isEmpty())
+ {
+ return;
+ }
+ 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);
+ }
+ if(this.cachedBlockDrops.containsKey(ev))
+ {
+ Iterator<ItemStack> drops = this.cachedBlockDrops.remove(ev).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 victim = this.cachedEntities[ev];
+ if(victim!=null)
+ {
+ victim.attackEntityFrom(DamageSource.setExplosionSource(explosion), power/10f);
+ this.cachedEntities[ev]=null;
+ }
+ this.dropBlocks.add(ev);
+ }
+
+ private void addDrops(World world, int sourceX, int sourceY, int sourceZ, int[] directionMask)
+ {
+ Iterator<Entry<Integer, ItemStack>> di = this.cachedDrops.entrySet().iterator();
+ Entry<Integer, ItemStack> cde = di.next();
+ while(di.hasNext() && this.dropBlocksPos.size() > 0)
+ {
+ int[] xyz = this.dropBlocksPos.remove(this.dropBlocksPos.size()-1);
+ int x = xyz[0];
+ int y = xyz[1];
+ int z = xyz[2];
+ int rx = (x - sourceX) * directionMask[0];
+ int ry = (y - sourceY) * directionMask[1];
+ int rz = (z - sourceZ) * directionMask[2];
+ int ev = encodeXYZ(rx,ry,rz);
+ int ev2 = encodeXYZ(rx,ry-1,rz);
+ if(this.dropBlocks.contains(ev) && !this.dropBlocks.contains(ev2))
+ {
+ 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();
+ if(di.hasNext())
+ {
+ cde = di.next();
+ }
+ else
+ {
+ return;
+ }
+ }
+ 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)
+ {
+// Set<Long> clientSideChunkXZKeySet = new HashSet<Long>();
+ 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);
+// long chunkXZKey = ChunkCoordIntPair.chunkXZ2Int(chunk.xPosition, chunk.zPosition);
+// clientSideChunkXZKeySet.add(chunkXZKey);
+ }
+ 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));
+ }
+ }
+// IHLMod.proxy.sendChunksLightUpdateQuery(world, sourceX, sourceY, sourceZ, clientSideChunkXZKeySet);
+ this.chunksToUpdate.clear();
+ }
+
+ public void doExplosion(World world, int sourceX, int sourceY, int sourceZ, final int[] startVectors1, int[] directionMask, Explosion explosion)
+ {
+ boolean doExplosion=true;
+ int[] sv = null;
+ int svsize = 0;
+ while(doExplosion)
+ {
+ int[] sv2= new int[1<<bits*2];
+ int sv2size = 0;
+ if(sv==null)
+ {
+ sv = startVectors1;
+ svsize = startVectors1.length;
+ }
+ for(int i=0;i<svsize;i++)
+ {
+ int[] sv3 = this.breakBlocksAndGetDescendants(world,
+ sourceX-(directionMask[0]<0?1:0),
+ sourceY-(directionMask[1]<0?1:0),
+ sourceZ-(directionMask[2]<0?1:0),
+ explosion, sv[i],directionMask);
+ if(sv3!=null)
+ {
+ for(int sv3v:sv3)
+ {
+ if(sv3v!=0)
+ {
+ sv2[sv2size]=sv3v;
+ sv2size++;
+ }
+ }
+ }
+ }
+ if(sv2size==0)
+ {
+ doExplosion=false;
+ sv = null;
+ if(!this.cachedDrops.isEmpty())
+ {
+ addDrops(world, sourceX, sourceY, sourceZ, directionMask);
+ }
+ break;
+ }
+ else
+ {
+ sv=sv2;
+ svsize=sv2size;
+ }
+ }
+ // Free and clean resources
+ this.cachedBlockDrops.clear();
+ this.cachedDrops.clear();
+ this.dropBlocks.clear();
+ this.dropBlocksPos.clear();
+ Arrays.fill(cachedBlockHardness,-1);
+ Arrays.fill(cachedFluidBlocks,0);
+ }
+
+ public void doExplosion(World world, int sourceX, int sourceY, int sourceZ, final int[] startVectors1)
+ {
+ IHLMod.log.info("Starting explosion server");
+ Explosion explosion = new Explosion(world, null, sourceX, sourceY, sourceZ, 100f);
+ for(int[] directionMask:directionMasks)
+ {
+ this.doExplosion(world, sourceX, sourceY, sourceZ, startVectors1, directionMask, explosion);
+ }
+ sendChunkUpdateToPlayersInExplosionAffectedZone(world, sourceX, sourceY, sourceZ);
+ }
+}
\ No newline at end of file diff --git a/ihl/explosion/ExplosiveBlock.java b/ihl/explosion/ExplosiveBlock.java new file mode 100644 index 0000000..446b177 --- /dev/null +++ b/ihl/explosion/ExplosiveBlock.java @@ -0,0 +1,252 @@ +package ihl.explosion; + +import ic2.core.IC2; +import ihl.IHLCreativeTab; +import ihl.IHLModInfo; +import ihl.items_blocks.IHLItemBlock; +import ihl.processing.metallurgy.MuffleFurnanceTileEntity; +import java.util.List; + +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; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +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", 100); + itemList.add(result); + result = new ItemStack(item); + result.stackTagCompound=new NBTTagCompound(); + result.stackTagCompound.setInteger("explosionType", 1);//0 - IC2; 1- IHL + result.stackTagCompound.setInteger("explosionPower", 31000);//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/ihl/explosion/ExplosiveTileEntity.java b/ihl/explosion/ExplosiveTileEntity.java new file mode 100644 index 0000000..002c959 --- /dev/null +++ b/ihl/explosion/ExplosiveTileEntity.java @@ -0,0 +1,85 @@ +package ihl.explosion; + +import ic2.core.IC2; +import ihl.IHLMod; +import ihl.utils.IHLMathUtils; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +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.setPower(IHLMod.explosionHandler.startVectors, power); + IHLMod.explosionHandler.doExplosion(worldObj, xCoord, yCoord, zCoord, IHLMod.explosionHandler.startVectors); + 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 && + player.getCurrentEquippedItem().getItem()==Items.flint_and_steel) + { + ignite(); + return true; + } + return false; + } + + 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/ihl/explosion/GroundRemoverItem.java b/ihl/explosion/GroundRemoverItem.java new file mode 100644 index 0000000..d3d2b80 --- /dev/null +++ b/ihl/explosion/GroundRemoverItem.java @@ -0,0 +1,106 @@ +package ihl.explosion;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+import cpw.mods.fml.common.registry.GameRegistry;
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+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;
+import ihl.IHLCreativeTab;
+import ihl.IHLMod;
+import ihl.IHLModInfo;
+
+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/ihl/explosion/IHLEntityFallingPile.java b/ihl/explosion/IHLEntityFallingPile.java new file mode 100644 index 0000000..79973d8 --- /dev/null +++ b/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/ihl/explosion/IHLEntityFallingPileRender.java b/ihl/explosion/IHLEntityFallingPileRender.java new file mode 100644 index 0000000..e3e0334 --- /dev/null +++ b/ihl/explosion/IHLEntityFallingPileRender.java @@ -0,0 +1,52 @@ +package ihl.explosion;
+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;
+
+import java.util.Random;
+
+import org.lwjgl.opengl.GL11;
+
+import ihl.utils.IHLItemRenderer;
+
+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/ihl/explosion/PileBlock.java b/ihl/explosion/PileBlock.java new file mode 100644 index 0000000..a2c56c3 --- /dev/null +++ b/ihl/explosion/PileBlock.java @@ -0,0 +1,125 @@ +package ihl.explosion; + +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.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 + ":fluidAcetyleneFlowing"); + } + + @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){} +} diff --git a/ihl/explosion/PileBlockRender.java b/ihl/explosion/PileBlockRender.java new file mode 100644 index 0000000..307cf3c --- /dev/null +++ b/ihl/explosion/PileBlockRender.java @@ -0,0 +1,342 @@ +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.Minecraft;
+import net.minecraft.client.renderer.RenderBlocks;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.texture.TextureMap;
+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.textureIdMap.containsKey(itemHash))
+ {
+ Tessellator tessellator = Tessellator.instance;
+ tessellator.draw();
+ int texture=this.pileTileEntityRender.textureIdMap.get(itemHash);
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
+ int[][][] brightness = new int[3][3][3];
+ this.generateBrightnessMatrix(blockAccess, x, y, z, brightness);
+ tessellator.startDrawing(GL11.GL_TRIANGLES);
+ 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);
+ }
+ else if(!blocksViewAround[0] &&
+ blocksViewAround[1] &&
+ blocksViewAround[2] &&
+ blocksViewAround[3])
+ {
+ this.addSlope(tessellator, x, y, z, 1, 1, 0, 1, brightness);
+ }
+ else if(blocksViewAround[0] &&
+ !blocksViewAround[1] &&
+ blocksViewAround[2] &&
+ blocksViewAround[3])
+ {
+ this.addSlope(tessellator, x, y, z, 0, 1, 1, 1, brightness);
+ }
+ else if(blocksViewAround[0] &&
+ blocksViewAround[1] &&
+ !blocksViewAround[2] &&
+ blocksViewAround[3])
+ {
+ this.addSlope(tessellator, x, y, z, 1, 1, 1, 0, brightness);
+ }
+ else if(blocksViewAround[0] &&
+ blocksViewAround[1] &&
+ blocksViewAround[2] &&
+ !blocksViewAround[3])
+ {
+ this.addSlope(tessellator, x, y, z, 1, 0, 1, 1, brightness);
+ }
+ // 2-sided piramid
+ else if(blocksViewAround[0] &&
+ blocksViewAround[1] &&
+ !blocksViewAround[2] &&
+ !blocksViewAround[3])
+ {
+ this.addSlope(tessellator, x, y, z, 1, 0, 1, 0, brightness);
+ }
+ else if(!blocksViewAround[0] &&
+ blocksViewAround[1] &&
+ blocksViewAround[2] &&
+ !blocksViewAround[3])
+ {
+ this.addSlope(tessellator, x, y, z, 1, 0, 0, 1, brightness);
+ }
+ else if(!blocksViewAround[0] &&
+ !blocksViewAround[1] &&
+ blocksViewAround[2] &&
+ blocksViewAround[3])
+ {
+ this.addSlope(tessellator, x, y, z, 0, 1, 0, 1, brightness);
+ }
+ else if(blocksViewAround[0] &&
+ !blocksViewAround[1] &&
+ !blocksViewAround[2] &&
+ blocksViewAround[3])
+ {
+ this.addSlope(tessellator, x, y, z, 0, 1, 1, 0, brightness);
+ }
+ else
+ {
+ this.addPyramid(tessellator, x, y, z, brightness);
+ }
+ if(!blockAccess.getBlock(x, y-1, z).isOpaqueCube())
+ {
+ this.addBottom(tessellator, x, y, z, brightness);
+ }
+ tessellator.draw();
+ Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationBlocksTexture);
+ tessellator.startDrawingQuads();
+ }
+ 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)
+ {
+ double[][] triangle1 = new double[3][3];
+ double[][] triangle2 = new double[3][3];
+ triangle1[0] = new double[] {0D,0D,1D};
+ triangle1[1] = new double[] {0D,0D,0D};
+ triangle1[2] = new double[] {1D,0D,0D};
+ triangle2[0] = triangle1[0];
+ triangle2[1] = triangle1[2];
+ triangle2[2] = new double[] {1D,0D,1D};
+ this.addTriangle(tessellator, triangle1, x, y, z, ForgeDirection.UP, brightness);
+ this.addTriangle(tessellator, triangle2, x, y, z, ForgeDirection.UP, brightness);
+ }
+
+ private void addFlatTop(Tessellator tessellator, int x, int y, int z, int[][][] brightness)
+ {
+ double[][] triangle1 = new double[3][3];
+ double[][] triangle2 = new double[3][3];
+ double height = 0.9D;
+ triangle1[0] = new double[] {1D,height,0D};
+ triangle1[1] = new double[] {0D,height,0D};
+ triangle1[2] = new double[] {0D,height,1D};
+ triangle2[0] = triangle1[2];
+ triangle2[1] = new double[] {1D,height,1D};
+ triangle2[2] = triangle1[0];
+ this.addTriangle(tessellator, triangle1, x, y, z, ForgeDirection.UP, brightness);
+ this.addTriangle(tessellator, triangle2, x, y, z, ForgeDirection.UP, brightness);
+ }
+
+ private void addSlope(Tessellator tessellator, int x, int y, int z, int px, int nx, int pz, int nz, int[][][] brightness)
+ {
+ double[][] triangle1 = new double[3][3];
+ double[][] triangle2 = new double[3][3];
+ if(px*pz+nx*nz==1)
+ {
+ triangle1[0] = new double[] {1D,px*nz,0D}; //+X -Z
+ triangle1[1] = new double[] {0D,nx*nz,0D}; //-X -Z
+ triangle1[2] = new double[] {1D,px*pz,1D}; //-X +Z
+ triangle2[0] = triangle1[2];
+ triangle2[1] = triangle1[1]; //+X +Z
+ triangle2[2] = new double[] {0D,nx*pz,1D};
+ }
+ else
+ {
+ triangle1[0] = new double[] {1D,px*nz,0D}; //+X -Z
+ triangle1[1] = new double[] {0D,nx*nz,0D}; //-X -Z
+ triangle1[2] = new double[] {0D,nx*pz,1D}; //-X +Z
+ triangle2[0] = triangle1[2];
+ triangle2[1] = new double[] {1D,px*pz,1D}; //+X +Z
+ triangle2[2] = triangle1[0];
+ }
+ this.addTriangle(tessellator, triangle1, x, y, z, ForgeDirection.UP, brightness);
+ this.addTriangle(tessellator, triangle2, x, y, z, ForgeDirection.UP, brightness);
+ }
+
+ private void addPyramid(Tessellator tessellator, int x, int y, int z, int[][][] brightness)
+ {
+ double[][] triangle1 = new double[3][3];
+ double[][] triangle2 = new double[3][3];
+ double[][] triangle3 = new double[3][3];
+ double[][] triangle4 = new double[3][3];
+ double pileHeight = 0.3D;
+ triangle1[0] = new double[] {1D,0D,0D};
+ triangle1[1] = new double[] {0D,0D,0D};
+ triangle1[2] = new double[] {0.5D,pileHeight,0.5D};
+ triangle2[0] = triangle1[1];
+ triangle2[1] = new double[] {0D,0D,1D};
+ triangle2[2] = triangle1[2];
+ triangle3[0] = triangle2[1];
+ triangle3[1] = new double[] {1D,0D,1D};
+ triangle3[2] = triangle1[2];
+ triangle4[0] = triangle3[1];
+ triangle4[1] = triangle1[0];
+ triangle4[2] = triangle1[2];
+ this.addTriangle(tessellator, triangle1, x, y, z, ForgeDirection.UP, brightness);
+ this.addTriangle(tessellator, triangle2, x, y, z, ForgeDirection.UP, brightness);
+ this.addTriangle(tessellator, triangle3, x, y, z, ForgeDirection.UP, brightness);
+ this.addTriangle(tessellator, triangle4, x, y, z, ForgeDirection.UP, brightness);
+ }
+
+ private void addTriangle(Tessellator tessellator, double[][] triangle, int x, int y, int z, ForgeDirection uvmapping, int[][][] brightness)
+ {
+ int iu = 0;
+ int iv = 2;
+ if(uvmapping.offsetY == 0)
+ {
+ iv = 1;
+ if(uvmapping.offsetZ == 0)
+ {
+ iu = 2;
+ }
+ }
+ float[] normal = IHLMathUtils.get_triangle_normal(triangle);
+ tessellator.setNormal(normal[0], normal[1], normal[2]);
+ tessellator.setBrightness(this.getBrightness(triangle[0], brightness));
+ tessellator.addVertexWithUV(x+triangle[0][0], y+triangle[0][1], z+triangle[0][2], triangle[0][iu], triangle[0][iv]);
+ tessellator.setBrightness(this.getBrightness(triangle[1], brightness));
+ tessellator.addVertexWithUV(x+triangle[1][0], y+triangle[1][1], z+triangle[1][2], triangle[1][iu], triangle[1][iv]);
+ tessellator.setBrightness(this.getBrightness(triangle[2], brightness));
+ tessellator.addVertexWithUV(x+triangle[2][0], y+triangle[2][1], z+triangle[2][2], triangle[2][iu], triangle[2][iv]);
+ }
+
+ 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;
+ }
+}
+
\ No newline at end of file diff --git a/ihl/explosion/PileTileEntity.java b/ihl/explosion/PileTileEntity.java new file mode 100644 index 0000000..b6046db --- /dev/null +++ b/ihl/explosion/PileTileEntity.java @@ -0,0 +1,91 @@ +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()); + Minecraft.getMinecraft().renderGlobal.markBlockForRenderUpdate(xCoord, yCoord, zCoord); + } +} + + diff --git a/ihl/explosion/PileTileEntityRender.java b/ihl/explosion/PileTileEntityRender.java new file mode 100644 index 0000000..ea8ab4f --- /dev/null +++ b/ihl/explosion/PileTileEntityRender.java @@ -0,0 +1,160 @@ +package ihl.explosion;
+
+import java.nio.IntBuffer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+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;
+
+import org.lwjgl.BufferUtils;
+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;
+
+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> textureIdMap = new HashMap<Long,Integer>();
+private IntBuffer textureIDBuffer;
+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(!textureIdMap.containsKey(hash))
+ {
+ textureIdMap.put(hash,textureIDBuffer.get(++nextAvailableId));
+ this.preparetexture(nextAvailableId);
+ this.drawTexture(tile);
+ Minecraft.getMinecraft().entityRenderer.setupCameraTransform(f, 0);
+ Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
+ tile.updateBlockRender();
+ }
+ }
+}
+
+private void generateFrameBuffer()
+{
+ textureIDBuffer = BufferUtils.createIntBuffer(Short.MAX_VALUE);
+ GL11.glGenTextures(textureIDBuffer);
+ fb=GL30.glGenFramebuffers();
+ this.preparetexture(0);
+ 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(int textureID)
+{
+ GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, fb);
+ int texture = textureIDBuffer.get(textureID);
+ GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture);
+ GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, GL11.GL_TEXTURE_2D, texture, 0);
+ GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB8, textureWidth, textureHeight, 0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, (java.nio.ByteBuffer)null);
+ GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP);
+ GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP);
+ GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER,GL11.GL_NEAREST);
+ GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_NEAREST);
+}
+
+private void drawTexture(PileTileEntity tile)
+{
+ GL11.glViewport(0, 0, textureWidth, textureHeight);
+ GL11.glClearColor(0f, 0f, 0f, 1f);
+ GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
+ 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);
+// Tessellator.instance.setBrightness(16711935);
+ 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());
+// IHLRenderUtils.instance.disableAmbientLighting();
+}
+
+@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/ihl/explosion/WorldSavedDataBlastWave.java b/ihl/explosion/WorldSavedDataBlastWave.java new file mode 100644 index 0000000..73019b9 --- /dev/null +++ b/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); + } +} |
