提供: Minecraft Modding Wiki
(基盤作成 説明足りてないと思う) |
細 (エラーが発生するところを修正。) |
||
103行目: | 103行目: | ||
protected BlockHogeLeaves(int i, int j) | protected BlockHogeLeaves(int i, int j) | ||
{ | { | ||
− | super(i, j, Material.leaves, false); | + | super( i, j, Material.leaves, false); |
− | baseIndexInPNG = j; | + | this.baseIndexInPNG = j; |
− | + | this.setTickRandomly(true); | |
} | } | ||
149行目: | 149行目: | ||
for (int i2 = -1; i2 <= 1; i2++) | for (int i2 = -1; i2 <= 1; i2++) | ||
{ | { | ||
− | int j2 = iblockaccess. | + | int j2 = iblockaccess.func_48454_a(i + i2, k + l1).func_48412_k(); |
i1 += (j2 & 0xff0000) >> 16; | i1 += (j2 & 0xff0000) >> 16; | ||
j1 += (j2 & 0xff00) >> 8; | j1 += (j2 & 0xff00) >> 8; |
2012年3月27日 (火) 23:15時点における版
この記事は"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; } }
正直、中級者向け以上だと思う。
コメントの自動更新を有効化