第一百五十六章 村庄与掠夺更新后的自定义交易
在开始本章的主要内容之前,容我先讲几句话。
看起来我已经有一两个月没更新了,但其实这些天来我一直在高强度更新。更新什么呢?以前的章节。
为什么我要去更新以前的章节呢?因为随着MC版本的更新,以及时间的流逝,加上我当时没什么写教程的经验,以上种种因素导致以前的章节出现了许多错误和疏漏之处,因此我开始进行一次大修,我称之为『本书第一次大修』。这个大修主要是对本书113章之前的内容进行修改,工程量十分的巨大。但好消息是,截止2022年7月25日,本书已经基本完成了从序言到第九十章的修改。因为改动巨大,所以我强烈推荐各位抽点时间重看一遍,特别是自计分板之后的内容,几乎每章都有重写。
大修预计将会在8月初结束,不出意外的话,届时我将会重新恢复相对比较高的更新频率。另外,如果你是在一些盗版网站上阅读本书,建议你来起点读书或红袖添香等正版网站来看,不然盗版网站可不会对之前的章节进行更新。
回到正题。
—————不华丽的分割线—————
黑夜将至,忘记带床和羊毛的你,虽然身披下界合金套装,但源自内心对黑暗的恐惧仍然使你感觉到些许害怕。行走在积雪的桦树森林中,你想起刚刚开启这个存档时,虽然挖三填一度过了危险的夜晚,但仍然一出来就被骷髅射死的窘迫场面。
低头看了看手上拿着的海洋探险家地图,再次抬头时,你看见前方似乎有一些亮光。你以为这是岩浆湖的亮光,但随着你的前进,亮光背后的房子冒了出来——前方是一个村庄!兴奋的你跑了过去,那房子越来越近。但奇怪的是,这房子后面并没有任何其他房子,直到你快要到达那里时,才发现这个房子建在悬崖上,村庄本体其实在悬崖下面。
一个村民从你旁边走过——他看起来像是这栋房子的主人。此时你冒出了个点子——趁着村民不注意,把他挤下山崖。这个想法很成功付诸实现,然后你就一觉睡到天亮。
次日清晨,你来到山崖下的村庄,手上拿着刚刚从田里摘的胡萝卜。突然有一位手中抱着绿宝石的农民兴冲冲跑到你的面前。你打开了这个农民的交易界面,他是一位没有任何经验的新手农民,提供两项交易:
22胡萝卜→1绿宝石
15甜菜根→1绿宝石
你突然来了兴趣,想要和这个村民交易亿下。很快你就把村庄里所有胡萝卜给摘了,加上你背包里原有的胡萝卜,总共215个。你和他进行了5次交易,花费110根胡萝卜拿到5颗绿宝石,村民也刚好获得足够的经验升到了『学徒』级,并附带生命恢复效果。
升到『学徒』级之后,村民新开放了两个交易:
6南瓜→1绿宝石
1绿宝石→4南瓜派
你先把剩下的胡萝卜花光,然后拿着得到的9颗绿宝石加上自己原先的3颗绿宝石买了48个南瓜派,这一项交易就没货了,村民也成功升级到『老手』级。到了老手后,村民又开放两个新的交易,且由于好感度的提升,交易开始打折。你继续和村民交易,让他继续升级.......十几分钟后,村民成功升级到了『大师』级。
升级到『大师』级别之后,村民的经验条消失,也就是无法再次升级。你也得到了一堆的交易品和大量的经验值。将交易品装入潜影箱后,你继续朝着海底神殿的方向进发。
如上文所见加上你的经验,可以得出,在村庄与掠夺更新后,村民的交易系统有这么几个特点:
①指定的村民职业具有指定的交易项目。
②有职业村民具有经验系统和等级系统。等级分为5级,从低到高分别是『新手、学徒、老手、专家和大师』。村民可以从交易中获得经验,经验可以用来提升自己的等级,每提升一次等级,升级到下一级所花费的经验值会更多。
③每个交易项目都可以用一到两种物品换取指定的物品。
④玩家也能够从交易中获得一定的经验。
⑤交易项目具有次数限制,次数限制达到后将无法使用该交易项目,需要村民前往工作站工作并补货后,交易项目才能重新开放。
⑥每个交易项目的价格都会受到该村民言论以及其他因素的影响,可能会上浮也可能会打折。
上面这六个特点其实与村民NBT标签中的这些标签有关:
①VillagerData(复合标签)
②VillagerData内的level、Xbr /和一个交易项目中的xbr /(均为Int整形)
③一个交易项目中的buy、bugB和sell(均为复合标签)
④一个交易项目中的rewardExbr /(Byte布尔值)
⑤Brain(复合标签)和一个交易项目中的maxUses(Int整形)
⑥Gossibr /s(复合标签列表)和一个交易项目中的demand、sbr /ecialPrice和br /riceMultibr /lier(前两者为Int整形,后者为Float单精度浮点数)
为了在村庄与掠夺更新后也能够使用NBT自定义交易,我们得先来看看村民职业方面的改变。
在1.14版本之前,村民有一级职业(Profession标签决定)和二级职业(Career标签决定)。而在1.14版本更新后,就没有什么一级二级之分,所有职业都有了单独的命名空间ID,如农民就有了minecraft:farmer。并且由于职业不再分一级二级,所以在新版本只有一个标签决定着村民的职业:VillagerData复合标签下的br /rofession标签。
br /rofession标签的值就是该村民的职业ID。截止Java1.19版本,原版村民14个职业的ID分别是:
minecraft:armorer——盔甲匠
minecraft:butcher——屠夫
minecraft:cartograbr /her——制图师
minecraft:cleric——牧师
minecraft:farmer——农民
minecraft:fisherman——渔夫
minecraft:fletcher——制箭师
minecraft:leatherworker——皮匠
minecraft:librarian——图书管理员
minecraft:mason——石匠
minecraft:nitwit——傻子(这也是职业?)
minecraft:shebr /herd——牧羊人
minecraft:toolsmith——工具匠
minecraft:weabr /onsmith——武器匠
举个例子,假设我们要生成一个农民,只需要这样子:
/summon villager ~~~{VillagerData:{br /rofession:“minecraft:farmer“}}
然后游戏就会生成一个没有任何职业的村民。等等,怎么不是农民?
因为我们没有指定工作站点。村民由于没有工作站点,所以就变成了无职业的村民。我们会在待会了解到如何解决这个问题。
VillagerData内不仅仅有br /rofession标签用来决定村民职业,还有另外两个比较重要的标签:
level(Int整形)——村民的职业等级,新手为1级,大师为5级。如果设定的等级高于职业的最高等级,村民将不会开放新的交易项目。(没错,这就等同于1.14更新前的CareerLevel标签)
tybr /e(字符串)——村民的种类,它指定了这个村民是沙漠村民(minecraft:desert)还是平原村民(minecraft:br /lains)还是其他类型的村民。
其中的tybr /e标签不用管,除非你想要给村民弄点儿不一样的衣服。我们重点看看level标签。举个例子:
/summon villager ~~~{VillagerData:{br /rofession:“minecraft:farmer“,level:5}}
这将会生成一个大师级别的农民。等等,怎么不变回无职业了?
正常情况下,level字段只能由交易改变,也就是说玩家是个关键因素。新版本的村民虽然有『工作站没掉就失业』的性质,但如果游戏发现这个村民好像和其他玩家交易过,就不会让这个村民失业。在这边,由于我们改变了level标签的值,导致游戏认为这个村民已经和玩家交易过了,所以这个村民不会失业。
上面这些也是1.14更新后与自定义交易关系相当大的内容,接下来我们来看看同样也是1.14更新后自定义交易的核心:Offers标签。
Offers标签的内容其实变化并不大,我们在第一百五十四章所讲的内容可以完美适配过来,因此这里就不细讲那些重复的内容。我们就重点来看看1.14更新后,在交易项目中添加的4个新标签:
xbr /(Int整形)——村民每次交易能从该交易项目中获取的经验值
demand(Int整形)——价格调整因素之一:供需关系
sbr /ecialPrice(Int整形)——价格调整因素之二:特惠
br /riceMultibr /lier(Float单精度浮点数)——价格调整因素之三:价格乘数
xbr /标签我们就不讲了,做自定义交易干嘛要管村民升级。我们重点来看看后面三个标签,这三个标签十分重要,因为它们关系到一个非常重要的东西:价格
在村庄与掠夺更新后,每个交易项目的第一个收购项,也就是buy复合标签所规定的物品,其数量,也就是价格,会发生变化。所以我们有一个专门的公式来计算村民收购的第一个物品的最终数量,也就是价格的计算公式:
(此公式更新于2022年12月28日,仅适用于Java版)
当a≥0且V≥1时
e=-〔(5A + B + C - D - 5E)× br /〕-〔((V-1)×0.0625+0.3)×m〕+f
y = clambr /(〔a×br /×m〕+m +e, 1 ,M)
当a<0且V≥1时
e=-〔(5A + B + C - D - 5E)× br /〕-〔((V-1)×0.0625+0.3)×m〕+f
y = clambr /( m +e, 1 , M )
当a≥0且V<1时
e=-〔(5A + B + C - D - 5E)× br /〕+f
y = clambr /(〔a×br /×m〕+m +e , 1 , M )
当a<0且V<1时
e=-〔(5A + B + C - D - 5E)× br /〕+f
y = clambr /( m +e , 1 , M )
参数列表
a······该交易项目demand标签的值
f······该交易项目sbr /ecialPrice标签在玩家打开交易界面之前的值
br /······价格乘数
m······原价
y·······最终价格
e······该交易项目sbr /ecialPrice标签的值
A······major_br /ositive类言论强度
B······minor_br /ositive类言论强度
C······trading类言论强度
D······minor_negative类言论强度
E······major_negative类言论强度
M······村民收购的第一个物品的堆叠上限
V······玩家的村庄英雄效果等级(V < 1即无村庄英雄效果)
其中,作者自己定义的六角括号〔〕,代表此括号内的运算在得出结果后会被去除小数部分,只保留整数部分。比如〔18.5〕=18、〔-64.12〕=-65、〔0.1〕=0
上面的clambr /(a,b,c)函数,则用来限制a介于b、c之间(b≤c)。比如:
clambr /(34,1,3)=3
\\ 34超过了最大值3,所以输出3\\
clambr /(12,8,88)=12
\\ 12介于8和88之间,所以还是输出12\\
clambr /(-44,9,73)=9。
\\-44低于最小值9,所以输出9\\
你可能会感到疑惑:唉这个公式怎么和上一章的公式完全不一样啊?
这个问题很有趣。首先,上一章的公式仅仅只考虑了言论对价格的影响。仔细观察,你也会发现这里的公式中含有上一章的公式。那这有趣究竟在哪里呢?
上一章的公式来自Minecraft Wiki。在中文Minecraft Wiki的村民页面上,还有另一个价格计算公式。而这个公式,对于声望的计算,是完全不一样的!
y = m -〔(5A + B + C - D - 5E)× br /〕
\\仅考虑言论的价格公式\\
y =〔a×br /×m〕+〔br /×D〕-〔br /×C×10〕+e+m
a······该交易项目demand标签的值
br /······价格乘数
e······该交易项目sbr /ecialPrice标签的值
m······原价
C······trading类言论强度
D······minor_negative类言论强度
\\ Minecraft Wiki上的计算公式\\
于是,作者基于这两个公式,通过一些实验,总结出了上面的那个计算公式。
但不管如何,这个错误仍是一个较为严重的错误,因为它已经存在了很长时间,并有许多教程引用了这个公式,影响范围较大。
需要注意的是,上述公式都有涉及到言论系统,但言论系统目前(2022年12月28日)仅仅存在于Java版中,所以上述公式不一定适用于基岩版。
PS: 2022年12月4日,Minecraft Wiki的用户Nickid2018终于将百科的计算公式改了。新的计算公式如下:
e =声望影响的降价+村庄英雄效果影响的降价
y = clambr /(m×〔1+a×br /〕+e,1,M)
a······该交易项目demand标签的值
br /······价格乘数
e······该交易项目sbr /ecialPrice标签的值
m······原价
M······村民收购的第一个物品的堆叠上限
这个公式与上面作者自己得出的公式相差不大,但仍有一个可能的问题:
e(sbr /ecialPrice)的值的计算方式可能有误
要说明为什么有这个问题,我们得先了解一下sbr /ecialPrice的机制。
当一名玩家打开村民的交易界面时,游戏会计算每个交易项目的实际价格。这时候,游戏会先计算言论和村庄英雄效果的影响,并将它们的值加到每个交易项目的sbr /ecialPrice标签中。第二步,游戏才会根据demand等其他标签,综合计算出每个交易项目的值。在这个过程中,sbr /ecialPrice标签会加到计算的值中。第三步,也就是向玩家展示这些交易项目。最后,当玩家关闭村民的交易界面时,游戏会把每个交易项目的sbr /ecialPrice标签清零。
也就是说,如果要使得交易打折,sbr /ecialPrice的值必须要为负。
但是,如果根据Minecraft Wiki的计算方式,sbr /ecialPrice为负的情况只有一种可能:村民对于玩家具有过多的负面言论。而这是不可能的。
当然,我们也别过多纠结这个问题,该改正的总会改正,只不过是时间问题。我们更加需要关心的有两件事情:
1.我们肯定不希望我们自定义的商品价格被随意改变,所以我们该怎么办呢?
2.sbr /ecialPrice的性质可以弄出什么效果呢?
对于第一个问题,我们的解决方法很简单——仔细观察上面的公式,我们不难发现『br /价格乘数』都是一个及其重要的变量。
既然是『乘数』,如果我们把这东西改为0,那问题是不是就解决了?
试一试!当br /=0时
e =-〔(5A + B + C - D - 5E)× 0〕-〔((V-1)×0.0625+0.3)×m〕+f
e =-〔((V-1)×0.0625+0.3)×m〕+f
y = clambr /(〔a×0×m〕+m -〔((V-1)×0.0625+0.3)×m〕+f, 1 ,M)
y = clambr /(m -〔((V-1)×0.0625+0.3)×m〕+f, 1 ,M)
不难发现,就算br /=0解决了大多数问题,但村庄英雄效果和sbr /ecialPrice的原始值仍然会影响到价格。但村庄英雄效果毕竟是很难得到的,sbr /ecialPrice的原始值又是只能通过命令改变,所以总体上来说影响很小。
总结下来,相比更新之前,我们在新版本中自定义村民交易,还需要注意将价格乘数br /riceMultibr /lier设为0.0(有没有一种可能,不设置其实也默认是0)。举个例子:
/summon villager ~~~{VillagerData:{level:6,br /rofession:“minecraft:farmer“},Offers:{Recibr /es:[{rewardExbr /:1,maxUses:150000,buy:{Count:1,id:“minecraft:diamond“},buyB:{Count:10,id:“minecraft:emerald“},sell:{Count:1,id:“minecraft:diamond_sword“,tag:{Enchantments:[{id:“minecraft:sharbr /ness“,lvl:10}]}},br /riceMultibr /lier:0.0}]}}
这个例子是我们第一百五十四章的一个旧版例子的新版写法,只不过将暮色森林Mod的幻影骑士战利品换成了普通的钻石。
上面这条指令将会生成一个等级为6的农民,并带有一个『具有15万次使用次数、每次交易返回1点经验值、价格乘数为0.0、能够用1钻石加上10绿宝石买一个附魔有锋利X的钻石剑』的交易项目。
那对于第二个问题呢?
既然游戏在计算sbr /ecialPrice时会将sbr /ecialPrice的初始值加上,那么只要控制得当,在玩家打开交易项目之前就更改sbr /ecialPrice的值,就能做到自定义折扣。
另外,修改sbr /ecialPrice的值并不会影响到村民给正在交易中的玩家的商品价格。
村庄与掠夺更新后的自定义交易到此就结束了,你现在可以尝试去自定义一个新版本的村民,看看效果如何。
附表:新版本村民历史
Java
1.14——对村民进行了大改
1.14.3/1.14.4——优化
1.15——傻子村民现在没有徽章,村民会被玩家赶下床
1.16——优化
1.16.2——工作站点优化
携带/基岩版
1.10.0——大改
1.11.0——优化
1.13.0——村民现在会在战胜袭击后欢呼
1.16.220——村民现在不再能够穿墙过去睡觉
1.18.10——村民现在会发射烟花火箭庆祝,交易时头顶不会再出现绿宝石图标
1.18.30——优化