種の使用について

Modding・サーバPlugin制作・ツール制作など、開発関連の質問があればこちらにお願い致します。
フォーラムルール
質問関連フォーラムで質問する時は、必ず次のトピックを一読/厳守お願い致します。
viewtopic.php?f=5&t=999
  • (PostNo.305926)

種の使用について

投稿記事by dark snow » 2017年8月07日(月) 11:56

Forge-1.7.10-10.13.4.1558-1.7.10環境でmoddingをしているのですが、種を植えようとするとクラッシュしてしまいます。
一度試しに種ではなく作物ブロックを植えてみたらクラッシュしませんでした。

ItemADSeeds
コード: 全て選択
package mods.steel;

import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemSeeds;
import net.minecraft.item.ItemStack;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.ForgeDirection;

public class ItemADSeeds extends ItemSeeds implements IPlantable {
   private Block field_150925_a;
   // 土台となるブロックのインスタンス。使われていない。
   //   private Block soilBlockID;
 
   public ItemADSeeds() {
      super(SteelModAPI.cropAD, Blocks.farmland);
      // 以下はItemSeedsのコンストラクタ。
      this.field_150925_a = SteelModAPI.cropAD;
      //      this.soilBlockID = Blocks.farmland;
      //      this.setCreativeTab(CreativeTabs.tabMaterials);
      this.setCreativeTab(SteelModAPI.tabSteel);
      this.setUnlocalizedName("seedAD");
      this.setTextureName("steelmod:seed_ad");
      GameRegistry.registerItem(this,"seedAD");
   }
 
   /** アイテムを使用した時の処理。 */
   @Override
   public boolean onItemUse(ItemStack itemStack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) {
      if (side != 1) {
         return false;
      } else if (player.canPlayerEdit(x, y, z, side, itemStack) && player.canPlayerEdit(x, y + 1, z, side, itemStack)) {
         // 上からの使用で、プレイヤーが編集可能で、右クリックしたブロックが耕地であり、その上が空気の時。
         if (world.getBlock(x, y, z).canSustainPlant(world, x, y, z, ForgeDirection.UP, this) && world.isAirBlock(x, y + 1, z)) {
            // 作物を設置する。
            world.setBlock(x, y + 1, z, this.field_150925_a);
            // スタック数を減らす。
            --itemStack.stackSize;
            return true;
         } else {
            return false;
         }
      } else {
         return false;
      }
   }
 
   /** 作物の種別を返す。 */
   @Override
   public EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z) {
      // IPlantableの実装。作物。耕地の上に設置する。
      return EnumPlantType.Crop;
   }
 
   /** 作物ブロックのインスタンスを返す。 */
   @Override
   public Block getPlant(IBlockAccess world, int x, int y, int z) {
      // IPlantableの実装。
      return field_150925_a;
   }
 
   /** 作物のメタデータを返す。 */
   @Override
   public int getPlantMetadata(IBlockAccess world, int x, int y, int z) {
      // IPlantableの実装。
      return 0;
   }
}

BlockADCrop
コード: 全て選択
package mods.steel;

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

import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCrops;
import net.minecraft.block.IGrowable;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraftforge.common.EnumPlantType;
import net.minecraftforge.common.IPlantable;
import net.minecraftforge.common.util.ForgeDirection;

public class BlockADCrop extends BlockCrops implements IPlantable, IGrowable {
   private IIcon[] iIcons;
 
