提供: Minecraft Modding Wiki
移動先: 案内検索

この記事は"ModLoader"を前提MODとしています。

1.原木・葉・苗木ブロックの追加
2.成長段階分のテクスチャデータの定義
3.成長処理判定
4.ドロップさせるアイテム設定
5.チャンクデータ生成時に追加した木を生成させる
6.他色々
概要はこんな感じです。
非常にやることが多いです。

ソース解説[編集]

mod_HogeTreeクラスを作成[編集]

基盤を作ります。

package net.minecraft.src;

import java.util.Random;

public class mod_HogeTree extends BaseMod
{
	public static final Block hogeLeaves;
	public static final Block hogeWood;
	public static final Block hogeSapling;
	
	public mod_HogeTree()
	{
	}
	
	public String getVersion()
	{
		return "1.1";
	}
	
	public void load()
	{
		/*
		 * 毎度おなじみ、Block追加
		 */
		ModLoader.AddName(hogeLeaves, "Hoge Leaves");
		ModLoader.AddName(hogeWood, "Hoge Wood");
		ModLoader.AddName(hogeSapling, "Hoge Sapling");
		ModLoader.RegisterBlock(hogeLeaves);
		ModLoader.RegisterBlock(hogeWood);
		ModLoader.RegisterBlock(hogeSapling);
		/*
		 * ModLoader.AddSmeltingで原木を燃やしたら木炭ができるように設定
		 */
		ModLoader.AddSmelting(hogeWood.blockID, new ItemStack(Item.coal, 1, 1));
	}

	/*
	 * チャンクデータの生成呼び出し
	 */
	public void GenerateSurface(World world, Random random, int i, int j)
	{
		BiomeGenBase biomegenbase = world.getWorldChunkManager().getBiomeGenAt(i, j);
		WorldGenHogeTrees worldgenhogetrees = new WorldGenHogeTrees(true);
		if((biomegenbase instanceof BiomeGenForest) || (biomegenbase instanceof BiomeGenForest))
		{
			int k = i + random.nextInt(16) + 8;
			int l = j + random.nextInt(16) + 8;
			int i1 = world.getHeightValue(k, l);
			worldgenhogetrees.setScale(1.0D, 1.0D, 1.0D);
			worldgenhogetrees.generate(world, random, k, i1, l);
		}
	}
	
	static
	{
		/*
		 * ブロックの定義
		 * setLightOpacity(int)で透過率を設定(のはず)
		 */
		hogeLeaves = new BlockHogeLeaves(100, ModLoader.addOverride("/terrain.png", "/block/hogeLeaves.png"));
		hogeLeaves.setHardness(0.2F).setLightOpacity(1).setStepSound(Block.soundGrassFootstep).setBlockName("hogeLeaves").disableStats();
		
		hogeWood = new BlockHogeWood(101, ModLoader.addOverride("/terrain.png", "/block/hogeWood.png"));
		hogeWood.setHardness(2.0F).setStepSound(Block.soundWoodFootstep).setBlockName("hogeWood");
		
		hogeSapling = new BlockHogeSapling(102, ModLoader.addOverride("/terrain.png", "/block/hogeSapling.png"));
		hogeSapling.setHardness(0.2F).setLightOpacity(1).setBlockName("hogeSapling").disableStats();
	}
}

BlockHogeLeavesクラスを作成[編集]

基本はBlockLeavesから拝借 原木なかったら消失とか、りんごを抽選ドロップとか色々やる必要があります。

package net.minecraft.src;

import java.util.ArrayList;
import java.util.Random;

import net.minecraft.src.forge.IShearable;

public class BlockHogeLeaves extends BlockLeavesBase implements IShearable
{
    private int baseIndexInPNG;
    int adjacentTreeBlocks[];

    protected BlockHogeLeaves(int i, int j)
    {
        super( i, j, Material.leaves, false);
        this.baseIndexInPNG = j;
        this.setTickRandomly(true);
    }

    public int getBlockColor()
    {
        double d = 0.5D;
        double d1 = 1.0D;
        return ColorizerFoliage.getFoliageColor(d, d1);
    }

    public int getRenderColor(int i)
    {
        if ((i & 1) == 1)
        {
            return ColorizerFoliage.getFoliageColorPine();
        }
        if ((i & 2) == 2)
        {
            return ColorizerFoliage.getFoliageColorBirch();
        }
        else
        {
            return ColorizerFoliage.getFoliageColorBasic();
        }
    }

