From 2db8e30b1d2151fdde5d08a6c06aef55f0c397d2 Mon Sep 17 00:00:00 2001 From: Foghrye4 Date: Fri, 27 Jan 2017 11:32:28 +0300 Subject: License, readme and stuff --- ihl/explosion/ChunkAndWorldLoadEventHandler.java | 72 +++ ihl/explosion/DetonatorMiniGUI.java | 83 ++++ ihl/explosion/ExplosionEntityFX.java | 177 ++++++++ ihl/explosion/ExplosionRenderFX.java | 51 +++ ihl/explosion/ExplosionVectorBlockV2.java | 552 +++++++++++++++++++++++ ihl/explosion/ExplosiveBlock.java | 252 +++++++++++ ihl/explosion/ExplosiveTileEntity.java | 85 ++++ ihl/explosion/GroundRemoverItem.java | 106 +++++ ihl/explosion/IHLEntityFallingPile.java | 152 +++++++ ihl/explosion/IHLEntityFallingPileRender.java | 52 +++ ihl/explosion/PileBlock.java | 125 +++++ ihl/explosion/PileBlockRender.java | 342 ++++++++++++++ ihl/explosion/PileTileEntity.java | 91 ++++ ihl/explosion/PileTileEntityRender.java | 160 +++++++ ihl/explosion/WorldSavedDataBlastWave.java | 108 +++++ 15 files changed, 2408 insertions(+) create mode 100644 ihl/explosion/ChunkAndWorldLoadEventHandler.java create mode 100644 ihl/explosion/DetonatorMiniGUI.java create mode 100644 ihl/explosion/ExplosionEntityFX.java create mode 100644 ihl/explosion/ExplosionRenderFX.java create mode 100644 ihl/explosion/ExplosionVectorBlockV2.java create mode 100644 ihl/explosion/ExplosiveBlock.java create mode 100644 ihl/explosion/ExplosiveTileEntity.java create mode 100644 ihl/explosion/GroundRemoverItem.java create mode 100644 ihl/explosion/IHLEntityFallingPile.java create mode 100644 ihl/explosion/IHLEntityFallingPileRender.java create mode 100644 ihl/explosion/PileBlock.java create mode 100644 ihl/explosion/PileBlockRender.java create mode 100644 ihl/explosion/PileTileEntity.java create mode 100644 ihl/explosion/PileTileEntityRender.java create mode 100644 ihl/explosion/WorldSavedDataBlastWave.java (limited to 'ihl/explosion') 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 bwArraySet = bwdata.data.remove(cc); + int[] svset = new int[bwArraySet.size()]; + int[] directionMask = new int[3]; + int i=0; + Iterator 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= this.particleMaxAge) + { + this.setDead(); + } + for(int i=0;i> cachedBlockDrops = new HashMap>(128); + public final List dropBlocksPos = new ArrayList(64); + public Set chunksToUpdate=new HashSet(64); + public Map cachedDrops = new HashMap(128); + public Set dropBlocks = new HashSet(); + public Map blastWaveByDimensionId = new HashMap(); + 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,l>>bits&maxValue,l&maxValue}; + } + + public void precalculateExplosion() + { + startVectors[0]=0; + explosionPowerDampingFactor[0]=1f; + for(int levelRadius=1; levelRadiusMath.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 eList = this.getEntityList(chunk, absX, absY, absZ); + if(eList!=null) + { + Iterator 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>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>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 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 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 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> di = this.cachedDrops.entrySet().iterator(); + Entry 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 clientSideChunkXZKeySet = new HashSet(); + Iterator 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 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)); + } + } +// 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< 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 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/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+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 textureIdMap = new HashMap(); +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> 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