   public BlockADCrop() {
      // BlockBushのコンストラクタでMaterialはMaterial.plantsを指定されている。
      super();
      // updateTickがランダムに呼ばれるようにする。
      this.setTickRandomly(true);
      // ブロックの大きさを指定する。あたり判定やカーソルがあった時の枠の大きさに使われる。
      float f = 0.5F;
      this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, 0.25F, 0.5F + f);
      // クリエイティブタブに表示されないようにする。
      this.setCreativeTab(null);
      // 一瞬で破壊できるようにする。ツールを持っていても耐久値は消費しない。
      this.setHardness(0.0F);
      // 設置時や歩行時の音の種類を指定する。
      this.setStepSound(soundTypeGrass);
      // 統計にカウントされないようにする。(?)
      this.disableStats();
      this.setBlockName("cropAD");
      this.setBlockTextureName("steelmod:crop_ad");
      GameRegistry.registerBlock(this, "cropAD");
   }
 
   /** その座標に設置できるか。 */
   @Override
   public boolean canPlaceBlockAt(World world, int x, int y, int z) {
      return world.getBlock(x, y, z).isReplaceable(world, x, y, z) && this.canBlockStay(world, x, y, z);
      // 以下はBlockBushでの実装。superを呼び出すと二重に判定されてしまうため変更した。
      //      return super.canPlaceBlockAt(world, x, y, z) && this.canBlockStay(world, x, y, z);
   }
 
   /** そのブロックの上に設置できるか。 */
   @Override
   protected boolean canPlaceBlockOn(Block block) {
      // 耕地の上のみ。
      return block == Blocks.farmland;
   }
 
   /** 隣接ブロックが更新された時の処理。 */
   @Override
   public void onNeighborBlockChange(World world, int x, int y, int z, Block block) {
      // 二重判定回避のためコメントアウト。実際、Blockクラスでは何もしていない。
      //      super.onNeighborBlockChange(world, x, y, z, block);
      this.checkAndDropBlock(world, x, y, z);
   }
 
   /** Tick更新時の処理。 */
   @Override
   public void updateTick(World world, int x, int y, int z, Random random) {
      // ランダムに呼ばれる。
      this.checkAndDropBlock(world, x, y, z);
      // 一つ上のブロックの光源レベルが0以上の時。
      if (world.getBlockLightValue(x, y + 1, z) >= 0) {
         // メタデータを取得。
         int l = world.getBlockMetadata(x, y, z);
         // 成長限界に達していない時。
         if (l < 3) {
            // 成長しやすさを取得。
            float f = this.func_149864_n(world, x, y, z);
            // 成長させるかを判定する。
            if (random.nextInt((int) (25.0F / f) + 1) == 0) {
               // 一段階成長させる。
               ++l;
               world.setBlockMetadataWithNotify(x, y, z, l, 2);
            }
         }
      }
   }
 
   /** 設置状態を維持できるかを確認し、維持できなければドロップする。 */
   @Override
   protected void checkAndDropBlock(World world, int x, int y, int z) {
      // 維持できない時。
      if (!this.canBlockStay(world, x, y, z)) {
         // ドロップする。
         this.dropBlockAsItem(world, x, y, z, world.getBlockMetadata(x, y, z), 0);
         // 空気に上書きする。
         world.setBlock(x, y, z, getBlockById(0), 0, 2);
      }
   }
 
   /** その座標で維持できるか。 */
   @Override
   public boolean canBlockStay(World world, int x, int y, int z) {
      // 下のブロックが耕地かどうかを判定する。
      return world.getBlock(x, y - 1, z).canSustainPlant(world, x, y - 1, z, ForgeDirection.UP, this);
   }
 
   /** 作物の種別を返す。 */
   @Override
   public EnumPlantType getPlantType(IBlockAccess world, int x, int y, int z) {
      // IPlantableの実装。作物。耕地の上に設置する。
      return EnumPlantType.Crop;
   }
 
   /** 作物ブロックのインスタンスを返す。 */
   @Override
   public Block getPlant(IBlockAccess world, int x, int y, int z) {
      // IPlantableの実装。
      return this;
   }
 
   /** 作物のメタデータを返す。 */
   @Override
   public int getPlantMetadata(IBlockAccess world, int x, int y, int z) {
      // IPlantableの実装。
      return world.getBlockMetadata(x, y, z);
   }
 
   /** 成長しやすさの数値を返す。 */
   private float func_149864_n(World world, int x, int y, int z) {
      // 周囲の耕地、作物の状況を判定し、成長しやすさを算出する。
      float f = 1.0F;
      Block block = world.getBlock(x, y, z - 1);
      Block block1 = world.getBlock(x, y, z + 1);
      Block block2 = world.getBlock(x - 1, y, z);
      Block block3 = world.getBlock(x + 1, y, z);
      Block block4 = world.getBlock(x - 1, y, z - 1);
      Block block5 = world.getBlock(x + 1, y, z - 1);
      Block block6 = world.getBlock(x + 1, y, z + 1);
      Block block7 = world.getBlock(x - 1, y, z + 1);
      boolean flag = block2 == this || block3 == this;
      boolean flag1 = block == this || block1 == this;
      boolean flag2 = block4 == this || block5 == this || block6 == this || block7 == this;
      for (int l = x - 1; l <= x + 1; ++l) {
         for (int i1 = z - 1; i1 <= z + 1; ++i1) {
            float f1 = 0.0F;
            if (world.getBlock(l, y - 1, i1).canSustainPlant(world, l, y - 1, i1, ForgeDirection.UP, this)) {
               f1 = 1.0F;
               if (world.getBlock(l, y - 1, i1).isFertile(world, l, y - 1, i1)) {
                  f1 = 3.0F;
               }
            }
            if (l != x || i1 != z) {
               f1 /= 4.0F;
            }
            f += f1;
         }
      }
      if (flag2 || flag && flag1) {
         f /= 2.0F;
      }
      return f;
   }
 
   /** あたり判定を返す。 */
   @Override
   public AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) {
      // あたり判定をなくす。
      return null;
   }
 
   /** 不透明なブロックか。 */
   @Override
   public boolean isOpaqueCube() {
      // 透明なブロックなのでfalseを返す。
      return false;
   }
 
   /** 通常と同様に描画するか。 */
   @Override
   public boolean renderAsNormalBlock() {
      return false;
   }
 
   /** 描画の種別を返す。 */
   @Override
   public int getRenderType() {
      // 小麦などと同じ。四枚の板が上から見て「井」の形になるように配置され、そこにテクスチャが表示される。
      return 1;
   }

   /** 種のアイテムを返す。 */
   @Override
   protected Item func_149866_i() {
      return SteelModAPI.seedAD;
   }

   /** 作物のアイテムを返す。 */
   @Override
   protected Item func_149865_P() {
      return SteelModAPI.essenceAD;
   }

   /** ブロックをドロップさせる。 */
   @Override
   public void dropBlockAsItemWithChance(World world, int x, int y, int z, int meta, float dropChance, int fortune) {
      super.dropBlockAsItemWithChance(world, x, y, z, meta, dropChance, fortune);
      // BlockCropで以下のようにオーバーライドされている。幸運レベルを0に固定。
      //      super.dropBlockAsItemWithChance(world, x, y, z, meta, dropChance, 0);
   }

   /** ドロップアイテムを返す。 */
   @Override
   public Item getItemDropped(int meta, Random random, int fortune) {
      // 基本的に種を返すが、完全成長していたら作物を返す。
      return meta == 3 ? this.func_149865_P() : this.func_149866_i();
   }

   /** ドロップ数を返す。 */
   @Override
   public int quantityDropped(Random random) {
      return 16;
   }

   /** ドロップアイテムのリストを返す。 */
   @Override
   public ArrayList<ItemStack> getDrops(World world, int x, int y, int z, int metadata, int fortune) {
      ArrayList<ItemStack> ret = new ArrayList<ItemStack>();
      int count = quantityDropped(metadata, fortune, world.rand);
      for (int i = 0; i < count; i++) {
         Item item = getItemDropped(metadata, world.rand, fortune);
         if (item != null) {
            ret.add(new ItemStack(item, 1, damageDropped(metadata)));
         }
      }
      // 以上はBlockでの実装。以下はBlockCropsでの実装。重複処理回避のため変更した。
            //      ArrayList<ItemStack> ret = super.getDrops(world, x, y, z, metadata, fortune);
            //
            // 完全成長の時
      if (metadata >= 3) {
         // 幸運レベルにより判定回数が増加する。デフォルトは3回。
         for (int i = 0; i < 3 + fortune; ++i) {
            // 0~14 <= 3 より、1/2の確率。
            if (world.rand.nextInt(15) <= metadata) {
               // 種を追加する。
               ret.add(new ItemStack(this.func_149866_i(), 1, 0));
            }
         }
      }
      return ret;
   }

   /** 対応するアイテムを返す。 */
   @Override
   @SideOnly(Side.CLIENT)
   public Item getItem(World world, int x, int y, int z) {
      // 種を返す。
      return this.func_149866_i();
   }

   /** ブロックのテクスチャを返す。 */
   @Override
   @SideOnly(Side.CLIENT)
   public IIcon getIcon(int side, int meta) {
      // メタデータの数値が異常だったら成長限界の値を使う。
      if (meta < 0 || meta > 3) {
         meta = 3;
      }
      return this.iIcons[meta];
   }

   /** ブロックのテクスチャを登録する。 */
   @Override
   @SideOnly(Side.CLIENT)
   public void registerBlockIcons(IIconRegister register) {
      this.iIcons = new IIcon[4];
      for (int i = 0; i < this.iIcons.length; ++i) {
         this.iIcons[i] = register.registerIcon(this.getTextureName() + "_stage_" + i);
      }
   }

   /** 骨粉を使用できるか。 */
   @Override
   public boolean func_149851_a(World world, int x, int y, int z, boolean isRemote) {
      // IGrowableの実装。完全成長していたらfalse。
      return world.getBlockMetadata(x, y, z) != 3;
   }

   /** 骨粉を適用するか。 */
   @Override
   public boolean func_149852_a(World world, Random random, int x, int y, int z) {
      // IGrowableの実装。
      return true;
   }

   /** 骨粉を適用する。 */
   @Override
   public void func_149853_b(World world, Random random, int x, int y, int z) {
      // IGrowableの実装。
      this.func_149863_m(world, x, y, z);
   }

   /** 骨粉を使用した時の成長させる処理。 */
   @Override
   public void func_149863_m(World world, int x, int y, int z) {
      // 成長段階を2以上5以下上昇させる。
      int l = world.getBlockMetadata(x, y, z) + MathHelper.getRandomIntegerInRange(world.rand, 2, 5);
      // 成長限界を超えていたら抑える。
      if (l > 3) {
         l = 3;
      }
      // メタデータを設定する。
      world.setBlockMetadataWithNotify(x, y, z, l, 2);
   }
}