    public int colorMultiplier(IBlockAccess iblockaccess, int i, int j, int k)
    {
        int l = iblockaccess.getBlockMetadata(i, j, k);
        if ((l & 1) == 1)
        {
            return ColorizerFoliage.getFoliageColorPine();
        }
        if ((l & 2) == 2)
        {
            return ColorizerFoliage.getFoliageColorBirch();
        }
        int i1 = 0;
        int j1 = 0;
        int k1 = 0;
        for (int l1 = -1; l1 <= 1; l1++)
        {
            for (int i2 = -1; i2 <= 1; i2++)
            {
                int j2 = iblockaccess.func_48454_a(i + i2, k + l1).func_48412_k();
                i1 += (j2 & 0xff0000) >> 16;
                j1 += (j2 & 0xff00) >> 8;
                k1 += j2 & 0xff;
            }
        }

        return (i1 / 9 & 0xff) << 16 | (j1 / 9 & 0xff) << 8 | k1 / 9 & 0xff;
    }

    public void onBlockRemoval(World world, int i, int j, int k)
    {
        int l = 1;
        int i1 = l + 1;
        if (world.checkChunksExist(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1))
        {
            for (int j1 = -l; j1 <= l; j1++)
            {
                for (int k1 = -l; k1 <= l; k1++)
                {
                    for (int l1 = -l; l1 <= l; l1++)
                    {
                        int i2 = world.getBlockId(i + j1, j + k1, k + l1);
                        if (i2 == mod_HogeTree.hogeLeaves.blockID)
                        {
                            int j2 = world.getBlockMetadata(i + j1, j + k1, k + l1);
                            world.setBlockMetadata(i + j1, j + k1, k + l1, j2 | 8);
                        }
                    }
                }
            }
        }
    }

    /*
     * 成長時にどのようにBlockを配置させるかを判定
     * 通常の木をそのままパクった状態がこれ。
     * 
     */
    public void updateTick(World world, int i, int j, int k, Random random)
    {
        if (world.isRemote)
        {
            return;
        }
        int l = world.getBlockMetadata(i, j, k);
        if ((l & 8) != 0 && (l & 4) == 0)
        {
            byte byte0 = 4;
            int i1 = byte0 + 1;
            byte byte1 = 32;
            int j1 = byte1 * byte1;
            int k1 = byte1 / 2;
            if (adjacentTreeBlocks == null)
            {
                adjacentTreeBlocks = new int[byte1 * byte1 * byte1];
            }
            if (world.checkChunksExist(i - i1, j - i1, k - i1, i + i1, j + i1, k + i1))
            {
                for (int l1 = -byte0; l1 <= byte0; l1++)
                {
                    for (int k2 = -byte0; k2 <= byte0; k2++)
                    {
                        for (int i3 = -byte0; i3 <= byte0; i3++)
                        {
                            int k3 = world.getBlockId(i + l1, j + k2, k + i3);
                            if (k3 == mod_HogeTree.hogeWood.blockID)
                            {
                                adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = 0;
                                continue;
                            }
                            if (k3 == mod_HogeTree.hogeLeaves.blockID)
                            {
                                adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = -2;
                            }
                            else
                            {
                                adjacentTreeBlocks[(l1 + k1) * j1 + (k2 + k1) * byte1 + (i3 + k1)] = -1;
                            }
                        }
                    }
                }

                for (int i2 = 1; i2 <= 4; i2++)
                {
                    for (int l2 = -byte0; l2 <= byte0; l2++)
                    {
                        for (int j3 = -byte0; j3 <= byte0; j3++)
                        {
                            for (int l3 = -byte0; l3 <= byte0; l3++)
                            {
                                if (adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] != i2 - 1)
                                {
                                    continue;
                                }
                                if (adjacentTreeBlocks[((l2 + k1) - 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] == -2)
                                {
                                    adjacentTreeBlocks[((l2 + k1) - 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] = i2;
                                }
                                if (adjacentTreeBlocks[(l2 + k1 + 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] == -2)
                                {
                                    adjacentTreeBlocks[(l2 + k1 + 1) * j1 + (j3 + k1) * byte1 + (l3 + k1)] = i2;
                                }
                                if (adjacentTreeBlocks[(l2 + k1) * j1 + ((j3 + k1) - 1) * byte1 + (l3 + k1)] == -2)
                                {
                                    adjacentTreeBlocks[(l2 + k1) * j1 + ((j3 + k1) - 1) * byte1 + (l3 + k1)] = i2;
                                }
                                if (adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1 + 1) * byte1 + (l3 + k1)] == -2)
                                {
                                    adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1 + 1) * byte1 + (l3 + k1)] = i2;
                                }
                                if (adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + ((l3 + k1) - 1)] == -2)
                                {
                                    adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + ((l3 + k1) - 1)] = i2;
                                }
                                if (adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1 + 1)] == -2)
                                {
                                    adjacentTreeBlocks[(l2 + k1) * j1 + (j3 + k1) * byte1 + (l3 + k1 + 1)] = i2;
                                }
                            }
                        }
                    }
                }
            }
            int j2 = adjacentTreeBlocks[k1 * j1 + k1 * byte1 + k1];
            if (j2 >= 0)
            {
                world.setBlockMetadata(i, j, k, l & -9);
            }
            else
            {
                removeLeaves(world, i, j, k);
            }
        }
    }

    /*
     * 近くに原木がなかったら葉が消える処理
     */    
    private void removeLeaves(World world, int i, int j, int k)
    {
        dropBlockAsItem(world, i, j, k, world.getBlockMetadata(i, j, k), 0);
        world.setBlockWithNotify(i, j, k, 0);
    }

    /*
     * 葉を破壊した際、ランダムでアイテムがでるように設定
     */
    public int quantityDropped(Random random)
    {
        return random.nextInt(20) != 0 ? 0 : 1;
    }

    /*
     * 葉を破壊したら苗木がでるように設定
     */
    public int idDropped(int i, Random random, int j)
    {
        return mod_HogeTree.hogeSapling.blockID;
    }

    /*
     * 葉を破壊時、追加でりんごがでるように抽選
     */
    public void dropBlockAsItemWithChance(World world, int i, int j, int k, int l, float f, int i1)
    {
        super.dropBlockAsItemWithChance(world, i, j, k, l, f, i1);
        if (!world.isRemote && (l & 3) == 0 && world.rand.nextInt(200) == 0)
        {
            dropBlockAsItem_do(world, i, j, k, new ItemStack(Item.appleRed, 1, 0));
        }
    }

    public void harvestBlock(World world, EntityPlayer entityplayer, int i, int j, int k, int l)
    {
        super.harvestBlock(world, entityplayer, i, j, k, l);
    }

    protected int damageDropped(int i)
    {
        return i & 3;
    }

    public boolean isOpaqueCube()
    {
        return !graphicsLevel;
    }

    public int getBlockTextureFromSideAndMetadata(int i, int j)
    {
        if ((j & 3) == 1)
        {
            return blockIndexInTexture + 80;
        }
        else
        {
            return blockIndexInTexture;
        }
    }

    public void setGraphicsLevel(boolean flag)
    {
        graphicsLevel = flag;
        blockIndexInTexture = baseIndexInPNG + (flag ? 0 : 1);
    }

    public void onEntityWalking(World world, int i, int j, int k, Entity entity)
    {
        super.onEntityWalking(world, i, j, k, entity);
    }

    @Override
    public boolean isShearable(ItemStack item, World world, int X, int Y, int Z) 
    {
        return true;
    }

    /*
     * 鋏を使った場合とエンチャント(Fortune)を使った場合の判定
     */
    @Override
    public ArrayList<ItemStack> onSheared(ItemStack item, World world, int X, int Y, int Z, int fortune) 
    {
        ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
        ret.add(new ItemStack(mod_HogeTree.hogeLeaves.blockID, 1, world.getBlockMetadata(X, Y, Z) & 3));
        return ret;
    }
}

