From f355fc1643698f010a60535f0daad61bb4195355 Mon Sep 17 00:00:00 2001 From: AlgorithmX2 Date: Sun, 20 Jul 2014 03:53:05 -0500 Subject: [PATCH] Initial Paint Ball Implementation. --- block/misc/BlockPaint.java | 39 ++-- client/render/blocks/RenderBlockPaint.java | 127 ++++++++++++- client/texture/ExtraBlockTextures.java | 4 +- core/Registration.java | 2 + helpers/Splot.java | 79 +++++++++ items/misc/ItemPaintBall.java | 6 + items/tools/powered/ToolMassCannon.java | 44 +++-- tile/misc/TilePaint.java | 196 ++++++++++++++++++++- 8 files changed, 465 insertions(+), 32 deletions(-) create mode 100644 helpers/Splot.java diff --git a/block/misc/BlockPaint.java b/block/misc/BlockPaint.java index 41d5961f..e0b46e7e 100644 --- a/block/misc/BlockPaint.java +++ b/block/misc/BlockPaint.java @@ -4,13 +4,17 @@ import java.util.EnumSet; import java.util.List; import java.util.Random; -import net.minecraft.block.material.Material; +import net.minecraft.block.Block; +import net.minecraft.block.material.MapColor; +import net.minecraft.block.material.MaterialLiquid; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.item.Item; import net.minecraft.util.AxisAlignedBB; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import appeng.block.AEBaseBlock; +import appeng.client.render.BaseBlockRender; +import appeng.client.render.blocks.RenderBlockPaint; import appeng.core.features.AEFeature; import appeng.tile.misc.TilePaint; import appeng.util.Platform; @@ -19,12 +23,18 @@ public class BlockPaint extends AEBaseBlock { public BlockPaint() { - super( BlockPaint.class, Material.air ); + super( BlockPaint.class, new MaterialLiquid( MapColor.airColor ) ); setfeature( EnumSet.of( AEFeature.PaintBalls ) ); setTileEntiy( TilePaint.class ); + setLightOpacity( 0 ); isFullSize = false; isOpaque = false; - lightOpacity = 0; + } + + @Override + protected Class getRenderer() + { + return RenderBlockPaint.class; } @Override @@ -49,20 +59,17 @@ public class BlockPaint extends AEBaseBlock @Override public void fillWithRain(World w, int x, int y, int z) { - w.setBlock( x, y, z, Platform.air, 0, 3 ); + if ( Platform.isServer() ) + w.setBlock( x, y, z, Platform.air, 0, 3 ); } @Override - public boolean canBlockStay(World w, int x, int y, int z) + public void onNeighborBlockChange(World w, int x, int y, int z, Block junk) { TilePaint tp = getTileEntity( w, x, y, z ); if ( tp != null ) - { - return tp.canStay(); - } - - return false; + tp.onNeighborBlockChange(); } public AxisAlignedBB getCollisionBoundingBoxFromPool(World p_149668_1_, int p_149668_2_, int p_149668_3_, int p_149668_4_) @@ -87,4 +94,16 @@ public class BlockPaint extends AEBaseBlock return null; } + @Override + public boolean isAir(IBlockAccess world, int x, int y, int z) + { + return true; + } + + @Override + public boolean isReplaceable(IBlockAccess world, int x, int y, int z) + { + return true; + } + } diff --git a/client/render/blocks/RenderBlockPaint.java b/client/render/blocks/RenderBlockPaint.java index b010440c..8276fa2f 100644 --- a/client/render/blocks/RenderBlockPaint.java +++ b/client/render/blocks/RenderBlockPaint.java @@ -1,11 +1,17 @@ package appeng.client.render.blocks; import net.minecraft.client.renderer.RenderBlocks; +import net.minecraft.client.renderer.Tessellator; import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; import net.minecraft.world.IBlockAccess; import net.minecraftforge.client.IItemRenderer.ItemRenderType; +import net.minecraftforge.common.util.ForgeDirection; import appeng.block.AEBaseBlock; import appeng.client.render.BaseBlockRender; +import appeng.client.texture.ExtraBlockTextures; +import appeng.helpers.Splot; +import appeng.tile.misc.TilePaint; public class RenderBlockPaint extends BaseBlockRender { @@ -17,18 +23,125 @@ public class RenderBlockPaint extends BaseBlockRender @Override public void renderInventory(AEBaseBlock block, ItemStack is, RenderBlocks renderer, ItemRenderType type, Object[] obj) { - renderer.setRenderBounds( 0.25f, 0.0f, 0.25f, 0.75f, 0.5f, 0.75f ); - super.renderInventory( block, is, renderer, type, obj ); + } @Override public boolean renderInWorld(AEBaseBlock imb, IBlockAccess world, int x, int y, int z, RenderBlocks renderer) { - renderer.renderAllFaces = true; - renderer.setRenderBounds( 0.25f, 0.0f, 0.25f, 0.75f, 0.5f, 0.75f ); - boolean out = super.renderInWorld( imb, world, x, y, z, renderer ); - renderer.renderAllFaces = false; + TilePaint tp = imb.getTileEntity( world, x, y, z ); + boolean out = false; + if ( tp != null ) + { + // super.renderInWorld( imb, world, x, y, z, renderer ); + + IIcon icoSet[] = new IIcon[] { imb.getIcon( 0, 0 ), ExtraBlockTextures.BlockPaint2.getIcon(), ExtraBlockTextures.BlockPaint3.getIcon() }; + + Tessellator tess = Tessellator.instance; + + int lumen = 14 << 20 | 14 << 4; + int worldb = imb.getMixedBrightnessForBlock( world, x, y, z ); + + double offoff = 0.001; + + for (Splot s : tp.getDots()) + { + if ( s.lumen ) + { + tess.setColorOpaque_I( s.color.whiteVariant ); + tess.setBrightness( lumen ); + } + else + { + tess.setColorOpaque_I( s.color.mediumVariant ); + tess.setBrightness( worldb ); + } + + double offset = offoff; + offoff += 0.001; + + double H = 0.1; + + double pos_x = s.x(); + double pos_y = s.y(); + + pos_x = Math.max( H, Math.min( 1.0 - H, pos_x ) ); + pos_y = Math.max( H, Math.min( 1.0 - H, pos_y ) ); + + if ( s.side == ForgeDirection.SOUTH || s.side == ForgeDirection.NORTH ) + { + pos_x += x; + pos_y += y; + } + + else if ( s.side == ForgeDirection.UP || s.side == ForgeDirection.DOWN ) + { + pos_x += x; + pos_y += z; + } + + else + { + pos_x += y; + pos_y += z; + } + + IIcon ico = icoSet[s.getSeed() % icoSet.length]; + + switch (s.side) + { + case UP: + offset = 1.0 - offset; + tess.addVertexWithUV( pos_x - H, y + offset, pos_y - H, ico.getMinU(), ico.getMinV() ); + tess.addVertexWithUV( pos_x + H, y + offset, pos_y - H, ico.getMaxU(), ico.getMinV() ); + tess.addVertexWithUV( pos_x + H, y + offset, pos_y + H, ico.getMaxU(), ico.getMaxV() ); + tess.addVertexWithUV( pos_x - H, y + offset, pos_y + H, ico.getMinU(), ico.getMaxV() ); + break; + + case DOWN: + tess.addVertexWithUV( pos_x + H, y + offset, pos_y - H, ico.getMinU(), ico.getMinV() ); + tess.addVertexWithUV( pos_x - H, y + offset, pos_y - H, ico.getMaxU(), ico.getMinV() ); + tess.addVertexWithUV( pos_x - H, y + offset, pos_y + H, ico.getMaxU(), ico.getMaxV() ); + tess.addVertexWithUV( pos_x + H, y + offset, pos_y + H, ico.getMinU(), ico.getMaxV() ); + break; + + case EAST: + offset = 1.0 - offset; + tess.addVertexWithUV( x + offset, pos_x + H, pos_y - H, ico.getMinU(), ico.getMinV() ); + tess.addVertexWithUV( x + offset, pos_x - H, pos_y - H, ico.getMaxU(), ico.getMinV() ); + tess.addVertexWithUV( x + offset, pos_x - H, pos_y + H, ico.getMaxU(), ico.getMaxV() ); + tess.addVertexWithUV( x + offset, pos_x + H, pos_y + H, ico.getMinU(), ico.getMaxV() ); + break; + + case WEST: + tess.addVertexWithUV( x + offset, pos_x - H, pos_y - H, ico.getMinU(), ico.getMinV() ); + tess.addVertexWithUV( x + offset, pos_x + H, pos_y - H, ico.getMaxU(), ico.getMinV() ); + tess.addVertexWithUV( x + offset, pos_x + H, pos_y + H, ico.getMaxU(), ico.getMaxV() ); + tess.addVertexWithUV( x + offset, pos_x - H, pos_y + H, ico.getMinU(), ico.getMaxV() ); + break; + + case SOUTH: + offset = 1.0 - offset; + tess.addVertexWithUV( pos_x + H, pos_y - H, z + offset, ico.getMinU(), ico.getMinV() ); + tess.addVertexWithUV( pos_x - H, pos_y - H, z + offset, ico.getMaxU(), ico.getMinV() ); + tess.addVertexWithUV( pos_x - H, pos_y + H, z + offset, ico.getMaxU(), ico.getMaxV() ); + tess.addVertexWithUV( pos_x + H, pos_y + H, z + offset, ico.getMinU(), ico.getMaxV() ); + break; + + case NORTH: + tess.addVertexWithUV( pos_x - H, pos_y - H, z + offset, ico.getMinU(), ico.getMinV() ); + tess.addVertexWithUV( pos_x + H, pos_y - H, z + offset, ico.getMaxU(), ico.getMinV() ); + tess.addVertexWithUV( pos_x + H, pos_y + H, z + offset, ico.getMaxU(), ico.getMaxV() ); + tess.addVertexWithUV( pos_x - H, pos_y + H, z + offset, ico.getMinU(), ico.getMaxV() ); + break; + + default: + } + } + + out = true; + } + return out; } - } diff --git a/client/texture/ExtraBlockTextures.java b/client/texture/ExtraBlockTextures.java index a4220d54..59995269 100644 --- a/client/texture/ExtraBlockTextures.java +++ b/client/texture/ExtraBlockTextures.java @@ -75,7 +75,9 @@ public enum ExtraBlockTextures BlockCraftingUnitRing("BlockCraftingUnitRing"), BlockCraftingUnitRingLongRotated("BlockCraftingUnitRingLongRotated"), BlockCraftingUnitRingLong( "BlockCraftingUnitRingLong"), BlockCraftingUnitFit("BlockCraftingUnitFit"), - BlockCraftingMonitorOuter("BlockCraftingMonitorOuter"), BlockCraftingFitSolid("BlockCraftingFitSolid"); + BlockCraftingMonitorOuter("BlockCraftingMonitorOuter"), BlockCraftingFitSolid("BlockCraftingFitSolid"), + + BlockPaint2("BlockPaint2"), BlockPaint3("BlockPaint3"); final private String name; public IIcon IIcon; diff --git a/core/Registration.java b/core/Registration.java index 24c37295..1b88de16 100644 --- a/core/Registration.java +++ b/core/Registration.java @@ -43,6 +43,7 @@ import appeng.block.misc.BlockCondenser; import appeng.block.misc.BlockInscriber; import appeng.block.misc.BlockInterface; import appeng.block.misc.BlockLightDetector; +import appeng.block.misc.BlockPaint; import appeng.block.misc.BlockQuartzGrowthAccelerator; import appeng.block.misc.BlockQuartzTorch; import appeng.block.misc.BlockSecurity; @@ -342,6 +343,7 @@ public class Registration blocks.blockEnergyCellCreative = addFeature( BlockCreativeEnergyCell.class ); blocks.blockSecurity = addFeature( BlockSecurity.class ); + blocks.blockPaint = addFeature( BlockPaint.class ); items.itemCellCreative = addFeature( ItemCreativeStorageCell.class ); items.itemViewCell = addFeature( ItemViewCell.class ); diff --git a/helpers/Splot.java b/helpers/Splot.java new file mode 100644 index 00000000..19e42703 --- /dev/null +++ b/helpers/Splot.java @@ -0,0 +1,79 @@ +package appeng.helpers; + +import io.netty.buffer.ByteBuf; +import net.minecraft.util.Vec3; +import net.minecraftforge.common.util.ForgeDirection; +import appeng.api.util.AEColor; + +public class Splot +{ + + public Splot(AEColor col, boolean lit, ForgeDirection side, Vec3 Pos) { + color = col; + lumen = lit; + + double x, y; + + if ( side == ForgeDirection.SOUTH || side == ForgeDirection.NORTH ) + { + x = Pos.xCoord; + y = Pos.yCoord; + } + + else if ( side == ForgeDirection.UP || side == ForgeDirection.DOWN ) + { + x = Pos.xCoord; + y = Pos.zCoord; + } + + else + { + x = Pos.yCoord; + y = Pos.zCoord; + } + + int a = (int) (x * 0xF); + int b = (int) (y * 0xF); + this.pos = a | (b << 4); + + this.side = side; + } + + public Splot(ByteBuf data) { + + pos = data.readByte(); + int val = data.readByte(); + + side = ForgeDirection.getOrientation( val & 0x07 ); + color = AEColor.values()[(val >> 3) & 0x0F]; + lumen = ((val >> 7) & 0x01) > 0; + } + + public void writeToStream(ByteBuf stream) + { + stream.writeByte( pos ); + int val = side.ordinal() | (color.ordinal() << 3) | (lumen ? 0x80 : 0x00); + stream.writeByte( val ); + } + + final private int pos; + final public ForgeDirection side; + final public boolean lumen; + final public AEColor color; + + public float x() + { + return (float) (pos & 0x0f) / 15.0f; + } + + public float y() + { + return (float) ((pos >> 4) & 0x0f) / 15.0f; + } + + public int getSeed() + { + int val = side.ordinal() | (color.ordinal() << 3) | (lumen ? 0x80 : 0x00); + return Math.abs( pos + val ); + } +} diff --git a/items/misc/ItemPaintBall.java b/items/misc/ItemPaintBall.java index 10a6e218..b7123f07 100644 --- a/items/misc/ItemPaintBall.java +++ b/items/misc/ItemPaintBall.java @@ -60,4 +60,10 @@ public class ItemPaintBall extends AEBaseItem l.add( new ItemStack( this, 1, 20 + c.ordinal() ) ); } + public boolean isLumen(ItemStack is) + { + int dmg = is.getItemDamage(); + return dmg >= 20; + } + } diff --git a/items/tools/powered/ToolMassCannon.java b/items/tools/powered/ToolMassCannon.java index 960854f8..8c574cb7 100644 --- a/items/tools/powered/ToolMassCannon.java +++ b/items/tools/powered/ToolMassCannon.java @@ -10,8 +10,8 @@ import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; -import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; @@ -19,6 +19,7 @@ import net.minecraft.util.MovingObjectPosition; import net.minecraft.util.MovingObjectPosition.MovingObjectType; import net.minecraft.util.Vec3; import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; import appeng.api.AEApi; import appeng.api.config.Actionable; import appeng.api.config.FuzzyMode; @@ -45,6 +46,7 @@ import appeng.items.contents.CellUpgrades; import appeng.items.misc.ItemPaintBall; import appeng.items.tools.powered.powersink.AEBasePoweredItem; import appeng.me.storage.CellInventoryHandler; +import appeng.tile.misc.TilePaint; import appeng.util.Platform; public class ToolMassCannon extends AEBasePoweredItem implements IStorageCell @@ -134,18 +136,42 @@ public class ToolMassCannon extends AEBasePoweredItem implements IStorageCell Vec3 vec31 = vec3.addVector( (double) f7 * d3, (double) f6 * d3, (double) f8 * d3 ); Vec3 direction = Vec3.createVectorHelper( (double) f7 * d3, (double) f6 * d3, (double) f8 * d3 ); + direction.normalize(); float penitration = AEApi.instance().registries().matterCannon().getPenetration( ammo ); // 196.96655f; if ( penitration <= 0 ) { ItemStack type = ((IAEItemStack) aeammo).getItemStack(); - if ( type.getItem() instanceof ItemBlock ) + if ( type.getItem() instanceof ItemPaintBall ) { + MovingObjectPosition pos = w.rayTraceBlocks( vec3, vec31, false ); + if ( pos != null && pos.typeOfHit == MovingObjectType.BLOCK ) + { + ForgeDirection side = ForgeDirection.getOrientation( pos.sideHit ); - } - else if ( type.getItem() instanceof ItemPaintBall ) - { + int x = pos.blockX + side.offsetX; + int y = pos.blockY + side.offsetY; + int z = pos.blockZ + side.offsetZ; + Block whatsThere = w.getBlock( x, y, z ); + if ( whatsThere == AEApi.instance().blocks().blockPaint.block() ) + { + + } + else if ( whatsThere.isReplaceable( w, x, y, z ) && w.isAirBlock( x, y, z ) ) + { + w.setBlock( x, y, z, AEApi.instance().blocks().blockPaint.block(), 0, 3 ); + } + + TileEntity te = w.getTileEntity( x, y, z ); + if ( te instanceof TilePaint ) + { + pos.hitVec.xCoord -= x; + pos.hitVec.yCoord -= y; + pos.hitVec.zCoord -= z; + ((TilePaint) te).addBlot( type, side.getOpposite(), pos.hitVec ); + } + } } return item; } @@ -373,12 +399,8 @@ public class ToolMassCannon extends AEBasePoweredItem implements IStorageCell if ( pen > 0 ) return false; - /* - * if ( requsetedAddition.getItem() instanceof ItemPaintBall ) return false; - * - * if ( requsetedAddition.getItem() instanceof ItemBlock ) { Block blk = Block.getBlockFromItem( - * requsetedAddition.getItem() ); return blk == null; } - */ + if ( requsetedAddition.getItem() instanceof ItemPaintBall ) + return false; return true; } diff --git a/tile/misc/TilePaint.java b/tile/misc/TilePaint.java index 9f232f4c..2f8e1c5b 100644 --- a/tile/misc/TilePaint.java +++ b/tile/misc/TilePaint.java @@ -1,18 +1,208 @@ package appeng.tile.misc; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import net.minecraft.block.Block; +import net.minecraft.init.Blocks; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.Vec3; +import net.minecraft.world.EnumSkyBlock; +import net.minecraftforge.common.util.ForgeDirection; +import appeng.api.util.AEColor; +import appeng.helpers.Splot; +import appeng.items.misc.ItemPaintBall; import appeng.tile.AEBaseTile; +import appeng.tile.events.AETileEventHandler; +import appeng.tile.events.TileEventType; + +import com.google.common.collect.ImmutableList; public class TilePaint extends AEBaseTile { - public boolean canStay() + static final int LIGHT_PER_DOT = 12; + + int isLit = 0; + ArrayList dots = null; + + void writeBuffer(ByteBuf out) { - return false; + if ( dots == null ) + { + out.writeByte( 0 ); + return; + } + + out.writeByte( dots.size() ); + + for (Splot s : dots) + s.writeToStream( out ); + } + + void readBuffer(ByteBuf in) + { + byte howMany = in.readByte(); + + if ( howMany == 0 ) + { + isLit = 0; + dots = null; + return; + } + + dots = new ArrayList( howMany ); + for (int x = 0; x < howMany; x++) + dots.add( new Splot( in ) ); + + isLit = 0; + for (Splot s : dots) + { + if ( s.lumen ) + { + isLit += LIGHT_PER_DOT; + } + } + + maxLit(); + } + + class PaintHandler extends AETileEventHandler + { + + public PaintHandler() { + super( TileEventType.NETWORK, TileEventType.WORLD_NBT ); + } + + @Override + public void writeToNBT(NBTTagCompound data) + { + ByteBuf myDat = Unpooled.buffer(); + writeBuffer( myDat ); + if ( myDat.hasArray() ) + data.setByteArray( "dots", myDat.array() ); + } + + @Override + public void readFromNBT(NBTTagCompound data) + { + if ( data.hasKey( "dots" ) ) + readBuffer( Unpooled.copiedBuffer( data.getByteArray( "dots" ) ) ); + } + + @Override + public void writeToStream(ByteBuf data) throws IOException + { + writeBuffer( data ); + } + + @Override + public boolean readFromStream(ByteBuf data) throws IOException + { + readBuffer( data ); + return true; + } + } + + public TilePaint() { + addNewHandler( new PaintHandler() ); + } + + public void onNeighborBlockChange() + { + if ( dots == null ) + return; + + for (ForgeDirection side : ForgeDirection.VALID_DIRECTIONS) + { + Block blk = worldObj.getBlock( xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ ); + if ( !blk.isSideSolid( worldObj, xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ, side.getOpposite() ) ) + removeSide( side ); + } + + isLit = 0; + for (Splot s : dots) + { + if ( s.lumen ) + { + isLit += LIGHT_PER_DOT; + } + } + + maxLit(); + + if ( dots.isEmpty() ) + dots = null; + + if ( dots == null ) + worldObj.setBlock( xCoord, yCoord, zCoord, Blocks.air ); + } + + private void removeSide(ForgeDirection side) + { + Iterator i = dots.iterator(); + while (i.hasNext()) + { + Splot s = i.next(); + if ( s.side == side ) + i.remove(); + } + + markForUpdate(); + markDirty(); } public int getLightLevel() { - return 0; + return isLit; } + public void addBlot(ItemStack type, ForgeDirection side, Vec3 hitVec) + { + Block blk = worldObj.getBlock( xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ ); + if ( blk.isSideSolid( worldObj, xCoord + side.offsetX, yCoord + side.offsetY, zCoord + side.offsetZ, side.getOpposite() ) ) + { + ItemPaintBall ipb = (ItemPaintBall) type.getItem(); + + AEColor col = ipb.getColor( type ); + boolean lit = ipb.isLumen( type ); + + if ( dots == null ) + dots = new ArrayList(); + + if ( dots.size() > 20 ) + dots.remove( 0 ); + + dots.add( new Splot( col, lit, side, hitVec ) ); + if ( lit ) + isLit += LIGHT_PER_DOT; + + maxLit(); + markForUpdate(); + markDirty(); + } + } + + private void maxLit() + { + if ( isLit > 14 ) + isLit = 14; + + if ( worldObj != null ) + worldObj.updateLightByType( EnumSkyBlock.Block, xCoord, yCoord, zCoord ); + } + + public Collection getDots() + { + if ( dots == null ) + return ImmutableList.of(); + + return dots; + } }