初心者modderの備忘録

マイクラのmodを作りたくて、初めて見たのですが難しくて忘れそうなので自分用の備忘録も兼ねてブログにしようと思います

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消費して、コンソールにメッセージを出力するだけのアイテムができました。
f:id:json_fileman:20181231155327p:plain
空に向かって使っても、ちゃんとメッセージが表示されていますね!


次に機能を追加していきます。
今回は、使用するとプレイヤーの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);
    }

f:id:json_fileman:20181231161100p:plain

こんな感じになりました。ちなみにこれだと、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になったらフラグを寝かせます。

もっといいコードないですかね?笑

Up_and_Brick
Teleporte



次回はMOBの追加をしたいとおもいます。