BlockHogeWoodクラスを作成[編集]

原木を追加します。
あんまりここでやることはない

package net.minecraft.src;

import java.util.Random;

public class BlockHogeWood extends Block
{
	private int baseIndexInPNG;
	
	protected BlockHogeWood(int i, int j)
	{
		super(i, j, Material.wood);
		baseIndexInPNG = j;
	}
	
	public int quantityDropped(Random random)
	{
		return 1;
	}
	
	public int idDropped(int i, Random random)
	{
		return mod_HogeTree.hogeWood.blockID;
	}
	
	public int getBlocktextureFromSide(int i)
	{
		if(i == 1 || i == 0)
		{
			return 2;
		}
		else
		{
			return baseIndexInPNG;
		}
	}
}

BlockHogeSaplingクラスを作成[編集]

苗木追加します。 種子と同じく成長判定が必要です。

package net.minecraft.src;

import java.util.Random;

public class BlockHogeSapling extends BlockFlower
{
    protected BlockHogeSapling(int i, int j)
    {
        super(i, j);
        float f = 0.4F;
        setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f * 2.0F, 0.5F + f);
    }

    /*
     * 成長するための条件設定
     * 種子と同じくgetBlockLightValueが9以上で成長するように設定
     */
    public void updateTick(World world, int i, int j, int k, Random random)
    {
        if (world.isRemote)
        {
            return;
        }
        super.updateTick(world, i, j, k, random);
        if (world.getBlockLightValue(i, j + 1, k) >= 9 && random.nextInt(7) == 0)
        {
            int l = world.getBlockMetadata(i, j, k);
            if ((l & 8) == 0)
            {
                world.setBlockMetadataWithNotify(i, j, k, l | 8);
            }
            else
            {
                growTree(world, i, j, k, random);
            }
        }
    }

    /*
     * 成長時のテクスチャ判定
     */
    public int getBlockTextureFromSideAndMetadata(int i, int j)
    {
        j &= 3;
        if (j == 1)
        {
            return 63;
        }
        if (j == 2)
        {
            return 79;
        }
        else
        {
            return super.getBlockTextureFromSideAndMetadata(i, j);
        }
    }

    public void growTree(World world, int i, int j, int k, Random random)
    {
        int l = world.getBlockMetadata(i, j, k) & 3;
        world.setBlock(i, j, k, 0);
        Object obj = null;
        if (l == 1)
        {
            obj = new WorldGenTaiga2(true);
        }
        else if (l == 2)
        {
            obj = new WorldGenForest(true);
        }
        else
        {
            obj = new WorldGenHogeTrees(true);
            if (random.nextInt(10) == 0)
            {
                obj = new WorldGenBigTree(true);
            }
        }
        if (!((WorldGenerator) (obj)).generate(world, random, i, j, k))
        {
            world.setBlockAndMetadata(i, j, k, blockID, l);
        }
    }

    /*
     * 苗木破壊時のドロップアイテムの判定
     */
    protected int damageDropped(int i)
    {
        return i & 3;
    }
}

