NeoForge-1.20.4Mod开发教程之村民交易

本篇教程参考为Flandre芙兰的NeoForge1.20.4Mod开发的视频,这篇教程是我边学边总结的,与其说是教程更像我的学习笔记,如有不清楚的地方,大家可以在评论区提问。在我力所能及的范围内,我都会解答的。

POI机制

在《我的世界》中,村民的兴趣点(POI, Point of Interest)是指那些村民会去关注、认领或记住的特殊方块或位置(比如工作站方块、床、钟等),这些 POI 决定了村民的职业、上班地点、睡觉位置和日常行为:村民会寻找未被占用的工作站来认领并成为对应职业,会回到自己的床睡觉,也会围绕这些 POI 按日程活动,从而形成真实的生活习惯。POI 在 AI 系统里用于让村民识别和前往目标位置,是村庄运作的核心机制

因此我们想让村民有新职业首先得有新的兴趣点

 

创建ModVillagers类

public class ModVillagers {
     public static final DeferredRegister<PoiType> POI_TYPES=//兴趣点注册器
             DeferredRegister.create(Registries.POINT_OF_INTEREST_TYPE, ExampleMod.MODID);
 ​
     public static final DeferredRegister<VillagerProfession> VILLAGER_PROFESSIONS=//村民职业注册器
             DeferredRegister.create(Registries.VILLAGER_PROFESSION, ExampleMod.MODID);
 ​
     public static final Supplier<PoiType> RUBY_BLOCK_POI=POI_TYPES.register("ruby_block_poi",//新建兴趣点
            ()->new PoiType(ImmutableSet.copyOf(ModBlocks.RUBY_BLOCK.get().getStateDefinition().getPossibleStates()),1,1));//第一个1是同时占用的数量上限,第二个1是村民在多远的范围(方块)内可以识别这个 POI
     public static final Predicate<Holder<PoiType>> IS_RUBY_BLOCK_POI= poi->poi.value()==RUBY_BLOCK_POI.get();//检测兴趣点是不是我们需要的
 ​
     public static final Supplier<VillagerProfession> RUBY_MASTER =VILLAGER_PROFESSIONS.register("ruby_master",//新建职业
            ()->new VillagerProfession("ruby_master",IS_RUBY_BLOCK_POI,IS_RUBY_BLOCK_POI,
                     ImmutableSet.of(),ImmutableSet.of(), SoundEvents.VILLAGER_WORK_ARMORER));
 ​
 ​
     public static void register(IEventBus eventBus) {
         POI_TYPES.register(eventBus);
         VILLAGER_PROFESSIONS.register(eventBus);
    }
 }

 

添加交易

public class AddVillagerTrades {
     @Mod.EventBusSubscriber(modid = ExampleMod.MODID)
     public static class ForgeEvents {
         @SubscribeEvent
         public static void addVillagerTrades(VillagerTradesEvent event) {//监听交易事件
             int villagerLevel1 = 1;//村民等级,最高5级
             int villagerLevel2 = 2;
             if (event.getType() == VillagerProfession.ARMORER) {//给原版盔甲匠添加交易物品
                 Int2ObjectMap<List<VillagerTrades.ItemListing>> ARMORER_TRADES = event.getTrades();//得到该职业的交易列表
                 ItemStack magic_ingot_stack = new ItemStack(ModItems.MAGIC_INGOT.get(), 1);
 ​
                 ARMORER_TRADES.get(villagerLevel1).add((trader, random) -> new MerchantOffer(
                         new ItemStack(Items.EMERALD, 2),//两个绿宝石换一个魔法锭
                         magic_ingot_stack, 10, 8, 0//10为最大交易数,8为经验值,0为价格浮动乘数
                ));
            }
 ​
             if (event.getType() == ModVillagers.RUBY_MASTER.get()) {//给模组的村民添加交易
                 Int2ObjectMap<List<VillagerTrades.ItemListing>> RUVY_MASTER_TRADES = event.getTrades();
                 ItemStack ruby_stack = new ItemStack(ModItems.RUBY.get(),3);
 ​
                 RUVY_MASTER_TRADES.get(villagerLevel1).add((trader, random) -> new MerchantOffer(
                         new ItemStack(Items.EMERALD, 2),
                         ruby_stack, 10, 8, 0
                ));
            }
        }
    }
 }

 

添加兴趣点json

在原版的tags下新建point_of_interest_type目录,并创建acquirable_job_site.json

{
   "values": [
     "examplemod:ruby_block_poi"
  ]
 }

 

类介绍

PoiType

这个类用于定义某类 POI 所对应的方块状态(BlockState)集,指定这个兴趣点最多可以被多少村民“认领”和定义这个兴趣点的有效作用范围(AI 搜索范围)

PoiTypes

它提供游戏中所有兴趣点类型的引用位置,让你的 mod 可以根据需要使用现有的 POI 类型(例如用来定义职业对应的工作站)

VillagerProfession

它用于定义村民职业的行为、兴趣点以及交易/AI 特性

heldJobSite 用来判断村民是否持有该职业的工作站 POI

acquirableJobSite 用来判断哪些 POI 类型可以让这个职业被激活

requestedItems 是这个职业可能需要或收集的物品集合(通常为空)

secondaryPoi 是职业相关的额外兴趣点(如休息点、辅助站点等)

workSound 是职业村民在工作时播放的声音

© 版权声明
THE END
喜欢就支持一下吧
点赞6赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容