0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

概要

  • マインクラフトに新しいエンチャントを追加します。
  • 切った対象にエヴォーカーファングを追尾させる「魔術」を追加します。

コード

新しいエンチャントのクラス作成

Enchantmentを継承して作成します。

ForbiddenSorceryEnchantment

package com.example.examplemod.EditHere.enchant;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.monster.Evoker;
import net.minecraft.world.entity.projectile.EvokerFangs;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.NotNull;

public class ForbiddenSorceryEnchantment extends Enchantment {
    public ForbiddenSorceryEnchantment(){
        super(Rarity.VERY_RARE, EnchantmentCategory.WEAPON, new EquipmentSlot[]{EquipmentSlot.MAINHAND, EquipmentSlot.OFFHAND});
    }

    // 最小のエンチャントコストを取得するメソッド
    @Override
    public int getMinCost(int pLevel) {
        return super.getMinCost(pLevel);
    }
    // 最大のエンチャントコストを取得するメソッド
    @Override
    public int getMaxCost(int pLevel) {
        return super.getMaxCost(pLevel);
    }
    // レアリティを取得するメソッド

    @Override
    public @NotNull Rarity getRarity() {
        return Rarity.VERY_RARE;
    }
    // 最小のエンチャントレベルを取得するメソッド
    @Override
    public int getMinLevel() {
        return super.getMinLevel();
    }
    // 最大のエンチャントレベルを取得するメソッド
    // 10まではローマ数字で表してくれる
    @Override
    public int getMaxLevel() {
        return 10;
    }
    // 呪いかどうか。呪いなら赤色になる。
    @Override
    public boolean isCurse() {
        return true;
    }

    @Override
    public void doPostAttack(@NotNull LivingEntity pAttacker, @NotNull Entity pTarget, int pLevel) {
        Level level=pAttacker.level;
        // サーバーサイドで実行
        if(level instanceof ServerLevel){
            // プレイヤーの視線のy軸回転(Yaw)を取得
            float yaw=pAttacker.getYRot();
            // エンチャントレベルに応じて射程を変える
            int[] angles={0, -30, 30};
            for(int angleOffset:angles){
                // 距離1ブロックからエンチャントレベル分のブロック数だけファングを生成
                for(int i=1; i<pLevel; i++){
                    // 角度と距離から座標を計算
                    double rad=Math.toRadians(yaw+angleOffset+90);
                    double x=pAttacker.getX()+(double) i*Math.cos(rad);
                    double z=pAttacker.getZ()+(double) i*Math.sin(rad);
                    spawnFang(level, x, z, pAttacker.getY(), pAttacker, yaw, i);
                }
            }
        }
    }
    // 指定されたx, z座標の地面を探し、そこにファングをスポーンさせるメソッド
    private void spawnFang(Level level, double x, double z, double attackerY, LivingEntity owner, float yaw, int delay){
        BlockPos pos=new BlockPos(x, attackerY, z);
        boolean foundGround=false;
        double yOffset=0.0D;

        // プレイヤーの高さから上下に地面を探す範囲
        // 下に掘り下げる
        for(int i=0; i>=-2; i--){
            BlockPos checkPos=pos.above(i);
            BlockState state=level.getBlockState(checkPos);
            BlockState belowState=level.getBlockState(checkPos.below());

            // 下が頑丈なブロックかつ今の場所が空気や通り抜けられるものなら地面だと判定する
            if(belowState.isFaceSturdy(level, checkPos.below(), Direction.UP) && !state.getMaterial().isSolid()){
                // 厳密な高さ調整(ハーフブロックや積雪対応)
                if(!level.isEmptyBlock(checkPos)){
                    VoxelShape shape=state.getCollisionShape(level, checkPos);
                    if(!shape.isEmpty()){
                        yOffset=shape.max(Direction.Axis.Y);
                    }
                }
                pos=checkPos;
                foundGround=true;
                break;
            }
        }
        // 地面が見つかった場合のみスポーン
        if(foundGround){
            level.addFreshEntity(new EvokerFangs(level, x, pos.getY()+yOffset, z, yaw, delay, owner));
        }
    }
}

Example Modでの登録

 public static final Enchantment FORBIDDEN_SORCERY=new ForbiddenSorceryEnchantment().setRegistryName(MODID,"forbidden_sorcery");

専用のレジストリに登録。(新しく作る)

@SubscribeEvent
        public static void onEnchantmentsRegistry(final RegistryEvent.Register<Enchantment> event){
            IForgeRegistry<Enchantment> registry=event.getRegistry();
            registry.register(FORBIDDEN_SORCERY);
        }

補遺

新しいエンチャントを作ると自動でエンチャントの本も生成される。

動画

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?