zoukankan      html  css  js  c++  java
  • Minecraft 1.12.2 Mod开发笔记——新的附魔类型和状态效果(药水)

    总目录:Minecraft 1.12.2 开发笔记

    新的附魔

    我们试着给剑创建一个叫引爆的附魔。

    在 moonfan.mymod.enchantment 包下新建类 EnchantmentIgnite.java

    public class EnchantmentIgnite extends Enchantment {
        protected EnchantmentIgnite() {
            super(Rarity.COMMON, EnumEnchantmentType.WEAPON, new EntityEquipmentSlot[]{EntityEquipmentSlot.MAINHAND});
            // 设置非本地化名称
            this.setName("ignite_enchantment");
        }
    }
    

    来看构造器

    protected Enchantment(Enchantment.Rarity rarityIn, EnumEnchantmentType typeIn, EntityEquipmentSlot[] slots)

    • rarityIn 枚举类,表示附魔的稀有程度,有 COMMON、UNCOMMON、RARE 和 VERY_RARE 四种。
    • typeIn 枚举类,表示可以接收该附魔的物品种类,有 ALL、WEAPON、ARMOR 等多种类型。
    • slots 枚举类数组,表示被附魔的物品处于何种状态时附魔生效,有 MAINHAND、OFFHAND、FEET、LEGS、CHEST、HEAD 六种。

    附魔和物品一样需要注册:

    public class EnchantmentLoader {
        public static Enchantment ignite = new EnchantmentIgnite();
    
        @SubscribeEvent
        public static void registerEnchantment(RegistryEvent.Register<Enchantment> event){
            event.getRegistry().register(ignite.setRegistryName("mymod:ignite_enchantment"));
        }
    }
    

    en_us.lang:

    enchantment.ignite_enchantment=Ignite
    

    现在,可以通过 /give 命令或者附魔台得到带有这个附魔的剑了。但附魔本身只规定种类,并不规定其效果,效果的实现需要在需要的地方添加,比如时运和精准采集的效果其实是在 Block 类里判断方块掉落的时候添加的。在进阶部分再作说明。

    新的状态效果(药水)

    Minecraft 中,状态效果和药水是两个概念,喝了药水可以出现状态效果,而有状态效果不一定要有对应的药水,比如饥饿效果、凋零效果。

    我们先创建一个叫类似于中毒的持续扣血效果。

    在 moonfan.mymod.potion 包下新建类 PotionInjure.java

    public class PotionInjure extends Potion {
        protected PotionInjure() {
            super(true, 0xffffff);
            // 这里是设置的是实际的名称,不是非本地化名称
            setPotionName("injured");
        }
    }
    

    构造器 protected Potion(boolean isBadEffectIn, int liquidColorIn)

    • isBadEffectIn 是否是负面效果
    • liquidColorIn 状态效果的气泡以及药水瓶(如果有)的RGB颜色值,比如0xffffff

    状态效果和物品一样需要注册:

    @Mod.EventBusSubscriber
    public class PotionLoader {
        public static Potion injure = new PotionInjure();
        @SubscribeEvent
        public static void registerPotion(RegistryEvent.Register<Potion> event){
            event.getRegistry().register(injure.setRegistryName("mymod:injure"));
        }
    }
    

    现在,我们可以用命令 /effect 玩家名 mymod:injure 120 0 来给自己加上Ⅰ级,持续时间120s的 injured 效果了,不知道 harbinger 的教程里是不是把命令打错了。。

    药水类型

    前面说过,状态效果和药水是两回事,当创建了药水类型后,创造模式药水栏里将会自动添加该药水类型的普通型/喷溅型/滞留型的药水瓶武器栏里会自动添加对应效果的弓箭。喝下一种药水可以获得多种状态效果,因此药水类型可以接收多个状态效果参数:

    在PotionLoader里添加事件:

    @SubscribeEvent
    public static void registerPotionType(RegistryEvent.Register<PotionType> event){
        event.getRegistry().register(new PotionType(new PotionEffect(injure, 600, 0)).setRegistryName("mymod:injuring"));
    }
    

    其中药水类型的构造器,乱七八糟的变量名大概是MCP项目没有翻译出来?

    public PotionType(@Nullable String p_i46740_1_, PotionEffect... p_i46740_2_)
    public PotionType(PotionEffect... p_i46739_1_)
    
    • String 类型的参数可以省略,相当于非本地化名称,如果省略或者填 null,自动用注册名作为非本地化名称。
    • PotionEffect 类型的参数是一个可变长参数,代表药水触发的一个或多个状态效果。

    状态效果实例的构造器 public PotionEffect(Potion potionIn, int durationIn, int amplifierIn)

    分别表示状态效果类型、持续游戏刻数、药水等级(0为Ⅰ级),可省略后两个参数(默认为0)。其中 Minecraft 中每秒20刻。

    由于有普通型/喷溅型/滞留型三种药水瓶以及药水效果的弓箭,非本地化键也相应的有 potion.effect./splash_potion.effect./ingering_potion.effect./tipped_arrow.effect. 四个前缀,也就是说创建一个药水类型,在.lang语言文件里要写四条翻译文本。

    添加状态效果的实际作用

    和附魔不太一样的地方,状态效果并不全都需要在需要的事件监听里独立写逻辑。总结一下,状态效果有三大类:

    • 修改状态属性类,比如迟缓/失明/挖掘疲劳/急迫等等,这些是一种对生物自身属性的更改,在构造器里使用 this.registerPotionAttributeModifier()

      public Potion registerPotionAttributeModifier(IAttribute attribute, String uniqueId, double ammount, int operation)
      
      • attribute 修改的生物自身属性,可使用 SharedMonsterAttributes 类中的字段
      • uniqueId UUID,暂不清楚,参考原版 net/minecraft/potion/Potion.java (432行) 中写的的参数。
      • ammount 调整数量,比如-1.0D
      • operation 暂不清楚,参考原版 Potion 类中写的的参数。
    • 周期性效果类,比如中毒/凋零,这样的状态效果通过重写 performEffect()isReady() 实现:

      @Override
      public void performEffect(EntityLivingBase entityLivingBaseIn, int amplifier) {
          entityLivingBaseIn.attackEntityFrom(DamageSource.MAGIC, 6.0f);
      }
      @Override
      public boolean isReady(int duration, int amplifier) {
          int j = 25 >> amplifier;
          if (j > 0) { return duration % j == 0;} 
          else { return true;}
      }
      
      • performEffect() 中写你想周期性触发的任何事情。这里写的意思是生物受到6点魔法(药水)伤害。除了上面写的掉血,你还可以触发爆炸来实现人肉轰炸等等。
      • amplifier 指的是药水等级,0为Ⅰ级
      • isReady() 中控制触发周期,比如上面就是原版的中毒状态的代码
    • 其他效果类,比如 ustc_zzzz 教程中的摔落保护效果,属于事件触发,需要监听事件,这里就不展开了,之后再说。

    药水合成表

    使用 BrewingRecipeRegistry.addRecipe() 创建,同样可以把这个写在上一篇的 Recipes 类构造器里。

    public static boolean addRecipe(ItemStack input, ItemStack ingredient, ItemStack output)
    
    • input 药水瓶的位置
    • ingredient 地狱疣/火药等配方的位置
    • output 产物
  • 相关阅读:
    Linux基础-yum软件包管理
    Linux基础-rpm软件包管理
    Linux基础-简单的进程操作
    Linux基础-free窥内存-dd探硬盘
    Linux基础-swap交换分区
    Linux基础-软硬连接Block概念
    Linux基础操作-分区概念
    Linux基础-vim编辑器
    Linux基础操作命令-打包压缩
    RandomAccessFile 文件读写中文乱码解决方案!
  • 原文地址:https://www.cnblogs.com/moonfan/p/12384364.html
Copyright © 2011-2022 走看看