我的世界1.20.1模组开发---13.添加新的附魔

介绍

  最近备战期末,又逢放假,休息了一阵子没有更新,这次来介绍一些有趣的东西,那就是游戏中的附魔系统。游戏中可以对我们的装备、武器和工具在附魔台上进行附魔,旁边还可以放书架来提升可附魔等级,当年第一次见到这个玩法的时候就吸引到我了,感觉附魔系统还挺有趣的,这次我们就好好说一说mod中怎么添加新的附魔效果。

  在游戏中附魔的英文叫做enchantment,所以我们在看源码的时候也可以往这个方向靠靠,我们先找到enchantment类,这是所有附魔效果的父类,我们在这个单词上面按下CTRL+H快捷键(IDEA中)就可以看到这个类的父子关系,如下图所示。可以看到,原版中的所有附魔效果都要继承这个类,因此我们新建一个附魔类的时候也要继承这个类。因为附魔效果与ItemBlock不算是同一类别的对象,所以我们的附魔效果要想物品和方块一样新建一个注册的类,用来把我们的附魔放到注册表中,写法都和那两者一样,下面就来详细说明一下enchantment类。

  Enchantment类

  这里面东西还挺多的,但是大部分我们采用默认的即可,这俩我们只挑一些重要的来说明。

public abstract class Enchantment implements net.minecraftforge.common.extensions.IForgeEnchantment {
   private final EquipmentSlot[] slots;//附魔有效的槽位
   private final Enchantment.Rarity rarity;//附魔的稀有度
   public final EnchantmentCategory category;//附魔的种类
   @Nullable
   protected String descriptionId;//id值
    
    //当实体被带有此附魔的物品攻击时调用
   public void doPostAttack(LivingEntity pAttacker, Entity pTarget, int pLevel) {
   }
    
     //当实体被带有此附魔的物品攻击收到伤害后调用
   public void doPostHurt(LivingEntity pTarget, Entity pAttacker, int pLevel) {
   }
}

  首先就是最重要的属性,前三个是重点,最后一个id值不用管。

  第一个参数是指该附魔可以起作用的槽位(就是主手、副手、装备槽等槽位),第二个参数是指附魔的稀有度(越稀有越难在附魔台附魔到),第三个参数是指可以被附魔这个附魔的物品(里面有武器、装备等等)。详细参数可以进这个类里面看一下,这里不在过多介绍。

  下面是一个例子,我想把这个附魔用在剑上,就选择武器分类,并且用在主手上,稀有度为普通。

  另外doPostAttack方法和doPostHurt方法和之前Item类里面的方法用途一样,子类重写这个方法,在特定的时候可以调用这个方法来执行一些逻辑。但是我测试时发现doPostAttack方法不管怎么写都会执行两次,目前我还无法解决。方法里有三个参数,第一个参数是攻击者,第二个参数是被攻击的实体,第三个参数是该附魔的等级,有了这些参数我们就可以对目标进行一些处理,比如加大攻击力,让它飞起来等等操作,下面上代码。

代码

  首先和之前的ItemBlock一样,我们需要新建一个注册类,用来注册所有的附魔,我们在test1mod包下新建一个enchantment包,在这个包下新建一个ModEnchantments类,这个类里面创建一个注册表,用来注册所有新增的附魔。

//具体写法和ModItems、ModBlocks类一样
public class ModEnchantments {
    public static final DeferredRegister<Enchantment> ENCHANTMENTS=DeferredRegister.create(ForgeRegistries.ENCHANTMENTS, Test1Mod.MOD_ID);

    //向注册表中注册新加入的附魔
    public static final RegistryObject<Enchantment>LIGHTING_ATTACK=ENCHANTMENTS.register("lighting_attack",
            ()->new LightingAttack(Enchantment.Rarity.COMMON,EnchantmentCategory.WEAPON,EquipmentSlot.MAINHAND));

    //将注册表添加到事件总线上
    public static void register(IEventBus eventBus){
        ENCHANTMENTS.register(eventBus);
    }
}



//然后到主类Test1mod中添加到总线
ModEnchantments.register(modEventBus);

  之后就可以开始新建附魔效果了。在enchantments包下新建一个LightingAttack类,这个附魔效果会在攻击敌人的同时召唤闪电劈敌人,这个类要继承Enchantment类。

public class LightingAttack extends Enchantment{

    protected LightingAttack(Rarity pRarity, EnchantmentCategory pCategory, EquipmentSlot... pApplicableSlots) {
        super(pRarity, pCategory, pApplicableSlots);
    }

    @Override
    public void doPostAttack(LivingEntity attacker, Entity target, int pLevel) {
        onAttack(attacker,target,pLevel);
    }

    public static void onAttack(LivingEntity attacker, Entity target, int level){
        //在服务器端执行
        if(!attacker.level().isClientSide()){
            if(attacker instanceof Player player){
                //获取目标站立的位置
                BlockPos pos=target.getOnPos();
                if(level>0){
                    player.sendSystemMessage(Component.literal("以雷霆击碎黑暗!"));
                    //根据附魔等级在目标站立位置生成闪电
                    for(int i=0;i<level;i++){
                        EntityType.LIGHTNING_BOLT.spawn((ServerLevel) player.level(),pos, MobSpawnType.TRIGGERED);
                    }
                }
            }
        }


    }
    //附魔的最大等级,从1开始
    @Override
    public int getMaxLevel() {
        return 3;
    }

}

   因为新增一个附魔就会在游戏中新加一种附魔书,所以我们痛同样需要写一下这个附魔的语言文件,这里不在展示。RunData成功后就可以RunClient启动游戏了。下图就是实际的效果了,是不是很酷炫呢。Enchantment类中还有很多可以供我们修改的地方,这些方法可以控制附魔的最大等级,附魔的兼容性,是否能在附魔台附魔到等等,大家感兴趣的话建议自己研究一下,我就不过多解释(主要是我目前也不是了解的很透彻,附魔机制还是有点复杂的x.x)。

posted @ 2024-01-14 12:34  小明同学404  阅读(117)  评论(0编辑  收藏  举报