Хочу ковер, который соединяется по краям и по углам с соседними коврами, пригодится для декораций. Его можно вешать на стену, на потолок, слать по углам.
Уже сделаны 3 стадии прорисовки:
1. Собственно, ковер.
2. Соединение с соседними коврами по краям.
3. Соединение с соседними коврами по углам.
Теперь надо добавить ambient occlusion.





Без коментариев

Сделал текстурку поколоритнее, цвета можно комбинировать:
Ковры соединяются с собой в бесконечном количестве, т.е. вы сможете постелить дома здоровенный ковер 5х5 или постелить длиннющий вдоль дорожки 20х2 к вашему гробу. Или обстелить весь гроб к черту, хоть какое-то разнообразие будет.
Ловушку с помощью ковра не сделать, потому что ковер стелится там, где есть блок.
Даже не знаю как быть со ступеньками, полублоками и косыми блоками. Надо будет что-то придумать.


Лицензия WTFPL.

package net.minecraft.src;
import java.util.List;
import java.util.Random;
public class BlockCarpet extends Block
{
public static final int[][] carpetColors = {
{ 221, 221, 221, },
{ 219, 125, 62, },
{ 179, 80, 188 },
{ 107, 138, 201, },
{ 177, 166, 39, },
{ 65, 174, 56, },
{ 208, 132, 153, },
{ 64, 64, 64, },
{ 154, 161, 161, },
{ 46, 110, 137, },
{ 126, 61, 181, },
{ 46, 56, 141, },
{ 79, 50, 31, },
{ 53, 70, 27, },
{ 150, 52, 48, },
{ 25, 22, 22, },
};
public int fillTextureIndex;
public int sidesTextureIndex;
public boolean colored;
protected BlockCarpet(int blockId, int baseTextureIndex, int sidesTextureIndex, int fillTextureIndex, boolean colored)
{
super(blockId, baseTextureIndex, Material.cloth);
this.setCreativeTab(CreativeTabs.tabDeco);
this.fillTextureIndex = fillTextureIndex;
this.sidesTextureIndex = sidesTextureIndex;
this.colored = colored;
}
public int getRenderColor(int damage)
{
return !colored ? 0xffffff :
((carpetColors[damage][0] & 0xff) ‹‹ 16) |
((carpetColors[damage][1] & 0xff) ‹‹ 8) |
(carpetColors[damage][2] & 0xff);
}
/**
* Determines the damage on the item the block drops. Used in cloth and wood.
*/
protected int damageDropped(int par1)
{
return par1;
}
/**
* Returns true if the block at the coordinates of world passed is a valid a carpet block.
*/
public static final boolean isCarpetBlockAt(IBlockAccess par0IBlockAccess, int par1, int par2, int par3)
{
int var4 = par0IBlockAccess.getBlockId(par1, par2, par3);
return isCarpetBlock(var4);
}
/**
* Return true if the parameter is a blockID for a carpet block.
*/
public static final boolean isCarpetBlock(int par0)
{
return isCarpetBlock(Block.blocksList[par0]);
}
/**
* Return true if the parameter is a blockID for a carpet block.
*/
public static final boolean isCarpetBlock(Block par0)
{
return par0 != null && par0 instanceof BlockCarpet;
}
/**
* Returns a bounding box from the pool of bounding boxes (this means this box can change after the pool has been
* cleared to be reused)
*/
public AxisAlignedBB getCollisionBoundingBoxFromPool(World par1World, int par2, int par3, int par4)
{
int dir = 0;
for(int i = 1; i ‹= 6; i ++) {
if(canPlaceBlockAt(par1World,
par2 + RenderBlocks.DV_DIRS[i][0],
par3 + RenderBlocks.DV_DIRS[i][1],
par4 + RenderBlocks.DV_DIRS[i][2])) {
if(dir == 0) dir = i;
else {
return AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(par2 + 0.0f, par3 + 0.0f, par4 + 0.0f, par2 + 1.0f, par3 + 1.0f, par4 + 1.0f);
}
}
}
float xmin = 0.0f, ymin = 0.0f, zmin = 0.0f;
float xmax = 1.0f, ymax = 1.0f, zmax = 1.0f;
xmin = Math.max(xmin, xmin + RenderBlocks.DV_DIRS[dir][0]);
xmax = Math.min(xmax, xmax + RenderBlocks.DV_DIRS[dir][0]);
ymin = Math.max(ymin, ymin + RenderBlocks.DV_DIRS[dir][1]);
ymax = Math.min(ymax, ymax + RenderBlocks.DV_DIRS[dir][1]);
zmin = Math.max(zmin, zmin + RenderBlocks.DV_DIRS[dir][2]);
zmax = Math.min(zmax, zmax + RenderBlocks.DV_DIRS[dir][2]);
System.out.format("setted up %f, %f, %f, %f, %f, %f\n",
xmin, ymin, zmin, xmax, ymax, zmax);
return AxisAlignedBB.getAABBPool().addOrModifyAABBInPool(par2 + xmin, par3 + ymin, par4 + zmin, par2 + xmax, par3 + ymax, par4 + zmax);
}
/**
* Is this block (a) opaque and (b) a full 1m cube? This determines whether or not to render the shared face of two
* adjacent blocks and also whether the player can attach torches, redstone wire, etc to this block.
*/
public boolean isOpaqueCube()
{
return false;
}
/**
* Updates the blocks bounds based on its current state. Args: world, x, y, z
*/
public void setBlockBoundsBasedOnState(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
int dir = 0;
for(int i = 1; i ‹= 6; i ++) {
if(canPlaceBlockAt(par1IBlockAccess,
par2 + RenderBlocks.DV_DIRS[i][0],
par3 + RenderBlocks.DV_DIRS[i][1],
par4 + RenderBlocks.DV_DIRS[i][2])) {
if(dir == 0) dir = i;
else {
setBlockBounds(0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
return;
}
}
}
float xmin = 0.0f, ymin = 0.0f, zmin = 0.0f;
float xmax = 1.0f, ymax = 1.0f, zmax = 1.0f;
xmin = Math.max(xmin, xmin + RenderBlocks.DV_DIRS[dir][0]);
xmax = Math.min(xmax, xmax + RenderBlocks.DV_DIRS[dir][0]);
ymin = Math.max(ymin, ymin + RenderBlocks.DV_DIRS[dir][1]);
ymax = Math.min(ymax, ymax + RenderBlocks.DV_DIRS[dir][1]);
zmin = Math.max(zmin, zmin + RenderBlocks.DV_DIRS[dir][2]);
zmax = Math.min(zmax, zmax + RenderBlocks.DV_DIRS[dir][2]);
System.out.format("setted up %f, %f, %f, %f, %f, %f\n",
xmin, ymin, zmin, xmax, ymax, zmax);
setBlockBounds(xmin, ymin, zmin, xmax, ymax, zmax);
}
/**
* If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
*/
public boolean renderAsNormalBlock()
{
return false;
}
/**
* The type of render function that is called for this block
*/
public int getRenderType()
{
return 501;
}
/**
* Returns the quantity of items to drop on block destruction.
*/
public int quantityDropped(Random par1Random)
{
return 1;
}
/**
* Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
*/
public boolean canPlaceBlockAt(World par1World, int par2, int par3, int par4)
{
return canPlaceBlockAt((IBlockAccess)par1World, par2, par3, par4);
}
/**
* Checks to see if its valid to put this block at the specified coordinates. Args: world, x, y, z
*/
public boolean canPlaceBlockAt(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
return canPlaceOn(par1IBlockAccess.getBlockId(par2, par3 - 1, par4)) ||
canPlaceOn(par1IBlockAccess.getBlockId(par2, par3 + 1, par4)) ||
canPlaceOn(par1IBlockAccess.getBlockId(par2, par3, par4 - 1)) ||
canPlaceOn(par1IBlockAccess.getBlockId(par2, par3, par4 + 1)) ||
canPlaceOn(par1IBlockAccess.getBlockId(par2 - 1, par3, par4)) ||
canPlaceOn(par1IBlockAccess.getBlockId(par2 + 1, par3, par4));
}
public static boolean canPlaceOn(Block block) {
return block != null && block.isOpaqueCube();
}
public static boolean canPlaceOn(int blockId) {
return canPlaceOn(Block.blocksList[blockId]);
}
private static int[][] neighboursToCheck = {
{ 1, 0, 0 }, { -1, 0, 0 },
{ 0, 1, 0 }, { 0, -1, 0 },
{ 0, 0, 1 }, { 0, 0, -1 },
{ 1, 1, 0 }, { 1, -1, 0 },
{ -1, 1, 0 }, { -1, -1, 0 },
{ 0, 1, 1 }, { 0, -1, 1 },
{ 0, 1, -1 }, { 0, -1, -1 },
} ;
/**
* Called whenever the block is added into the world. Args: world, x, y, z
*/
public void onBlockAdded(World par1World, int par2, int par3, int par4)
{
setBlockBoundsBasedOnState(par1World, par2, par3, par4);
//
// for(int i = 0; i ‹ neighboursToCheck.length; i ++) {
// if(par1World.getBlockId(par2 + neighboursToCheck[i][0], par3 + neighboursToCheck[i][1], par4 + neighboursToCheck[i][2]) == Block.carpet.blockID)
// onNeighborBlockChange(par1World, par2 + neighboursToCheck[i][0], par3 + neighboursToCheck[i][1], par4 + neighboursToCheck[i][2], Block.carpet.blockID);
// }
}
/**
* Lets the block know when one of its neighbor changes. Doesn't know which neighbor changed (coordinates passed are
* their own) Args: x, y, z, neighbor blockID
*/
public void onNeighborBlockChange(World par1World, int par2, int par3, int par4, int par5)
{
if(!canPlaceBlockAt(par1World, par2, par3, par4)) {
this.dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
par1World.setBlockWithNotify(par2, par3, par4, 0);
}
}
/**
* returns a list of blocks with the same ID, but different meta (eg: wood returns 4 blocks)
*/
public void getSubBlocks(int par1, CreativeTabs par2CreativeTabs, List par3List)
{
for (int var4 = 0; var4 ‹ 16; ++var4)
{
par3List.add(new ItemStack(par1, 1, var4));
}
}
/**
* Returns an item stack containing a single instance of the current block type. 'i' is the block's subtype/damage
* and is ignored for blocks which do not support subtypes. Blocks which cannot be harvested should return null.
*/
protected ItemStack createStackedBlock(int par1)
{
return new ItemStack(this.blockID, 1, par1);
}
/**
* Ray traces through the blocks collision from start vector to end vector returning a ray trace hit. Args: world,
* x, y, z, startVec, endVec
*/
public MovingObjectPosition collisionRayTrace(World par1World, int par2, int par3, int par4, Vec3 par5Vec3, Vec3 par6Vec3)
{
setBlockBoundsBasedOnState(par1World, par2, par3, par4);
return super.collisionRayTrace(par1World, par2, par3, par4, par5Vec3, par6Vec3);
}
}

// ...
public static final Block carpet = new BlockCarpet(250, 184, 185, 186, true).setHardness(0.1F).setBlockName("carpet").setRequiresSelfNotify();
public static final Block carpetF = new BlockCarpet(251, 187, 188, 189, false).setHardness(0.1F).setBlockName("carpetF").setRequiresSelfNotify();
// ...
static {
// ...
Item.itemsList[carpet.blockID] = (new ItemCarpet(carpet.blockID - 256)).setItemName("carpet");
Item.itemsList[carpetF.blockID] = (new ItemCarpet(carpetF.blockID - 256)).setItemName("carpetF");
}
// ...

for(int i = 0; i ‹ 16; i ++) {
this.addRecipe(new ItemStack(Item.itemsList[Block.carpet.blockID], 8, i), new Object[] {"##", "##", '#', new ItemStack(Item.itemsList[Block.cloth.blockID], 1, i)});
}
this.addRecipe(new ItemStack(Block.carpetF, 8), new Object[] {"##", "##", '#', Block.cloth });

// ...
/**
* Renders the block at the given coordinates using the block's rendering type
*/
public boolean renderBlockByRenderType(Block par1Block, int par2, int par3, int par4)
{
int var5 = par1Block.getRenderType();
par1Block.setBlockBoundsBasedOnState(this.blockAccess, par2, par3, par4);
// ...
if(var5 == 501) return renderBlockCarpet((BlockCarpet)par1Block, par2, par3, par4);
// ...
}
// ...
public static final int DV_ILLEGAL = 0;
public static final int DV_XPOS = 1;
public static final int DV_XNEG = 2;
public static final int DV_YPOS = 3;
public static final int DV_YNEG = 4;
public static final int DV_ZPOS = 5;
public static final int DV_ZNEG = 6;
public static final int DV_SAME = 0;
public static final int DV_OPPOSITE = 1;
public static final int DV_ROTATE_XPOS = 2;
public static final int DV_ROTATE_XNEG = 3;
public static final int DV_ROTATE_YPOS = 4;
public static final int DV_ROTATE_YNEG = 5;
public static final int DV_ROTATE_ZPOS = 6;
public static final int DV_ROTATE_ZNEG = 7;
public static final int[][] DV_TRANSFORMS = {
{ DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, },
{ DV_XPOS, DV_XNEG, DV_XPOS, DV_XPOS, DV_ZNEG, DV_ZPOS, DV_YPOS, DV_YNEG, },
{ DV_XNEG, DV_XPOS, DV_XNEG, DV_XNEG, DV_ZPOS, DV_ZNEG, DV_YNEG, DV_YPOS, },
{ DV_YPOS, DV_YNEG, DV_ZPOS, DV_ZNEG, DV_YPOS, DV_YPOS, DV_XNEG, DV_XPOS, },
{ DV_YNEG, DV_YPOS, DV_ZNEG, DV_ZPOS, DV_YNEG, DV_YNEG, DV_XPOS, DV_XNEG, },
{ DV_ZPOS, DV_ZNEG, DV_YNEG, DV_YPOS, DV_XPOS, DV_XNEG, DV_ZPOS, DV_ZPOS, },
{ DV_ZNEG, DV_ZPOS, DV_YPOS, DV_YNEG, DV_XNEG, DV_XPOS, DV_ZNEG, DV_ZNEG, },
};
public static final int[][] DV_DIRS = {
{ 0, 0, 0, },
{ 1, 0, 0, },
{ -1, 0, 0, },
{ 0, 1, 0, },
{ 0, -1, 0, },
{ 0, 0, 1, },
{ 0, 0, -1, },
};
private static final int[][][] CORNERS = {
null,
{ { 1, 0, 0, }, { 0, 1, 0, }, { 0, 0, 1, }, },
{ { 0, 0, 0, }, { 0, 0, 1, }, { 0, 1, 0, }, },
{ { 0, 1, 0, }, { 0, 0, 1, }, { 1, 0, 0, }, },
{ { 0, 0, 0, }, { 1, 0, 0, }, { 0, 0, 1, }, },
{ { 0, 0, 1, }, { 1, 0, 0, }, { 0, 1, 0, }, },
{ { 0, 0, 0, }, { 0, 1, 0, }, { 1, 0, 0, }, },
};
private static final int[][] TEXTURES_INSIDE = {
{ 0, 0, }, { 0, 1, }, { 1, 1, }, { 1, 0, },
};
private static final int[][] LAY_INSIDE = {
{ 0, 0, }, { 0, 1, }, { 1, 1, }, { 1, 0, },
};
private static final double[][][] carpet2ndStageTexCoords = {
{ { 0.0d, 0.0d, }, { 0.0d, 0.25d, }, { 1.0d, 0.25d, }, { 1.0d, 0.0d, }, },
{ { 1.0d, 0.75d, }, { 0.0d, 0.75d, }, { 0.0d, 1.0d, }, { 1.0d, 1.0d, }, },
{ { 0.0d, 0.25d, }, { 0.0d, 0.5d, }, { 1.0d, 0.5d, }, { 1.0d, 0.25d, }, },
{ { 1.0d, 0.5d, }, { 0.0d, 0.5d, }, { 0.0d, 0.75d, }, { 1.0d, 0.75d, }, },
};
private static final double[][][] carpet2ndStageLayCoords = {
{ { 0.0d, 0.0d, }, { 0.0d, 0.25d, }, { 1.0d, 0.25d, }, { 1.0d, 0.0d, }, },
{ { 0.75d, 0.0d, }, { 0.75d, 1.0d, }, { 1.0d, 1.0d, }, { 1.0d, 0.0d, }, },
{ { 0.0d, 0.75d, }, { 0.0d, 1.0d, }, { 1.0d, 1.0d, }, { 1.0d, 0.75d, }, },
{ { 0.0d, 0.0d, }, { 0.0d, 1.0d, }, { 0.25d, 1.0d, }, { 0.25d, 0.0d, }, },
};
private static final double[][][] carpet3rdStageTexCoords = {
{ { 0.0d, 0.0d, }, { 0.0d, 0.5d, }, { 0.5d, 0.5d, }, { 0.5d, 0.0d, }, },
{ { 0.5d, 0.0d, }, { 0.5d, 0.5d, }, { 1.0d, 0.5d, }, { 1.0d, 0.0d, }, },
{ { 0.5d, 0.5d, }, { 0.5d, 1.0d, }, { 1.0d, 1.0d, }, { 1.0d, 0.5d, }, },
{ { 0.0d, 0.5d, }, { 0.0d, 1.0d, }, { 0.5d, 1.0d, }, { 0.5d, 0.5d, }, },
};
private static final double[][][] carpet3rdStageLayCoords = {
{ { 0.0d, 0.0d, }, { 0.0d, 0.5d, }, { 0.5d, 0.5d, }, { 0.5d, 0.0d, }, },
{ { 0.5d, 0.0d, }, { 0.5d, 0.5d, }, { 1.0d, 0.5d, }, { 1.0d, 0.0d, }, },
{ { 0.5d, 0.5d, }, { 0.5d, 1.0d, }, { 1.0d, 1.0d, }, { 1.0d, 0.5d, }, },
{ { 0.0d, 0.5d, }, { 0.0d, 1.0d, }, { 0.5d, 1.0d, }, { 0.5d, 0.5d, }, },
};
private static final int[][][] DV_IDENTS = new int[3][3][3];
static {
for(int i = 1; i ‹= 6; i ++) {
DV_IDENTS[DV_DIRS[i][0] + 1][DV_DIRS[i][1] + 1][DV_DIRS[i][2] + 1] = i;
}
}
private static final int[] carpet3rdStageData = {
0, 0, 0, 0, 0,
535822336, 16769040, 524104, 1605357568, -2107637614,
-536870908, 56999775, 1772992, 1687355264, -79689729,
63, 0, 0, -1033680896, 1862277965, -67108646, 1073415303,
33544704,
};
private boolean renderBlockCarpet(BlockCarpet carpetBlock, int x, int y, int z) {
int metadata = this.blockAccess.getBlockMetadata(x, y, z);
int blockId = this.blockAccess.getBlockId(x, y, z);
int color = carpetBlock.getRenderColor(metadata);
if(metadata ‹ 0 || metadata ›= 16) metadata = 0;
double baseTexX = (double) ((carpetBlock.blockIndexInTexture & 0xf) ‹‹ 4) / 256.0d;
double baseTexY = (double) (carpetBlock.blockIndexInTexture & ~0xf) / 256.0d;
double addTexX = (double) ((carpetBlock.sidesTextureIndex & 0xf) ‹‹ 4) / 256.0d;
double addTexY = (double) (carpetBlock.sidesTextureIndex & ~0xf) / 256.0d;
double fillTexX = (double) ((carpetBlock.fillTextureIndex & 0xf) ‹‹ 4) / 256.0d;
double fillTexY = (double) (carpetBlock.fillTextureIndex & ~0xf) / 256.0d;
double textureW = 16.0d / 256.0d;
double textureH = 16.0d / 256.0d;
double renderHeight = -0.001d;
double renderHeight2 = renderHeight * 2.0d;
double renderHeight3 = renderHeight * 3.0d;
Tessellator tessellator = Tessellator.instance;
int brightness = carpetBlock.getMixedBrightnessForBlock(this.blockAccess, x, y, z);
tessellator.setBrightness(brightness);
tessellator.setColorOpaque_I(color);
for(int dir = 1; dir ‹= 6; dir ++) {
if(BlockCarpet.canPlaceOn(this.blockAccess.getBlockId(x + DV_DIRS[dir][0], y + DV_DIRS[dir][1], z + DV_DIRS[dir][2]))) {
int cx = CORNERS[dir][0][0];
int cy = CORNERS[dir][0][1];
int cz = CORNERS[dir][0][2];
int xx = CORNERS[dir][1][0];
int xy = CORNERS[dir][1][1];
int xz = CORNERS[dir][1][2];
int yx = CORNERS[dir][2][0];
int yy = CORNERS[dir][2][1];
int yz = CORNERS[dir][2][2];
// stage 1
for(int k = 0; k ‹ 4; k ++) {
tessellator.addVertexWithUV(
x + cx + xx * LAY_INSIDE[k][0] + yx * LAY_INSIDE[k][1] + DV_DIRS[dir][0] * renderHeight,
y + cy + xy * LAY_INSIDE[k][0] + yy * LAY_INSIDE[k][1] + DV_DIRS[dir][1] * renderHeight,
z + cz + xz * LAY_INSIDE[k][0] + yz * LAY_INSIDE[k][1] + DV_DIRS[dir][2] * renderHeight,
baseTexX + textureW * TEXTURES_INSIDE[k][0], baseTexY + textureH * TEXTURES_INSIDE[k][1]);
}
// stage 2
int sidedir = DV_IDENTS[-CORNERS[dir][1][0] + 1][-CORNERS[dir][1][1] + 1][-CORNERS[dir][1][2] + 1];
for(int side = 0; side ‹ 4; side ++) {
sidedir = DV_TRANSFORMS[sidedir][dir - DV_XPOS + DV_ROTATE_XPOS];
boolean canPlaceNear = BlockCarpet.canPlaceOn(this.blockAccess.getBlockId(x + DV_DIRS[sidedir][0], y + DV_DIRS[sidedir][1], z + DV_DIRS[sidedir][2]));
boolean canPlaceFar = BlockCarpet.canPlaceOn(this.blockAccess.getBlockId(x + DV_DIRS[sidedir][0] + DV_DIRS[dir][0], y + DV_DIRS[sidedir][1] + DV_DIRS[dir][1], z + DV_DIRS[sidedir][2] + DV_DIRS[dir][2]));
boolean carpetNear = BlockCarpet.isCarpetBlockAt(this.blockAccess, x + DV_DIRS[sidedir][0], y + DV_DIRS[sidedir][1], z + DV_DIRS[sidedir][2]);
boolean carpetFar = BlockCarpet.isCarpetBlockAt(this.blockAccess, x + DV_DIRS[sidedir][0] + DV_DIRS[dir][0], y + DV_DIRS[sidedir][1] + DV_DIRS[dir][1], z + DV_DIRS[sidedir][2] + DV_DIRS[dir][2]);
if(canPlaceNear || (carpetNear && canPlaceFar) || carpetFar) {
for(int k = 0; k ‹ 4; k ++) {
tessellator.addVertexWithUV(
x + cx + xx * carpet2ndStageLayCoords[side][k][0] + yx * carpet2ndStageLayCoords[side][k][1] + DV_DIRS[dir][0] * renderHeight * 2,
y + cy + xy * carpet2ndStageLayCoords[side][k][0] + yy * carpet2ndStageLayCoords[side][k][1] + DV_DIRS[dir][1] * renderHeight * 2,
z + cz + xz * carpet2ndStageLayCoords[side][k][0] + yz * carpet2ndStageLayCoords[side][k][1] + DV_DIRS[dir][2] * renderHeight * 2,
addTexX + textureW * carpet2ndStageTexCoords[side][k][0], addTexY + textureH * carpet2ndStageTexCoords[side][k][1]);
}
}
}
// stage 3
int sdir1 = DV_IDENTS[-CORNERS[dir][1][0] + 1][-CORNERS[dir][1][1] + 1][-CORNERS[dir][1][2] + 1];
for(int side = 0; side ‹ 4; side ++) {
int sdir2 = DV_TRANSFORMS[sdir1][dir - DV_XPOS + DV_ROTATE_XPOS];
int idx1 = this.blockAccess.getBlockId(x + DV_DIRS[sdir1][0] + DV_DIRS[dir][0], y + DV_DIRS[sdir1][1] + DV_DIRS[dir][1], z + DV_DIRS[sdir1][2] + DV_DIRS[dir][2]);
int idx2 = this.blockAccess.getBlockId(x + DV_DIRS[sdir1][0], y + DV_DIRS[sdir1][1], z + DV_DIRS[sdir1][2]);
int idz1 = this.blockAccess.getBlockId(x + DV_DIRS[sdir2][0] + DV_DIRS[dir][0], y + DV_DIRS[sdir2][1] + DV_DIRS[dir][1], z + DV_DIRS[sdir2][2] + DV_DIRS[dir][2]);
int idz2 = this.blockAccess.getBlockId(x + DV_DIRS[sdir2][0], y + DV_DIRS[sdir2][1], z + DV_DIRS[sdir2][2]);
int idxz1 = this.blockAccess.getBlockId(x + DV_DIRS[sdir1][0] + DV_DIRS[sdir2][0] + DV_DIRS[dir][0], y + DV_DIRS[sdir1][1] + DV_DIRS[sdir2][1] + DV_DIRS[dir][1], z + DV_DIRS[sdir1][2] + DV_DIRS[sdir2][2] + DV_DIRS[dir][2]);
int idxz2 = this.blockAccess.getBlockId(x + DV_DIRS[sdir1][0] + DV_DIRS[sdir2][0], y + DV_DIRS[sdir1][1] + DV_DIRS[sdir2][1], z + DV_DIRS[sdir1][2] + DV_DIRS[sdir2][2]);
int i1 = BlockCarpet.isCarpetBlock(idz1) ? 1 : Block.blocksList[idz1] != null && Block.blocksList[idz1].isOpaqueCube() ? 2 : 0;
int i2 = BlockCarpet.isCarpetBlock(idz2) ? 1 : Block.blocksList[idz2] != null && Block.blocksList[idz2].isOpaqueCube() ? 2 : 0;
int i3 = BlockCarpet.isCarpetBlock(idx1) ? 1 : Block.blocksList[idx1] != null && Block.blocksList[idx1].isOpaqueCube() ? 2 : 0;
int i4 = BlockCarpet.isCarpetBlock(idx2) ? 1 : Block.blocksList[idx2] != null && Block.blocksList[idx2].isOpaqueCube() ? 2 : 0;
int i5 = BlockCarpet.isCarpetBlock(idxz1) ? 1 : Block.blocksList[idxz1] != null && Block.blocksList[idxz1].isOpaqueCube() ? 2 : 0;
int i6 = BlockCarpet.isCarpetBlock(idxz2) ? 1 : Block.blocksList[idxz2] != null && Block.blocksList[idxz2].isOpaqueCube() ? 2 : 0;
int index = 0;
index = index * 3 + i1;
index = index * 3 + i2;
index = index * 3 + i3;
index = index * 3 + i4;
index = index * 3 + i5;
index = index * 3 + i6;
if((carpet3rdStageData[index ››› 5] & (1 ‹‹ (index & 0x1f))) != 0) {
for(int k = 0; k ‹ 4; k ++) {
tessellator.addVertexWithUV(
x + cx + xx * carpet3rdStageLayCoords[side][k][0] + yx * carpet3rdStageLayCoords[side][k][1] + DV_DIRS[dir][0] * renderHeight * 3,
y + cy + xy * carpet3rdStageLayCoords[side][k][0] + yy * carpet3rdStageLayCoords[side][k][1] + DV_DIRS[dir][1] * renderHeight * 3,
z + cz + xz * carpet3rdStageLayCoords[side][k][0] + yz * carpet3rdStageLayCoords[side][k][1] + DV_DIRS[dir][2] * renderHeight * 3,
fillTexX + textureW * carpet3rdStageTexCoords[side][k][0], fillTexY + textureH * carpet3rdStageTexCoords[side][k][1]);
}
}
sdir1 = sdir2;
}
}
}
return true;
}

package net.minecraft.src;
public class ItemCarpet extends ItemBlock {
public ItemCarpet(int par1)
{
super(par1);
this.setMaxDamage(0);
this.setHasSubtypes(((BlockCarpet)Block.blocksList[getBlockID()]).colored);
}
/**
* Gets an icon index based on an item's damage value
*/
public int getIconFromDamage(int par1)
{
return Block.blocksList[getBlockID()].getBlockTextureFromSideAndMetadata(2, BlockCloth.getBlockFromDye(par1));
}
public int getColorFromDamage(int par1, int par2) {
return Block.blocksList[getBlockID()].getRenderColor(par1);
}
/**
* Returns the metadata of the block which this Item (ItemBlock) can place
*/
public int getMetadata(int par1)
{
return par1;
}
public String getItemNameIS(ItemStack par1ItemStack)
{
return super.getItemName() + (getHasSubtypes() ? "." + ItemDye.dyeColorNames[BlockCloth.getBlockFromDye(par1ItemStack.getItemDamage())] : "");
}
}

import /* hidden! here should be imports of 3d graphics library */;
import java.util.ArrayList;
public class MainGen {
public static void main(String[] strs) {
Vector3d[] d = {
null,
Utils.X_AXIS,
Utils.X_AXIS.opposite(),
Utils.Y_AXIS,
Utils.Y_AXIS.opposite(),
Utils.Z_AXIS,
Utils.Z_AXIS.opposite(),
};
int maxalgos = 0;
ArrayList‹Vector3d›[] table = new ArrayList[d.length];
for(int i = 0; i ‹ table.length; i ++) {
table[i] = new ArrayList‹Vector3d›();
if(d[i] == null) continue;
// algo 0: same
table[i].add(d[i]);
// algo 1: opposite
table[i].add(d[i].opposite());
// algo 2: rotate xp
table[i].add(Utils.rotate(Utils.X_AXIS, d[i], Math.PI / 2));
// algo 3: rotate xn
table[i].add(Utils.rotate(Utils.X_AXIS.opposite(), d[i], Math.PI / 2));
// algo 4: rotate yp
table[i].add(Utils.rotate(Utils.Y_AXIS, d[i], Math.PI / 2));
// algo 5: rotate yn
table[i].add(Utils.rotate(Utils.Y_AXIS.opposite(), d[i], Math.PI / 2));
// algo 6: rotate zp
table[i].add(Utils.rotate(Utils.Z_AXIS, d[i], Math.PI / 2));
// algo 7: rotate zn
table[i].add(Utils.rotate(Utils.Z_AXIS.opposite(), d[i], Math.PI / 2));
// finish
maxalgos = Math.max(maxalgos, table[i].size());
}
// now generate Java code
System.out.println("/** GENERATED CODE: DO NOT MODIFY */");
String[] equivs = {
"ILLEGAL",
"XPOS",
"XNEG",
"YPOS",
"YNEG",
"ZPOS",
"ZNEG",
};
String[] ops = {
"SAME",
"OPPOSITE",
"ROTATE_XPOS",
"ROTATE_XNEG",
"ROTATE_YPOS",
"ROTATE_YNEG",
"ROTATE_ZPOS",
"ROTATE_ZNEG",
};
for(String s : equivs) {
System.out.format("\tprivate static final int DV_%s = %d;\n", s, find(s, equivs));
}
System.out.println();
for(String s : ops) {
System.out.format("\tprivate static final int DV_%s = %d;\n", s, find(s, ops));
}
System.out.println();
System.out.println("\tprivate static final int[][] DV_TRANSFORMS = {");
for(int k = 0; k ‹ table.length; k ++) {
ArrayList‹Vector3d› l = table[k];
System.out.print("\t\t{");
for(Vector3d v : l) {
int found = find(v, d);
System.out.format(" DV_%s,", equivs[found ‹ 0 ? 0 : found]);
}
for(int i = l.size(); i ‹ maxalgos; i ++) {
System.out.format(" DV_%s,", equivs[0]);
}
System.out.println(" },");
}
System.out.println("\t};");
System.out.println();
System.out.println("\tprivate static final int[][] DV_DIRS = {");
for(Vector3d v : d) {
System.out.format("\t\t{ %d, %d, %d, },\n",
(int)Math.round(v == null ? 0.0d : v.getXLength()),
(int)Math.round(v == null ? 0.0d : v.getYLength()),
(int)Math.round(v == null ? 0.0d : v.getZLength()));
}
System.out.println("\t};");
System.out.println();
// now generate corners
System.out.println();
System.out.println("\tprivate static final int[][][] CORNERS_INSIDE = {");
System.out.println("\t\tnull,");
Point3d pz = Utils.ZERO_ORIGIN;
Point3d po = new Point3d(1.0d, 1.0d, 1.0d);
for(int i = 1; i ‹ d.length; i ++) {
Vector3d dir = d[i];
Point3d v = new Point3d(0.5d, 0.5d, 0.5d);
Plane3d p = dir.perpendicular(v.translate(dir.product(0.5d)));
Point3d p1 = Utils.projection(p, pz);
Point3d p3 = Utils.projection(p, po);
Point3d pc = p1.translate(p1.fromTo(p3).product(0.5d));
Ray3d ray = new Ray3d(pc, dir);
Point3d p2 = Utils.rotate(ray, p1, Math.PI / 2);
Point3d p4 = Utils.rotate(ray, p3, Math.PI / 2);
System.out.format("\t\t{ { %d, %d, %d, }, { %d, %d, %d, }, { %d, %d, %d, }, { %d, %d, %d, }, },\n",
(int)Math.round(p1.getX()), (int)Math.round(p1.getY()), (int)Math.round(p1.getZ()),
(int)Math.round(p4.getX()), (int)Math.round(p4.getY()), (int)Math.round(p4.getZ()),
(int)Math.round(p3.getX()), (int)Math.round(p3.getY()), (int)Math.round(p3.getZ()),
(int)Math.round(p2.getX()), (int)Math.round(p2.getY()), (int)Math.round(p2.getZ()));
}
System.out.println("\t};");
System.out.println();
// now generate corners
System.out.println();
System.out.println("\tprivate static final int[][][] CORNERS = {");
System.out.println("\t\tnull,");
for(int i = 1; i ‹ d.length; i ++) {
Vector3d dir = d[i];
Point3d v = new Point3d(0.5d, 0.5d, 0.5d);
Plane3d p = dir.perpendicular(v.translate(dir.product(0.5d)));
Point3d p1 = Utils.projection(p, pz);
Point3d p3 = Utils.projection(p, po);
Point3d pc = p1.translate(p1.fromTo(p3).product(0.5d));
Ray3d ray = new Ray3d(pc, dir);
Point3d p2 = Utils.rotate(ray, p1, Math.PI / 2);
Point3d p4 = Utils.rotate(ray, p3, Math.PI / 2);
System.out.format("\t\t{ { %d, %d, %d, }, { %d, %d, %d, }, { %d, %d, %d, }, },\n",
(int)Math.round(p1.getX()), (int)Math.round(p1.getY()), (int)Math.round(p1.getZ()),
(int)Math.round(p2.getX() - p1.getX()), (int)Math.round(p2.getY() - p1.getY()), (int)Math.round(p2.getZ() - p1.getZ()),
(int)Math.round(p3.getX() - p2.getX()), (int)Math.round(p3.getY() - p2.getY()), (int)Math.round(p3.getZ() - p2.getZ()));
}
System.out.println("\t};");
System.out.println();
// generating carpetDvSides
System.out.println("\tprivate static final int[][] carpetDvSides = {");
System.out.println("\t\tnull,");
for(int i = 1; i ‹ d.length; i ++) {
Vector3d dir = d[i];
Point3d v = new Point3d(0.5d, 0.5d, 0.5d);
Plane3d p = dir.perpendicular(v.translate(dir.product(0.5d)));
Point3d p1 = Utils.projection(p, pz);
Point3d p3 = Utils.projection(p, po);
Point3d pc = p1.translate(p1.fromTo(p3).product(0.5d));
Ray3d ray = new Ray3d(pc, dir);
Point3d p2 = Utils.rotate(ray, p1, Math.PI / 2);
Point3d p4 = Utils.rotate(ray, p3, Math.PI / 2);
System.out.format("\t\t{ DV_%s, DV_%s, DV_%s, DV_%s, },\n",
equivs[find(Utils.rotate(dir, Utils.fromTo(p1, p4), Math.PI / 2), d)],
equivs[find(Utils.rotate(dir, Utils.fromTo(p4, p3), Math.PI / 2), d)],
equivs[find(Utils.rotate(dir, Utils.fromTo(p3, p2), Math.PI / 2), d)],
equivs[find(Utils.rotate(dir, Utils.fromTo(p2, p1), Math.PI / 2), d)]
);
}
System.out.println("\t};");
System.out.println();
// generating carpet3rdStageFlags
int other = 0;
int carpet = 1;
int block = 2;
int[][][] space = {
{
{ block, block, block, block, },
{ block, block, block, block, },
{ block, block, block, block, },
{ block, block, block, block, },
},
{
{ block, block, block, block, },
{ block, block, other, block, },
{ block, carpet, other, block, },
{ block, block, block, block, },
},
{
{ block, block, block, block, },
{ block, other, other, block, },
{ block, other, other, block, },
{ block, block, block, block, },
},
{
{ block, block, block, block, },
{ block, block, block, block, },
{ block, block, block, block, },
{ block, block, block, block, },
},
};
int[] data = new int[23];
for(int i1 = 0; i1 ‹ 3; i1 ++)
for(int i2 = 0; i2 ‹ 3; i2 ++)
for(int i3 = 0; i3 ‹ 3; i3 ++)
for(int i4 = 0; i4 ‹ 3; i4 ++)
for(int i5 = 0; i5 ‹ 3; i5 ++)
for(int i6 = 0; i6 ‹ 3; i6 ++) {
space[1][1][2] = i1;
space[1][2][2] = i2;
space[2][1][1] = i3;
space[2][2][1] = i4;
space[2][1][2] = i5;
space[2][2][2] = i6;
int perp = DV_YPOS;
int dir = DV_ZPOS;
int xc = 1;
int yc = 2;
int zc = 1;
for(;;) {
int next = space[xc + DV_DIRS[dir][0]][yc + DV_DIRS[dir][1]][zc + DV_DIRS[dir][2]];
if(next == block) {
int nperp = DV_TRANSFORMS[dir][DV_OPPOSITE];
dir = DV_TRANSFORMS[dir][perp - DV_XPOS + DV_ROTATE_XPOS];
perp = nperp;
// System.out.print("nblock");
} else {
next = space[xc + DV_DIRS[dir][0] + DV_DIRS[DV_TRANSFORMS[perp][DV_OPPOSITE]][0]]
[yc + DV_DIRS[dir][1] + DV_DIRS[DV_TRANSFORMS[perp][DV_OPPOSITE]][1]]
[zc + DV_DIRS[dir][2] + DV_DIRS[DV_TRANSFORMS[perp][DV_OPPOSITE]][2]];
if(next == block) {
xc += DV_DIRS[dir][0];
yc += DV_DIRS[dir][1];
zc += DV_DIRS[dir][2];
dir = DV_TRANSFORMS[dir][perp - DV_XPOS + DV_ROTATE_XPOS];
// System.out.print("nfree");
} else {
xc += DV_DIRS[dir][0] + DV_DIRS[DV_TRANSFORMS[perp][DV_OPPOSITE]][0];
yc += DV_DIRS[dir][1] + DV_DIRS[DV_TRANSFORMS[perp][DV_OPPOSITE]][1];
zc += DV_DIRS[dir][2] + DV_DIRS[DV_TRANSFORMS[perp][DV_OPPOSITE]][2];
int ndir = DV_TRANSFORMS[dir][perp - DV_XPOS + DV_ROTATE_XPOS];
perp = dir;
dir = ndir;
// System.out.print("nfree2");
}
}
if(perp == DV_TRANSFORMS[dir][DV_OPPOSITE]) throw new IllegalArgumentException();
// System.out.println(" " + xc + " " + yc + " " + zc + " " + dir + " " + perp);
if(xc == 1 && yc == 2 && zc == 1 && perp == DV_YPOS && dir == DV_ZPOS) {
int index = 0;
index = index * 3 + i1;
index = index * 3 + i2;
index = index * 3 + i3;
index = index * 3 + i4;
index = index * 3 + i5;
index = index * 3 + i6;
data[index ››› 5] |= 1 ‹‹ (index & 0x1f);
break;
}
if(space[xc][yc][zc] != carpet) break;
}
if(xc == 1 && yc == 2 && zc == 1 && perp == DV_YPOS && dir == DV_ZPOS) {
}
// System.out.println();
}
System.out.println("\tprivate static final int[] carpet3rdStageData = {");
System.out.print("\t\t");
for(int i = 0; i ‹ data.length; i ++) {
System.out.print(data[i] + ", ");
}
System.out.println();
System.out.println("\t};\n");
}
public static final int DV_ILLEGAL = 0;
public static final int DV_XPOS = 1;
public static final int DV_XNEG = 2;
public static final int DV_YPOS = 3;
public static final int DV_YNEG = 4;
public static final int DV_ZPOS = 5;
public static final int DV_ZNEG = 6;
public static final int DV_SAME = 0;
public static final int DV_OPPOSITE = 1;
public static final int DV_ROTATE_XPOS = 2;
public static final int DV_ROTATE_XNEG = 3;
public static final int DV_ROTATE_YPOS = 4;
public static final int DV_ROTATE_YNEG = 5;
public static final int DV_ROTATE_ZPOS = 6;
public static final int DV_ROTATE_ZNEG = 7;
public static final int[][] DV_TRANSFORMS = {
{ DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, DV_ILLEGAL, },
{ DV_XPOS, DV_XNEG, DV_XPOS, DV_XPOS, DV_ZNEG, DV_ZPOS, DV_YPOS, DV_YNEG, },
{ DV_XNEG, DV_XPOS, DV_XNEG, DV_XNEG, DV_ZPOS, DV_ZNEG, DV_YNEG, DV_YPOS, },
{ DV_YPOS, DV_YNEG, DV_ZPOS, DV_ZNEG, DV_YPOS, DV_YPOS, DV_XNEG, DV_XPOS, },
{ DV_YNEG, DV_YPOS, DV_ZNEG, DV_ZPOS, DV_YNEG, DV_YNEG, DV_XPOS, DV_XNEG, },
{ DV_ZPOS, DV_ZNEG, DV_YNEG, DV_YPOS, DV_XPOS, DV_XNEG, DV_ZPOS, DV_ZPOS, },
{ DV_ZNEG, DV_ZPOS, DV_YPOS, DV_YNEG, DV_XNEG, DV_XPOS, DV_ZNEG, DV_ZNEG, },
};
public static final int[][] DV_DIRS = {
{ 0, 0, 0, },
{ 1, 0, 0, },
{ -1, 0, 0, },
{ 0, 1, 0, },
{ 0, -1, 0, },
{ 0, 0, 1, },
{ 0, 0, -1, },
};
private static int find(Object obj, Object[] arr) {
for(int i = 0; i ‹ arr.length; i ++)
if(arr[i] == null ? obj == null : arr[i].equals(obj))
return i;
return -1;
}
}