Делаем сначала воду:
Создаём mod_new_fluid.java, и пишем туда:
Code
package net.minecraft.src;
public class mod_new_fluid extends BaseMod
{
public static final Block NewWaterMoving = new BlockNewFlowingFluid(233, Material.water).setHardness(100F).setLightOpacity(3).setBlockName("NewFlowingFluid").disableStats().setRequiresSelfNotify();
public static final Block NewWaterStationary = new BlockNewStationaryFluid(234, Material.water).setHardness(100F).setLightOpacity(3).setBlockName("NewStationaryFluid").disableStats().setRequiresSelfNotify();
public static final Block NewMovingLava = new BlockNewFlowingFluid(235, Material.lava).setHardness(100F).setLightOpacity(3).setBlockName("NewFlowingLava").disableStats().setRequiresSelfNotify();
public static final Block NewStationaryLava = new BlockNewStationaryFluid(236, Material.lava).setHardness(100F).setLightOpacity(3).setBlockName("NewStationaryLava").disableStats().setRequiresSelfNotify();
public String getVersion()
{
return "1.3.1 new water";
}
public void load()
{
ModLoader.registerBlock(NewWaterMoving);
ModLoader.registerBlock(NewWaterStationary);
ModLoader.registerBlock(NewMovingLava);
ModLoader.registerBlock(NewStationaryLava);
ModLoader.addName(NewWaterMoving, "New Water Moving");
ModLoader.addName(NewWaterStationary, "New Water Still");
ModLoader.addName(NewMovingLava, "New Lava Still");
ModLoader.addName(NewStationaryLava, "New Lava Moving");
//Добавляем рецепт для "Теста".
ModLoader.addRecipe(new ItemStack(NewWaterMoving, 1), new Object[]{ "##", "##", Character.valueOf('#'), Block.dirt});
ModLoader.addRecipe(new ItemStack(NewMovingLava, 1), new Object[]{ "XZ", "ZX", Character.valueOf('X'), Block.sand});
}
}
Теперь создаём BlockFluidNew.java и пишем:
Code
package net.minecraft.src;
import java.util.Random;
public abstract class BlockFluidNew extends Block
{
protected BlockFluidNew(int par1, Material par2Material)
{
super(par1, (par2Material == Material.lava ? 14 : 12) * 16 + 13, par2Material);
float var3 = 0.0F;
float var4 = 0.0F;
this.setBlockBounds(0.0F + var4, 0.0F + var3, 0.0F + var4, 1.0F + var4, 1.0F + var3, 1.0F + var4);
this.setTickRandomly(true);
}
public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
return this.blockMaterial != Material.lava;
}
public int getBlockColor()
{
return 16777215;
}
/**
* Returns a integer with hex for 0xrrggbb with this color multiplied against the blocks color. Note only called
* when first determining what to render.
*/
public int colorMultiplier(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
if (this.blockMaterial != Material.water)
{
return 16777215;
}
else
{
int var5 = 0;
int var6 = 0;
int var7 = 0;
for (int var8 = -1; var8 <= 1; ++var8)
{
for (int var9 = -1; var9 <= 1; ++var9)
{
int var10 = par1IBlockAccess.getBiomeGenForCoords(par2 + var9, par4 + var8).waterColorMultiplier;
var5 += (var10 & 16711680) >> 16;
var6 += (var10 & 65280) >> 8;
var7 += var10 & 255;
}
}
return (var5 / 9 & 255) << 16 | (var6 / 9 & 255) << 8 | var7 / 9 & 255;
}
}
/**
* Returns the percentage of the fluid block that is air, based on the given flow decay of the fluid.
*/
public static float getFluidHeightPercent(int par0)
{
if (par0 >= 8)
{
par0 = 0;
}
return (float)(par0 + 1) / 9.0F;
}
/**
* Returns the block texture based on the side being looked at. Args: side
*/
public int getBlockTextureFromSide(int par1)
{
return par1 != 0 && par1 != 1 ? this.blockIndexInTexture + 1 : this.blockIndexInTexture;
}
/**
* Returns the amount of fluid decay at the coordinates, or -1 if the block at the coordinates is not the same
* material as the fluid.
*/
protected int getFlowDecay(World par1World, int par2, int par3, int par4)
{
return par1World.getBlockMaterial(par2, par3, par4) == this.blockMaterial ? par1World.getBlockMetadata(par2, par3, par4) : -1;
}
/**
* Returns the flow decay but converts values indicating falling liquid (values >=8) to their effective source block
* value of zero.
*/
protected int getEffectiveFlowDecay(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
if (par1IBlockAccess.getBlockMaterial(par2, par3, par4) != this.blockMaterial)
{
return -1;
}
else
{
int var5 = par1IBlockAccess.getBlockMetadata(par2, par3, par4);
if (var5 >= 8)
{
var5 = 0;
}
return var5;
}
}
/**
* If this block doesn't render as an ordinary block it will return False (examples: signs, buttons, stairs, etc)
*/
public boolean renderAsNormalBlock()
{
return false;
}
/**
* 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;
}
/**
* Returns whether this block is collideable based on the arguments passed in Args: blockMetaData, unknownFlag
*/
public boolean canCollideCheck(int par1, boolean par2)
{
return par2 && par1 == 0;
}
/**
* Returns Returns true if the given side of this block type should be rendered (if it's solid or not), if the
* adjacent block is at the given coordinates. Args: blockAccess, x, y, z, side
*/
public boolean isBlockSolid(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
{
Material var6 = par1IBlockAccess.getBlockMaterial(par2, par3, par4);
return var6 == this.blockMaterial ? false : (par5 == 1 ? true : (var6 == Material.ice ? false : super.isBlockSolid(par1IBlockAccess, par2, par3, par4, par5)));
}
/**
* Returns true if the given side of this block type should be rendered, if the adjacent block is at the given
* coordinates. Args: blockAccess, x, y, z, side
*/
public boolean shouldSideBeRendered(IBlockAccess par1IBlockAccess, int par2, int par3, int par4, int par5)
{
Material var6 = par1IBlockAccess.getBlockMaterial(par2, par3, par4);
return var6 == this.blockMaterial ? false : (par5 == 1 ? true : (var6 == Material.ice ? false : super.shouldSideBeRendered(par1IBlockAccess, par2, par3, par4, par5)));
}
/**
* 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)
{
return null;
}
/**
* The type of render function that is called for this block
*/
public int getRenderType()
{
return 4;
}
/**
* Returns the ID of the items to drop on destruction.
*/
public int idDropped(int par1, Random par2Random, int par3)
{
return 0;
}
/**
* Returns the quantity of items to drop on block destruction.
*/
public int quantityDropped(Random par1Random)
{
return 0;
}
/**
* Returns a vector indicating the direction and intensity of fluid flow.
*/
private Vec3 getFlowVector(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
Vec3 var5 = Vec3.getVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D);
int var6 = this.getEffectiveFlowDecay(par1IBlockAccess, par2, par3, par4);
for (int var7 = 0; var7 < 4; ++var7)
{
int var8 = par2;
int var10 = par4;
if (var7 == 0)
{
var8 = par2 - 1;
}
if (var7 == 1)
{
var10 = par4 - 1;
}
if (var7 == 2)
{
++var8;
}
if (var7 == 3)
{
++var10;
}
int var11 = this.getEffectiveFlowDecay(par1IBlockAccess, var8, par3, var10);
int var12;
if (var11 < 0)
{
if (!par1IBlockAccess.getBlockMaterial(var8, par3, var10).blocksMovement())
{
var11 = this.getEffectiveFlowDecay(par1IBlockAccess, var8, par3 - 1, var10);
if (var11 >= 0)
{
var12 = var11 - (var6 - 8);
var5 = var5.addVector((double)((var8 - par2) * var12), (double)((par3 - par3) * var12), (double)((var10 - par4) * var12));
}
}
}
else if (var11 >= 0)
{
var12 = var11 - var6;
var5 = var5.addVector((double)((var8 - par2) * var12), (double)((par3 - par3) * var12), (double)((var10 - par4) * var12));
}
}
if (par1IBlockAccess.getBlockMetadata(par2, par3, par4) >= 8)
{
boolean var13 = false;
if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3, par4 - 1, 2))
{
var13 = true;
}
if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3, par4 + 1, 3))
{
var13 = true;
}
if (var13 || this.isBlockSolid(par1IBlockAccess, par2 - 1, par3, par4, 4))
{
var13 = true;
}
if (var13 || this.isBlockSolid(par1IBlockAccess, par2 + 1, par3, par4, 5))
{
var13 = true;
}
if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3 + 1, par4 - 1, 2))
{
var13 = true;
}
if (var13 || this.isBlockSolid(par1IBlockAccess, par2, par3 + 1, par4 + 1, 3))
{
var13 = true;
}
if (var13 || this.isBlockSolid(par1IBlockAccess, par2 - 1, par3 + 1, par4, 4))
{
var13 = true;
}
if (var13 || this.isBlockSolid(par1IBlockAccess, par2 + 1, par3 + 1, par4, 5))
{
var13 = true;
}
if (var13)
{
var5 = var5.normalize().addVector(0.0D, -6.0D, 0.0D);
}
}
var5 = var5.normalize();
return var5;
}
/**
* Can add to the passed in vector for a movement vector to be applied to the entity. Args: x, y, z, entity, vec3d
*/
public void velocityToAddToEntity(World par1World, int par2, int par3, int par4, Entity par5Entity, Vec3 par6Vec3)
{
Vec3 var7 = this.getFlowVector(par1World, par2, par3, par4);
par6Vec3.xCoord += var7.xCoord;
par6Vec3.yCoord += var7.yCoord;
par6Vec3.zCoord += var7.zCoord;
}
/**
* How many world ticks before ticking
*/
public int tickRate()
{
return this.blockMaterial == Material.water ? 5 : (this.blockMaterial == Material.lava ? 30 : 0);
}
/**
* Goes straight to getLightBrightnessForSkyBlocks for Blocks, does some fancy computing for Fluids
*/
public int getMixedBrightnessForBlock(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
int var5 = par1IBlockAccess.getLightBrightnessForSkyBlocks(par2, par3, par4, 0);
int var6 = par1IBlockAccess.getLightBrightnessForSkyBlocks(par2, par3 + 1, par4, 0);
int var7 = var5 & 255;
int var8 = var6 & 255;
int var9 = var5 >> 16 & 255;
int var10 = var6 >> 16 & 255;
return (var7 > var8 ? var7 : var8) | (var9 > var10 ? var9 : var10) << 16;
}
/**
* How bright to render this block based on the light its receiving. Args: iBlockAccess, x, y, z
*/
public float getBlockBrightness(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
float var5 = par1IBlockAccess.getLightBrightness(par2, par3, par4);
float var6 = par1IBlockAccess.getLightBrightness(par2, par3 + 1, par4);
return var5 > var6 ? var5 : var6;
}
/**
* Returns which pass should this block be rendered on. 0 for solids and 1 for alpha
*/
public int getRenderBlockPass()
{
return this.blockMaterial == Material.water ? 1 : 0;
}
/**
* A randomly called display update to be able to add particles or other items for display
*/
public void randomDisplayTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
int var6;
if (this.blockMaterial == Material.water)
{
if (par5Random.nextInt(10) == 0)
{
var6 = par1World.getBlockMetadata(par2, par3, par4);
if (var6 <= 0 || var6 >= 8)
{
par1World.spawnParticle("suspended", (double)((float)par2 + par5Random.nextFloat()), (double)((float)par3 + par5Random.nextFloat()), (double)((float)par4 + par5Random.nextFloat()), 0.0D, 0.0D, 0.0D);
}
}
for (var6 = 0; var6 < 0; ++var6)
{
int var7 = par5Random.nextInt(4);
int var8 = par2;
int var9 = par4;
if (var7 == 0)
{
var8 = par2 - 1;
}
if (var7 == 1)
{
++var8;
}
if (var7 == 2)
{
var9 = par4 - 1;
}
if (var7 == 3)
{
++var9;
}
if (par1World.getBlockMaterial(var8, par3, var9) == Material.air && (par1World.getBlockMaterial(var8, par3 - 1, var9).blocksMovement() || par1World.getBlockMaterial(var8, par3 - 1, var9).isLiquid()))
{
float var10 = 0.0625F;
double var11 = (double)((float)par2 + par5Random.nextFloat());
double var13 = (double)((float)par3 + par5Random.nextFloat());
double var15 = (double)((float)par4 + par5Random.nextFloat());
if (var7 == 0)
{
var11 = (double)((float)par2 - var10);
}
if (var7 == 1)
{
var11 = (double)((float)(par2 + 1) + var10);
}
if (var7 == 2)
{
var15 = (double)((float)par4 - var10);
}
if (var7 == 3)
{
var15 = (double)((float)(par4 + 1) + var10);
}
double var17 = 0.0D;
double var19 = 0.0D;
if (var7 == 0)
{
var17 = (double)(-var10);
}
if (var7 == 1)
{
var17 = (double)var10;
}
if (var7 == 2)
{
var19 = (double)(-var10);
}
if (var7 == 3)
{
var19 = (double)var10;
}
par1World.spawnParticle("splash", var11, var13, var15, var17, 0.0D, var19);
}
}
}
if (this.blockMaterial == Material.water && par5Random.nextInt(64) == 0)
{
var6 = par1World.getBlockMetadata(par2, par3, par4);
if (var6 > 0 && var6 < 8)
{
par1World.playSound((double)((float)par2 + 0.5F), (double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), "liquid.water", par5Random.nextFloat() * 0.25F + 0.75F, par5Random.nextFloat() * 1.0F + 0.5F);
}
}
double var21;
double var23;
double var22;
if (this.blockMaterial == Material.lava && par1World.getBlockMaterial(par2, par3 + 1, par4) == Material.air && !par1World.isBlockOpaqueCube(par2, par3 + 1, par4))
{
if (par5Random.nextInt(100) == 0)
{
var21 = (double)((float)par2 + par5Random.nextFloat());
var22 = (double)par3 + this.maxY;
var23 = (double)((float)par4 + par5Random.nextFloat());
par1World.spawnParticle("lava", var21, var22, var23, 0.0D, 0.0D, 0.0D);
par1World.playSound(var21, var22, var23, "liquid.lavapop", 0.2F + par5Random.nextFloat() * 0.2F, 0.9F + par5Random.nextFloat() * 0.15F);
}
if (par5Random.nextInt(200) == 0)
{
par1World.playSound((double)par2, (double)par3, (double)par4, "liquid.lava", 0.2F + par5Random.nextFloat() * 0.2F, 0.9F + par5Random.nextFloat() * 0.15F);
}
}
if (par5Random.nextInt(10) == 0 && par1World.doesBlockHaveSolidTopSurface(par2, par3 - 1, par4) && !par1World.getBlockMaterial(par2, par3 - 2, par4).blocksMovement())
{
var21 = (double)((float)par2 + par5Random.nextFloat());
var22 = (double)par3 - 1.05D;
var23 = (double)((float)par4 + par5Random.nextFloat());
if (this.blockMaterial == Material.water)
{
par1World.spawnParticle("dripWater", var21, var22, var23, 0.0D, 0.0D, 0.0D);
}
else
{
par1World.spawnParticle("dripLava", var21, var22, var23, 0.0D, 0.0D, 0.0D);
}
}
}
/**
* the sin and cos of this number determine the surface gradient of the flowing block.
*/
public static double getFlowDirection(IBlockAccess par0IBlockAccess, int par1, int par2, int par3, Material par4Material)
{
Vec3 var5 = null;
if (par4Material == Material.water)
{
var5 = ((BlockFluidNew)mod_new_fluid.NewWaterMoving).getFlowVector(par0IBlockAccess, par1, par2, par3);
}
if (par4Material == Material.lava)
{
var5 = ((BlockFluidNew)mod_new_fluid.NewMovingLava).getFlowVector(par0IBlockAccess, par1, par2, par3);
}
return var5.xCoord == 0.0D && var5.zCoord == 0.0D ? -1000.0D : Math.atan2(var5.zCoord, var5.xCoord) - (Math.PI / 2D);
}
/**
* 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)
{
this.checkForHarden(par1World, par2, par3, par4);
}
/**
* 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)
{
this.checkForHarden(par1World, par2, par3, par4);
}
/**
* Forces lava to check to see if it is colliding with water, and then decide what it should harden to.
*/
private void checkForHarden(World par1World, int par2, int par3, int par4)
{
if (par1World.getBlockId(par2, par3, par4) == this.blockID)
{
if (this.blockMaterial == Material.lava)
{
boolean var5 = false;
if (var5 || par1World.getBlockMaterial(par2, par3, par4 - 1) == Material.water)
{
var5 = true;
}
if (var5 || par1World.getBlockMaterial(par2, par3, par4 + 1) == Material.water)
{
var5 = true;
}
if (var5 || par1World.getBlockMaterial(par2 - 1, par3, par4) == Material.water)
{
var5 = true;
}
if (var5 || par1World.getBlockMaterial(par2 + 1, par3, par4) == Material.water)
{
var5 = true;
}
if (var5 || par1World.getBlockMaterial(par2, par3 + 1, par4) == Material.water)
{
var5 = true;
}
if (var5)
{
int var6 = par1World.getBlockMetadata(par2, par3, par4);
if (var6 == 0)
{ //Что получиться если влить нашы жидкости стоклновении жидкостей (лава в воду, вода в лаву). Для своего блока пишем mod_xxx.newblockA,blockID.
par1World.setBlockWithNotify(par2, par3, par4, Block.obsidian.blockID);
}
else if (var6 <= 4)
{ //Что будет если потоки вашей лавы и воды столкнуться, для своего блока пишем mod_xxx.newblockB,blockID.
par1World.setBlockWithNotify(par2, par3, par4, Block.cobblestone.blockID);
}
this.triggerLavaMixEffects(par1World, par2, par3, par4);
}
}
}
}
/**
* Creates fizzing sound and smoke. Used when lava flows over block or mixes with water.
*/
protected void triggerLavaMixEffects(World par1World, int par2, int par3, int par4)
{
par1World.playSoundEffect((double)((float)par2 + 0.5F), (double)((float)par3 + 0.5F), (double)((float)par4 + 0.5F), "random.fizz", 0.5F, 2.6F + (par1World.rand.nextFloat() - par1World.rand.nextFloat()) * 0.8F);
for (int var5 = 0; var5 < 8; ++var5)
{
par1World.spawnParticle("largesmoke", (double)par2 + Math.random(), (double)par3 + 1.2D, (double)par4 + Math.random(), 0.0D, 0.0D, 0.0D);
}
}
}
Потом делаем блок BlockNewFlowingFluid.java (текущий блок), и пишем туда:
Code
package net.minecraft.src;
import java.util.Random;
// тут пишем какой родитель блока, и вписываем свой
public class BlockNewFlowingFluid extends BlockFluidNew
{
/**
* Number of horizontally adjacent liquid source blocks. Diagonal doesn't count. Only source blocks of the same
* liquid as the block using the field are counted.
*/
int numAdjacentSources;
boolean isOptimalFlowDirection[];
int flowCost[];
protected BlockNewFlowingFluid(int par1, Material par2Material)
{
super(par1, par2Material);
numAdjacentSources = 0;
isOptimalFlowDirection = new boolean[4];
flowCost = new int[4];
}
/**
* Updates the flow for the BlockFlowing object.
*/
private void updateFlow(World par1World, int par2, int par3, int par4)
{
int i = par1World.getBlockMetadata(par2, par3, par4);
par1World.setBlockAndMetadata(par2, par3, par4, blockID + 1, i);
par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4);
par1World.markBlockNeedsUpdate(par2, par3, par4);
}
public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
return blockMaterial != Material.lava;
}
/**
* Ticks the block if it's been scheduled
*/
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
int var6 = this.getFlowDecay(par1World, par2, par3, par4);
byte var7 = 1;
if (this.blockMaterial == Material.lava && !par1World.provider.isHellWorld)
{
var7 = 2;
}
boolean var8 = true;
int var10;
if (var6 > 0)
{
byte var9 = -100;
this.numAdjacentSources = 0;
int var12 = this.getSmallestFlowDecay(par1World, par2 - 1, par3, par4, var9);
var12 = this.getSmallestFlowDecay(par1World, par2 + 1, par3, par4, var12);
var12 = this.getSmallestFlowDecay(par1World, par2, par3, par4 - 1, var12);
var12 = this.getSmallestFlowDecay(par1World, par2, par3, par4 + 1, var12);
var10 = var12 + var7;
if (var10 >= 8 || var12 < 0)
{
var10 = -1;
}
if (this.getFlowDecay(par1World, par2, par3 + 1, par4) >= 0)
{
int var11 = this.getFlowDecay(par1World, par2, par3 + 1, par4);
if (var11 >= 8)
{
var10 = var11;
}
else
{
var10 = var11 + 8;
}
}
if (this.numAdjacentSources >= 2 && this.blockMaterial == Material.water)
{
if (par1World.getBlockMaterial(par2, par3 - 1, par4).isSolid())
{
var10 = 0;
}
else if (par1World.getBlockMaterial(par2, par3 - 1, par4) == this.blockMaterial && par1World.getBlockMetadata(par2, par3, par4) == 0)
{
var10 = 0;
}
}
if (this.blockMaterial == Material.lava && var6 < 8 && var10 < 8 && var10 > var6 && par5Random.nextInt(4) != 0)
{
var10 = var6;
var8 = false;
}
if (var10 == var6)
{
if (var8)
{
this.updateFlow(par1World, par2, par3, par4);
}
}
else
{
var6 = var10;
if (var10 < 0)
{
par1World.setBlockWithNotify(par2, par3, par4, 0);
}
else
{
par1World.setBlockMetadataWithNotify(par2, par3, par4, var10);
par1World.scheduleBlockUpdate(par2, par3, par4, this.blockID, this.tickRate());
par1World.notifyBlocksOfNeighborChange(par2, par3, par4, this.blockID);
}
}
}
else
{
this.updateFlow(par1World, par2, par3, par4);
}
if (this.liquidCanDisplaceBlock(par1World, par2, par3 - 1, par4))
{
if (this.blockMaterial == Material.lava && par1World.getBlockMaterial(par2, par3 - 1, par4) == Material.water)
{
par1World.setBlockWithNotify(par2, par3 - 1, par4, Block.stone.blockID);
this.triggerLavaMixEffects(par1World, par2, par3 - 1, par4);
return;
}
if (var6 >= 8)
{
this.flowIntoBlock(par1World, par2, par3 - 1, par4, var6);
}
else
{
this.flowIntoBlock(par1World, par2, par3 - 1, par4, var6 + 8);
}
}
else if (var6 >= 0 && (var6 == 0 || this.blockBlocksFlow(par1World, par2, par3 - 1, par4)))
{
boolean[] var13 = this.getOptimalFlowDirections(par1World, par2, par3, par4);
var10 = var6 + var7;
if (var6 >= 8)
{
var10 = 1;
}
if (var10 >= 8)
{
return;
}
if (var13[0])
{
this.flowIntoBlock(par1World, par2 - 1, par3, par4, var10);
}
if (var13[1])
{
this.flowIntoBlock(par1World, par2 + 1, par3, par4, var10);
}
if (var13[2])
{
this.flowIntoBlock(par1World, par2, par3, par4 - 1, var10);
}
if (var13[3])
{
this.flowIntoBlock(par1World, par2, par3, par4 + 1, var10);
}
}
}
/**
* flowIntoBlock(World world, int x, int y, int z, int newFlowDecay) - Flows into the block at the coordinates and
* changes the block type to the liquid.
*/
private void flowIntoBlock(World par1World, int par2, int par3, int par4, int par5)
{
if (liquidCanDisplaceBlock(par1World, par2, par3, par4))
{
int i = par1World.getBlockId(par2, par3, par4);
if (i > 0)
{
if (blockMaterial == Material.lava)
{
triggerLavaMixEffects(par1World, par2, par3, par4);
}
else
{
Block.blocksList[i].dropBlockAsItem(par1World, par2, par3, par4, par1World.getBlockMetadata(par2, par3, par4), 0);
}
}
par1World.setBlockAndMetadataWithNotify(par2, par3, par4, blockID, par5);
}
}
/**
* calculateFlowCost(World world, int x, int y, int z, int accumulatedCost, int previousDirectionOfFlow) - Used to
* determine the path of least resistance, this method returns the lowest possible flow cost for the direction of
* flow indicated. Each necessary horizontal flow adds to the flow cost.
*/
private int calculateFlowCost(World par1World, int par2, int par3, int par4, int par5, int par6)
{
int i = 1000;
for (int j = 0; j < 4; j++)
{
if (j == 0 && par6 == 1 || j == 1 && par6 == 0 || j == 2 && par6 == 3 || j == 3 && par6 == 2)
{
continue;
}
int k = par2;
int l = par3;
int i1 = par4;
if (j == 0)
{
k--;
}
if (j == 1)
{
k++;
}
if (j == 2)
{
i1--;
}
if (j == 3)
{
i1++;
}
if (blockBlocksFlow(par1World, k, l, i1) || par1World.getBlockMaterial(k, l, i1) == blockMaterial && par1World.getBlockMetadata(k, l, i1) == 0)
{
continue;
}
if (!blockBlocksFlow(par1World, k, l - 1, i1))
{
return par5;
}
if (par5 >= 4)
{
continue;
}
int j1 = calculateFlowCost(par1World, k, l, i1, par5 + 1, j);
if (j1 < i)
{
i = j1;
}
}
return i;
}
/**
* Returns a boolean array indicating which flow directions are optimal based on each direction's calculated flow
* cost. Each array index corresponds to one of the four cardinal directions. A value of true indicates the
* direction is optimal.
*/
private boolean[] getOptimalFlowDirections(World par1World, int par2, int par3, int par4)
{
for (int i = 0; i < 4; i++)
{
flowCost[i] = 1000;
int k = par2;
int j1 = par3;
int k1 = par4;
if (i == 0)
{
k--;
}
if (i == 1)
{
k++;
}
if (i == 2)
{
k1--;
}
if (i == 3)
{
k1++;
}
if (blockBlocksFlow(par1World, k, j1, k1) || par1World.getBlockMaterial(k, j1, k1) == blockMaterial && par1World.getBlockMetadata(k, j1, k1) == 0)
{
continue;
}
if (!blockBlocksFlow(par1World, k, j1 - 1, k1))
{
flowCost[i] = 0;
}
else
{
flowCost[i] = calculateFlowCost(par1World, k, j1, k1, 1, i);
}
}
int j = flowCost[0];
for (int l = 1; l < 4; l++)
{
if (flowCost[l] < j)
{
j = flowCost[l];
}
}
for (int i1 = 0; i1 < 4; i1++)
{
isOptimalFlowDirection[i1] = flowCost[i1] == j;
}
return isOptimalFlowDirection;
}
/**
* Returns true if block at coords blocks fluids
*/
//Думаю тут понятно.
private boolean blockBlocksFlow(World par1World, int par2, int par3, int par4)
{
int i = par1World.getBlockId(par2, par3, par4);
if (i == Block.doorWood.blockID || i == Block.doorSteel.blockID || i == Block.signPost.blockID || i == Block.ladder.blockID || i == Block.reed.blockID)
{
return true;
}
if (i == 0)
{
return false;
}
Material material = Block.blocksList[i].blockMaterial;
if (material == Material.portal)
{
return true;
}
return material.blocksMovement();
}
/**
* getSmallestFlowDecay(World world, intx, int y, int z, int currentSmallestFlowDecay) - Looks up the flow decay at
* the coordinates given and returns the smaller of this value or the provided currentSmallestFlowDecay. If one
* value is valid and the other isn't, the valid value will be returned. Valid values are >= 0. Flow decay is the
* amount that a liquid has dissipated. 0 indicates a source block.
*/
protected int getSmallestFlowDecay(World par1World, int par2, int par3, int par4, int par5)
{
int i = getFlowDecay(par1World, par2, par3, par4);
if (i < 0)
{
return par5;
}
if (i == 0)
{
numAdjacentSources++;
}
if (i >= 8)
{
i = 0;
}
return par5 >= 0 && i >= par5 ? par5 : i;
}
/**
* Returns true if the block at the coordinates can be displaced by the liquid.
*/
private boolean liquidCanDisplaceBlock(World par1World, int par2, int par3, int par4)
{
Material material = par1World.getBlockMaterial(par2, par3, par4);
if (material == blockMaterial)
{
return false;
}
if (material == Material.lava)
{
return false;
}
else
{
return !blockBlocksFlow(par1World, par2, par3, par4);
}
}
/**
* 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)
{
super.onBlockAdded(par1World, par2, par3, par4);
if (par1World.getBlockId(par2, par3, par4) == blockID)
{
par1World.scheduleBlockUpdate(par2, par3, par4, blockID, tickRate());
}
}
}
Теперь создаём блок BlockNewStationaryFluid.java (не текущий блок), и пишем туда:
Code
package net.minecraft.src;
import java.util.Random;
//тут тоже пишем наш родитель.
public class BlockNewStationaryFluid extends BlockFluidNew
{
protected BlockNewStationaryFluid(int par1, Material par2Material)
{
super(par1, par2Material);
setTickRandomly(false);
if (par2Material == Material.lava)
{
setTickRandomly(true);
}
}
public boolean getBlocksMovement(IBlockAccess par1IBlockAccess, int par2, int par3, int par4)
{
return blockMaterial != Material.lava;
}
/**
* 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)
{
super.onNeighborBlockChange(par1World, par2, par3, par4, par5);
if (par1World.getBlockId(par2, par3, par4) == blockID)
{
setNotStationary(par1World, par2, par3, par4);
}
}
/**
* Changes the block ID to that of an updating fluid.
*/
private void setNotStationary(World par1World, int par2, int par3, int par4)
{
int i = par1World.getBlockMetadata(par2, par3, par4);
par1World.editingBlocks = true;
par1World.setBlockAndMetadata(par2, par3, par4, blockID - 1, i);
par1World.markBlocksDirty(par2, par3, par4, par2, par3, par4);
par1World.scheduleBlockUpdate(par2, par3, par4, blockID - 1, tickRate());
par1World.editingBlocks = false;
}
/**
* Ticks the block if it's been scheduled
*/
public void updateTick(World par1World, int par2, int par3, int par4, Random par5Random)
{
if (blockMaterial == Material.lava)
{
int i = par5Random.nextInt(3);
for (int j = 0; j < i; j++)
{
par2 += par5Random.nextInt(3) - 1;
par3++;
par4 += par5Random.nextInt(3) - 1;
int l = par1World.getBlockId(par2, par3, par4);
if (l == 0)
{
if (isFlammable(par1World, par2 - 1, par3, par4) || isFlammable(par1World, par2 + 1, par3, par4) || isFlammable(par1World, par2, par3, par4 - 1) || isFlammable(par1World, par2, par3, par4 + 1) || isFlammable(par1World, par2, par3 - 1, par4) || isFlammable(par1World, par2, par3 + 1, par4))
{
par1World.setBlockWithNotify(par2, par3, par4, Block.fire.blockID);
return;
}
continue;
}
if (Block.blocksList[l].blockMaterial.blocksMovement())
{
return;
}
}
if (i == 0)
{
int k = par2;
int i1 = par4;
for (int j1 = 0; j1 < 3; j1++)
{
par2 = (k + par5Random.nextInt(3)) - 1;
par4 = (i1 + par5Random.nextInt(3)) - 1;
if (par1World.isAirBlock(par2, par3 + 1, par4) && isFlammable(par1World, par2, par3, par4))
{
par1World.setBlockWithNotify(par2, par3 + 1, par4, Block.fire.blockID);
}
}
}
}
}
/**
* Checks to see if the block is flammable.
*/
private boolean isFlammable(World par1World, int par2, int par3, int par4)
{
return par1World.getBlockMaterial(par2, par3, par4).getCanBurn();
}
}
Теперь заходим в BlockFluidNew.java и находим:
Code
if (var6 == 0)
{ //Что получиться если влить нашы жидкости стоклновении жидкостей (лава в воду, вода в лаву). Для своего блока пишем mod_xxx.newblockA,blockID.
par1World.setBlockWithNotify(par2, par3, par4, Block.obsidian.blockID);
}
else if (var6 <= 4)
{ //Что будет если потоки вашей лавы и воды столкнуться, для своего блока пишем mod_xxx.newblockB,blockID.
par1World.setBlockWithNotify(par2, par3, par4, Block.cobblestone.blockID);
}
Как изменить цвет (сказал as110z)
Ищем строку:
Code
package net.minecraft.src;
import java.util.Random;
public class BlockNewFlowingFluid extends BlockFluid
{
int numAdjacentSources;
boolean isOptimalFlowDirection[];
int flowCost[];
protected BlockNewFlowingFluid(int par1, Material par2Material)
{
super(par1, par2Material);
numAdjacentSources = 0;
isOptimalFlowDirection = new boolean[4];
flowCost = new int[4];
}
И заменяем на:
Code
package net.minecraft.src;
import java.util.Random;
public class BlockNewFlowingFluid extends BlockFluid
{
int numAdjacentSources;
boolean isOptimalFlowDirection[];
int flowCost[];
protected BlockNewFlowingFluid(int par1, Material par2Material)
{
super(par1, par2Material);
numAdjacentSources = 0;
isOptimalFlowDirection = new boolean[4];
flowCost = new int[4];
}
public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k)
{
return 0x99FF33;
}
Потом заходим в BlockNewStationaryFluidа
Опять же ищем строчку:
Code
package net.minecraft.src;
import java.util.Random;
public class BlockNewStationaryFluid extends BlockFluid
{
protected BlockNewStationaryFluid(int par1, Material par2Material)
{
super(par1, par2Material);
setTickRandomly(false);
if (par2Material == Material.lava)
{
setTickRandomly(true);
}
}
И заменяем её на:
Code
package net.minecraft.src;
import java.util.Random;
public class BlockNewStationaryFluid extends BlockFluid
{
protected BlockNewStationaryFluid(int i, Material material)
{
super(i, material);
setTickRandomly(false);
if (material == Material.lava)
{
setTickRandomly(true);
}
}
public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k)
{
return 0x99FF33;
}
Ну вот и всё теперь у вас будет зелёная жидкость чтобы поменять цвет надо Сменить в обоих файлах ,