From 0427ab89f1753a44b30cbc35ce021cbbdc845109 Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Thu, 10 Aug 2017 18:52:45 +0300 Subject: fix missing source folder --- .../explosion/ChunkAndWorldLoadEventHandler.java | 59 ++++ src/main/java/ihl/explosion/DetonatorMiniGUI.java | 82 +++++ src/main/java/ihl/explosion/ExplosionEntityFX.java | 177 ++++++++++ src/main/java/ihl/explosion/ExplosionRenderFX.java | 52 +++ .../java/ihl/explosion/ExplosionVectorBlockV2.java | 363 +++++++++++++++++++++ src/main/java/ihl/explosion/ExplosiveBlock.java | 252 ++++++++++++++ .../java/ihl/explosion/ExplosiveTileEntity.java | 78 +++++ src/main/java/ihl/explosion/GroundRemoverItem.java | 105 ++++++ .../java/ihl/explosion/IHLEntityFallingPile.java | 152 +++++++++ .../ihl/explosion/IHLEntityFallingPileRender.java | 51 +++ src/main/java/ihl/explosion/PileBlock.java | 133 ++++++++ src/main/java/ihl/explosion/PileBlockRender.java | 285 ++++++++++++++++ src/main/java/ihl/explosion/PileTileEntity.java | 78 +++++ .../java/ihl/explosion/PileTileEntityRender.java | 187 +++++++++++ .../ihl/explosion/WorldSavedDataBlastWave.java | 108 ++++++ 15 files changed, 2162 insertions(+) create mode 100644 src/main/java/ihl/explosion/ChunkAndWorldLoadEventHandler.java create mode 100644 src/main/java/ihl/explosion/DetonatorMiniGUI.java create mode 100644 src/main/java/ihl/explosion/ExplosionEntityFX.java create mode 100644 src/main/java/ihl/explosion/ExplosionRenderFX.java create mode 100644 src/main/java/ihl/explosion/ExplosionVectorBlockV2.java create mode 100644 src/main/java/ihl/explosion/ExplosiveBlock.java create mode 100644 src/main/java/ihl/explosion/ExplosiveTileEntity.java create mode 100644 src/main/java/ihl/explosion/GroundRemoverItem.java create mode 100644 src/main/java/ihl/explosion/IHLEntityFallingPile.java create mode 100644 src/main/java/ihl/explosion/IHLEntityFallingPileRender.java create mode 100644 src/main/java/ihl/explosion/PileBlock.java create mode 100644 src/main/java/ihl/explosion/PileBlockRender.java create mode 100644 src/main/java/ihl/explosion/PileTileEntity.java create mode 100644 src/main/java/ihl/explosion/PileTileEntityRender.java create mode 100644 src/main/java/ihl/explosion/WorldSavedDataBlastWave.java (limited to 'src/main/java/ihl/explosion') 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 bwArraySet = bwdata.data.remove(cc); + int[] directionMask = new int[3]; + Iterator 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= this.particleMaxAge) + { + this.setDead(); + } + for(int i=0;i startVectors = new HashSet(); + 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 chunksToUpdate = new HashSet(64); + private final Map cachedDrops = new HashMap(128); + final Map blastWaveByDimensionId = new HashMap(); + private final Map cachedEntities = new HashMap(); + 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=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 dropsList = block.getDrops(world, absX, absY, absZ, + ebs.getExtBlockMetadata(absX & 15, absY & 15, absZ & 15), 0); + Iterator 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 eList = this.getEntityList(chunk, absX, absY, absZ); + if (eList != null && !eList.isEmpty()) { + entities = new Entity[4096]; + Iterator 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 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> di = this.cachedDrops.entrySet().iterator(); + if (di.hasNext()) { + Entry 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 ci = this.chunksToUpdate.iterator(); + while (ci.hasNext()) { + Chunk chunk = ci.next(); + chunk.generateSkylightMap(); + Arrays.fill(chunk.updateSkylightColumns, true); + chunk.func_150804_b(false); + } + List chunks = new ArrayList(); + 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 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 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 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 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 removableBlockSet = new HashSet(); + 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 getDrops(World world, int x, int y, int z, int meta, int fortune) { + return new ArrayList(); + } +} 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 subIconIdMap = new HashMap(); + 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> data = new HashMap>(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 blastWaveArraySet= new HashSet(); + for(int i1=0;i1>> dataESI = data.entrySet().iterator(); + while(dataESI.hasNext()) + { + Entry> dataEntry = dataESI.next(); + Iterator 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 waves; + if(data.containsKey(chunkXZKey)) + { + waves=data.get(chunkXZKey); + } + else + { + waves=new HashSet(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); + } +} -- cgit v1.2.3