WorldGenHogeTreesクラスを作成[編集]

チャンクデータ生成時に読み込み、木を追加していきます。 WorldGenTreesクラスを基本にしています。

package net.minecraft.src;

import java.util.Random;

public class WorldGenHogeTrees extends WorldGenerator
{
    public WorldGenHogeTrees(boolean flag)
    {
        super(flag);
    }

    /*
     * チャンクデータ生成時の判定
     */
    public boolean generate(World world, Random random, int i, int j, int k)
    {
        int l = random.nextInt(3) + 4;
        boolean flag = true;
        if (j < 1 || j + l + 1 > world.worldHeight)
        {
            return false;
        }
        for (int i1 = j; i1 <= j + 1 + l; i1++)
        {
            byte byte0 = 1;
            if (i1 == j)
            {
                byte0 = 0;
            }
            if (i1 >= (j + 1 + l) - 2)
            {
                byte0 = 2;
            }
            for (int i2 = i - byte0; i2 <= i + byte0 && flag; i2++)
            {
                for (int l2 = k - byte0; l2 <= k + byte0 && flag; l2++)
                {
                    if (i1 >= 0 && i1 < world.worldHeight)
                    {
                        int j3 = world.getBlockId(i2, i1, l2);
                        if (j3 != 0 && j3 != mod_HogeTree.hogeLeaves.blockID)
                        {
                            flag = false;
                        }
                    }
                    else
                    {
                        flag = false;
                    }
                }
            }
        }

        if (!flag)
        {
            return false;
        }
        int j1 = world.getBlockId(i, j - 1, k);
        if (j1 != Block.grass.blockID && j1 != Block.dirt.blockID || j >= world.worldHeight - l - 1)
        {
            return false;
        }
        world.setBlock(i, j - 1, k, Block.dirt.blockID);
        for (int k1 = (j - 3) + l; k1 <= j + l; k1++)
        {
            int j2 = k1 - (j + l);
            int i3 = 1 - j2 / 2;
            for (int k3 = i - i3; k3 <= i + i3; k3++)
            {
                int l3 = k3 - i;
                for (int i4 = k - i3; i4 <= k + i3; i4++)
                {
                    int j4 = i4 - k;
                    if ((Math.abs(l3) != i3 || Math.abs(j4) != i3 || random.nextInt(2) != 0 && j2 != 0) && !Block.opaqueCubeLookup[world.getBlockId(k3, k1, i4)])
                    {
                        setBlockAndMetadata(world, k3, k1, i4, mod_HogeTree.hogeLeaves.blockID, 0);
                    }
                }
            }
        }

        for (int l1 = 0; l1 < l; l1++)
        {
            int k2 = world.getBlockId(i, j + l1, k);
            if (k2 == 0 || k2 == Block.leaves.blockID)
            {
                setBlockAndMetadata(world, i, j + l1, k, mod_HogeTree.hogeWood.blockID, 0);
            }
        }

        return true;
    }
}

正直、中級者向け以上だと思う。


自分のコメントを追加
Minecraft Modding Wikiはすべてのコメントを歓迎します。匿名で投稿したくない場合は、アカウント作成またはログインしてください。無料です。


  • これはForgeが前提になってるんでは? --58.72.83.244 2012年9月11日 (火) 14:02 (JST)