5日目 アイテムの機能の追加2
前回に引き続き、アイテムに機能をもたせようと思います。
今回はエンダーパールのようにブロックにカーソルを合わせないで使うタイプのアイテムを作成します。
今回は新しいアイテムは作成せずに前回作成したItemTomatoEggの中身だけ編集していこうと思います。
まず参照ライブラリーからItemEnderPearlを開き、ActionResult
ItemTomatoEgg.java_ed4
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { ItemStack itemstack = playerIn.getHeldItem(handIn); if (!playerIn.capabilities.isCreativeMode) { itemstack.shrink(1); } System.out.println("Right-clicked"); playerIn.addStat(StatList.getObjectUseStats(this)); return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemstack); }
サバイバルモードではアイテムを1消費して、コンソールにメッセージを出力するだけのアイテムができました。
空に向かって使っても、ちゃんとメッセージが表示されていますね!
次に機能を追加していきます。
今回は、使用するとプレイヤーのy座標を+10してその下にレンガブロックを配置するような機能をつけてみます。
public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { ItemStack itemstack = playerIn.getHeldItem(handIn); if (!playerIn.capabilities.isCreativeMode) { itemstack.shrink(1); } if(!worldIn.isRemote){ worldIn.setBlockState(playerIn.getPosition().add(0, 9, 0), Blocks.BRICK_BLOCK.getDefaultState()); } playerIn.setPosition(playerIn.posX, playerIn.posY+10, playerIn.posZ); System.out.println("Right-clicked"); playerIn.addStat(StatList.getObjectUseStats(this)); return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemstack); }
こんな感じになりました。ちなみにこれだと、Y=255を超えてブロックを生成しようとするので本当はifを書くべきですね。
あと、こういうテレポート系で一瞬で移動するんじゃなくて進んでいるようにする方法がないか調べてみました。
正しい方法なのかわかりませんが、一応書いておくのでもし詳しい人がいたら教えてほしいです。
またItemTomatoEggを編集して、使用するとプレイヤーが向いている方に20マスくらい進むアイテムにしました。
ItemTomatoEgg.java_
boolean isUsing = false; int counter=0; public ActionResult<ItemStack> onItemRightClick(World worldIn, EntityPlayer playerIn, EnumHand handIn) { ItemStack itemstack = playerIn.getHeldItem(handIn); if (!playerIn.capabilities.isCreativeMode) { itemstack.shrink(1); } if(counter==0)isUsing = true; playerIn.addStat(StatList.getObjectUseStats(this)); return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, itemstack); } public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected) { double X; double Z; double nextX; double nextZ; if(isUsing) { X=entityIn.getHorizontalFacing().getFrontOffsetX()*1.0D; Z=entityIn.getHorizontalFacing().getFrontOffsetZ()*1.0D; nextX=entityIn.lastTickPosX+X; nextZ=entityIn.lastTickPosZ+Z; entityIn.setPosition(nextX, entityIn.prevPosY, nextZ); counter++; } if(counter==20) { isUsing=false; counter=0; } }
そこで今回は毎tick呼び出されるonUpdateメソッドを利用しました。右クリックはフラグ立てに使用します。右クリックでフラグを立てて、フラグが立っている間はouUpdateの中の処理を行うという構築にしました。
entityIn.getHorizontalFacing().getFrontOffsetX()はプレイヤーがX座標の正の方向を向いているときは1、負の方向を向いているときは-1を返し、Z座標を向いているときは0を返します。offsetZはそれのZ版で、必ずどちらか1つだけが1または-1を返します。後ろの1.0Dを任意の数字に変えることで1tickに移動できる距離を調整できるんじゃないかと思っています。
この値を現在の座標に加えていき、counterが20になったらフラグを寝かせます。
もっといいコードないですかね?笑
次回はMOBの追加をしたいとおもいます。