クラッシュレポート
---- Minecraft Crash Report ----
// Shall we play a game?

Time: 17/08/07 11:16
Description: Unexpected error

java.lang.NullPointerException: Unexpected error
at net.minecraft.world.chunk.storage.ExtendedBlockStorage.func_150818_a(ExtendedBlockStorage.java:86)
at net.minecraft.world.chunk.Chunk.func_150807_a(Chunk.java:653)
at net.minecraft.world.World.setBlock(World.java:519)
at net.minecraft.world.World.setBlock(World.java:681)
at net.minecraft.item.ItemSeeds.onItemUse(ItemSeeds.java:41)
at net.minecraft.item.ItemStack.tryPlaceItemIntoWorld(ItemStack.java:143)
at net.minecraft.client.multiplayer.PlayerControllerMP.onPlayerRightClick(PlayerControllerMP.java:403)
at net.minecraft.client.Minecraft.func_147121_ag(Minecraft.java:1529)
at net.minecraft.client.Minecraft.runTick(Minecraft.java:2044)
at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1039)
at net.minecraft.client.Minecraft.run(Minecraft.java:962)
at net.minecraft.client.main.Main.main(Main.java:164)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
at GradleStart.main(Unknown Source)


A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

-- Head --
Stacktrace:
at net.minecraft.world.chunk.storage.ExtendedBlockStorage.func_150818_a(ExtendedBlockStorage.java:86)
at net.minecraft.world.chunk.Chunk.func_150807_a(Chunk.java:653)
at net.minecraft.world.World.setBlock(World.java:519)
at net.minecraft.world.World.setBlock(World.java:681)
at net.minecraft.item.ItemSeeds.onItemUse(ItemSeeds.java:41)
at net.minecraft.item.ItemStack.tryPlaceItemIntoWorld(ItemStack.java:143)
at net.minecraft.client.multiplayer.PlayerControllerMP.onPlayerRightClick(PlayerControllerMP.java:403)
at net.minecraft.client.Minecraft.func_147121_ag(Minecraft.java:1529)

