我的世界1.20.1模组开发---13.添加新的附魔
介绍
最近备战期末,又逢放假,休息了一阵子没有更新,这次来介绍一些有趣的东西,那就是游戏中的附魔系统。游戏中可以对我们的装备、武器和工具在附魔台上进行附魔,旁边还可以放书架来提升可附魔等级,当年第一次见到这个玩法的时候就吸引到我了,感觉附魔系统还挺有趣的,这次我们就好好说一说mod中怎么添加新的附魔效果。
在游戏中附魔的英文叫做enchantment
,所以我们在看源码的时候也可以往这个方向靠靠,我们先找到enchantment
类,这是所有附魔效果的父类,我们在这个单词上面按下CTRL+H
快捷键(IDEA中)就可以看到这个类的父子关系,如下图所示。可以看到,原版中的所有附魔效果都要继承这个类,因此我们新建一个附魔类的时候也要继承这个类。因为附魔效果与Item
和Block
不算是同一类别的对象,所以我们的附魔效果要想物品和方块一样新建一个注册的类,用来把我们的附魔放到注册表中,写法都和那两者一样,下面就来详细说明一下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
方法不管怎么写都会执行两次,目前我还无法解决。方法里有三个参数,第一个参数是攻击者,第二个参数是被攻击的实体,第三个参数是该附魔的等级,有了这些参数我们就可以对目标进行一些处理,比如加大攻击力,让它飞起来等等操作,下面上代码。
代码
首先和之前的Item和Block一样,我们需要新建一个注册类,用来注册所有的附魔,我们在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)。