浅谈CNPC脚本1.7与1.8+脚本的区别
底层实现
在谈论它们的区别之前,我们首先要知道脚本是如何实现的
CNPCmod在Forge订阅了一些事件,或者是通过覆写方法之类的手段,总之使得它可以在需要的时候运行自己自定义的代码,但这些代码大多数与脚本无关,CNPCmod在自己内部已经处理完了东西,不给你的机会。
但是,有一部分情况例外,那便是CNPCmod手动向你发来了事件,这便是触发脚本的时候。
CNPC用容器,储存你写的脚本的文本信息,然后在关键时候调用脚本,我描述一下大致发生了什么:
CNPC觉得应该发生什么->CNPC访问了容器->CNPC用脚本引擎调用了脚本
虽然好似容器并没有提及的必要,但这对于1.8+和1.7有很大区别。
容器
总所周知的是,1.7只能依赖实体NPC写脚本,1.12有player和forge框的同时在NPC上写脚本,这是容器的区别。
对于1.12,player框,forge框,NPC框,它们各自有自己的容器,事实上,它们底层的结构是这样的:
单个玩家-脚本控制器-复数的脚本容器(每一个意味着一个框)
单个NPC-脚本控制器-复数的脚本容器
单个存档(服务端)-脚本控制器-复数的脚本容器
而1.7,我没有具体看源码,但你可以以此想象它是怎么样的结构。
函数与钩子
在大多数人的感受中,1.8+与1.7最大的变化就是钩子函数化了,我大概讲一下到底发生了什么。
对于1.7而言,一个脚本框其实就相当于一个大的函数,当你写下npc,player,event,这些你不用任何额外操作就可以直接调用的变量时,就相当于调用了一个函数的参数。
我写一段并不能执行,但是可以反应1.7与1.12区别的代码:

理解了1.7的实质,你就大概可以理解1.12了
不过与1.7还有一点不同的是:
对于1.7而言,event是一个额外参数,负责提供某个事件才能发生的特殊功能,或者取消这个发生的事件。
对于1.12而言,event是所有参数的“包装盒”,像是1.7直接调用的npc和player,你都要通过调用event字段获取。
另外,1.7的“函数参数”是硬命名,event你必须写全event,player你必须写全player,但是1.12的真函数中,参数名你是可以自己定义的,参数名没有任何意义,它相当于一个变量,只是指向了传入函数的事件对象。

不过函数名必须正确,因为CNPCmod层是根据函数名调用函数,而不是其他任何东西。