-- Affected level --
Details:
Level name: MpServer
All players: 1 total; [EntityClientPlayerMP['Player47'/0, l='MpServer', x=897.51, y=54.62, z=1132.55]]
Chunk stats: MultiplayerChunkCache: 169, 169
Level seed: 0
Level generator: ID 01 - flat, ver 0. Features enabled: false
Level generator options:
Level spawn location: World: (899,4,1126), Chunk: (at 3,0,6 in 56,70; contains blocks 896,0,1120 to 911,255,1135), Region: (1,2; contains chunks 32,64 to 63,95, blocks 512,0,1024 to 1023,255,1535)
Level time: 241784 game time, 6800 day time
Level dimension: 0
Level storage version: 0x00000 - Unknown?
Level weather: Rain time: 0 (now: true), thunder time: 0 (now: false)
Level game mode: Game mode: creative (ID 1). Hardcore: false. Cheats: false
Forced entities: 1 total; [EntityClientPlayerMP['Player47'/0, l='MpServer', x=897.51, y=54.62, z=1132.55]]
Retry entities: 0 total; []
Server brand: fml,forge
Server type: Integrated singleplayer server
Stacktrace:
at net.minecraft.client.multiplayer.WorldClient.addWorldInfoToCrashReport(WorldClient.java:415)
at net.minecraft.client.Minecraft.addGraphicsAndWorldToCrashReport(Minecraft.java:2566)
at net.minecraft.client.Minecraft.run(Minecraft.java:991)
at net.minecraft.client.main.Main.main(Main.java:164)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
at GradleStart.main(Unknown Source)

-- System Details --
Details:
Minecraft Version: 1.7.10
Operating System: Windows 10 (amd64) version 10.0
Java Version: 1.8.0_112, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 747860280 bytes (713 MB) / 1038876672 bytes (990 MB) up to 1038876672 bytes (990 MB)
JVM Flags: 3 total; -Xincgc -Xmx1024M -Xms1024M
AABB Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0
FML: MCP v9.05 FML v7.10.99.99 Minecraft Forge 10.13.4.1558 4 mods loaded, 4 mods active
States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored
UCHIJAAAAAAAAA mcp{9.05} [Minecraft Coder Pack] (minecraft.jar)
UCHIJAAAAAAAAA FML{7.10.99.99} [Forge Mod Loader] (forgeSrc-1.7.10-10.13.4.1558-1.7.10.jar)
UCHIJAAAAAAAAA Forge{10.13.4.1558} [Minecraft Forge] (forgeSrc-1.7.10-10.13.4.1558-1.7.10.jar)
UCHIJAAAAAAAAA SteelMod{1.0.0} [SteelMod] (bin)
GL info: ' Vendor: 'Intel' Version: '4.0.0 - Build 10.18.10.4358' Renderer: 'Intel(R) HD Graphics 4000'
Launched Version: 1.7.10
LWJGL: 2.9.1
OpenGL: Intel(R) HD Graphics 4000 GL version 4.0.0 - Build 10.18.10.4358, Intel
GL Caps: Using GL 1.3 multitexturing.
Using framebuffer objects because OpenGL 3.0 is supported and separate blending is supported.
Anisotropic filtering is supported and maximum anisotropy is 16.
Shaders are available because OpenGL 2.1 is supported.

Is Modded: Definitely; Client brand changed to 'fml,forge'
Type: Client (map_client.txt)
Resource Packs: []
Current Language: 日本語 (日本)
Profiler Position: N/A (disabled)
Vec3 Pool Size: 0 (0 bytes; 0 MB) allocated, 0 (0 bytes; 0 MB) used
Anisotropic Filtering: Off (1)

他にも載せたほうが良いclassがありましたら、ご意見お願いします。
何かわかる方がいらっしゃいましたら、教えた下さい。
お願いします。
dark snow
ID:0e3e0877
木を殴ってる
 
記事: 18
登録日時: 2017年2月09日(木) 17:55

Return to 質問:開発・制作関連

cron

x