第一百五十六章 村莊與掠奪更新后的自定義交易
在開(kāi)始本章的主要內(nèi)容之前,容我先講幾句話。
看起來(lái)我已經(jīng)有一兩個(gè)月沒(méi)更新了,但其實(shí)這些天來(lái)我一直在高強(qiáng)度更新。更新什么呢?以前的章節(jié)。
為什么我要去更新以前的章節(jié)呢?因?yàn)殡S著MC版本的更新,以及時(shí)間的流逝,加上我當(dāng)時(shí)沒(méi)什么寫(xiě)教程的經(jīng)驗(yàn),以上種種因素導(dǎo)致以前的章節(jié)出現(xiàn)了許多錯(cuò)誤和疏漏之處,因此我開(kāi)始進(jìn)行一次大修,我稱(chēng)之為『本書(shū)第一次大修』。這個(gè)大修主要是對(duì)本書(shū)113章之前的內(nèi)容進(jìn)行修改,工程量十分的巨大。但好消息是,截止2022年7月25日,本書(shū)已經(jīng)基本完成了從序言到第九十章的修改。因?yàn)楦膭?dòng)巨大,所以我強(qiáng)烈推薦各位抽點(diǎn)時(shí)間重看一遍,特別是自計(jì)分板之后的內(nèi)容,幾乎每章都有重寫(xiě)。
大修預(yù)計(jì)將會(huì)在8月初結(jié)束,不出意外的話,屆時(shí)我將會(huì)重新恢復(fù)相對(duì)比較高的更新頻率。另外,如果你是在一些盜版網(wǎng)站上閱讀本書(shū),建議你來(lái)起點(diǎn)讀書(shū)或紅袖添香等正版網(wǎng)站來(lái)看,不然盜版網(wǎng)站可不會(huì)對(duì)之前的章節(jié)進(jìn)行更新。
回到正題。
—————不華麗的分割線—————
黑夜將至,忘記帶床和羊毛的你,雖然身披下界合金套裝,但源自?xún)?nèi)心對(duì)黑暗的恐懼仍然使你感覺(jué)到些許害怕。行走在積雪的樺樹(shù)森林中,你想起剛剛開(kāi)啟這個(gè)存檔時(shí),雖然挖三填一度過(guò)了危險(xiǎn)的夜晚,但仍然一出來(lái)就被骷髏射死的窘迫場(chǎng)面。
低頭看了看手上拿著的海洋探險(xiǎn)家地圖,再次抬頭時(shí),你看見(jiàn)前方似乎有一些亮光。你以為這是巖漿湖的亮光,但隨著你的前進(jìn),亮光背后的房子冒了出來(lái)——前方是一個(gè)村莊!興奮的你跑了過(guò)去,那房子越來(lái)越近。但奇怪的是,這房子后面并沒(méi)有任何其他房子,直到你快要到達(dá)那里時(shí),才發(fā)現(xiàn)這個(gè)房子建在懸崖上,村莊本體其實(shí)在懸崖下面。
一個(gè)村民從你旁邊走過(guò)——他看起來(lái)像是這棟房子的主人。此時(shí)你冒出了個(gè)點(diǎn)子——趁著村民不注意,把他擠下山崖。這個(gè)想法很成功付諸實(shí)現(xiàn),然后你就一覺(jué)睡到天亮。
次日清晨,你來(lái)到山崖下的村莊,手上拿著剛剛從田里摘的胡蘿卜。突然有一位手中抱著綠寶石的農(nóng)民興沖沖跑到你的面前。你打開(kāi)了這個(gè)農(nóng)民的交易界面,他是一位沒(méi)有任何經(jīng)驗(yàn)的新手農(nóng)民,提供兩項(xiàng)交易:
22胡蘿卜→1綠寶石
15甜菜根→1綠寶石
你突然來(lái)了興趣,想要和這個(gè)村民交易億下。很快你就把村莊里所有胡蘿卜給摘了,加上你背包里原有的胡蘿卜,總共215個(gè)。你和他進(jìn)行了5次交易,花費(fèi)110根胡蘿卜拿到5顆綠寶石,村民也剛好獲得足夠的經(jīng)驗(yàn)升到了『學(xué)徒』級(jí),并附帶生命恢復(fù)效果。
升到『學(xué)徒』級(jí)之后,村民新開(kāi)放了兩個(gè)交易:
6南瓜→1綠寶石
1綠寶石→4南瓜派
你先把剩下的胡蘿卜花光,然后拿著得到的9顆綠寶石加上自己原先的3顆綠寶石買(mǎi)了48個(gè)南瓜派,這一項(xiàng)交易就沒(méi)貨了,村民也成功升級(jí)到『老手』級(jí)。到了老手后,村民又開(kāi)放兩個(gè)新的交易,且由于好感度的提升,交易開(kāi)始打折。你繼續(xù)和村民交易,讓他繼續(xù)升級(jí).......十幾分鐘后,村民成功升級(jí)到了『大師』級(jí)。
升級(jí)到『大師』級(jí)別之后,村民的經(jīng)驗(yàn)條消失,也就是無(wú)法再次升級(jí)。你也得到了一堆的交易品和大量的經(jīng)驗(yàn)值。將交易品裝入潛影箱后,你繼續(xù)朝著海底神殿的方向進(jìn)發(fā)。
如上文所見(jiàn)加上你的經(jīng)驗(yàn),可以得出,在村莊與掠奪更新后,村民的交易系統(tǒng)有這么幾個(gè)特點(diǎn):
①指定的村民職業(yè)具有指定的交易項(xiàng)目。
②有職業(yè)村民具有經(jīng)驗(yàn)系統(tǒng)和等級(jí)系統(tǒng)。等級(jí)分為5級(jí),從低到高分別是『新手、學(xué)徒、老手、專(zhuān)家和大師』。村民可以從交易中獲得經(jīng)驗(yàn),經(jīng)驗(yàn)可以用來(lái)提升自己的等級(jí),每提升一次等級(jí),升級(jí)到下一級(jí)所花費(fèi)的經(jīng)驗(yàn)值會(huì)更多。
③每個(gè)交易項(xiàng)目都可以用一到兩種物品換取指定的物品。
?、芡婕乙材軌驈慕灰字蝎@得一定的經(jīng)驗(yàn)。
⑤交易項(xiàng)目具有次數(shù)限制,次數(shù)限制達(dá)到后將無(wú)法使用該交易項(xiàng)目,需要村民前往工作站工作并補(bǔ)貨后,交易項(xiàng)目才能重新開(kāi)放。
⑥每個(gè)交易項(xiàng)目的價(jià)格都會(huì)受到該村民言論以及其他因素的影響,可能會(huì)上浮也可能會(huì)打折。
上面這六個(gè)特點(diǎn)其實(shí)與村民NBT標(biāo)簽中的這些標(biāo)簽有關(guān):
①VillagerData(復(fù)合標(biāo)簽)
?、赩illagerData內(nèi)的level、Xp和一個(gè)交易項(xiàng)目中的xp(均為Int整形)
③一個(gè)交易項(xiàng)目中的buy、bugB和sell(均為復(fù)合標(biāo)簽)
④一個(gè)交易項(xiàng)目中的rewardExp(Byte布爾值)
?、軧rain(復(fù)合標(biāo)簽)和一個(gè)交易項(xiàng)目中的maxUses(Int整形)
⑥Gossips(復(fù)合標(biāo)簽列表)和一個(gè)交易項(xiàng)目中的demand、specialPrice和priceMultiplier(前兩者為Int整形,后者為Float單精度浮點(diǎn)數(shù))
為了在村莊與掠奪更新后也能夠使用NBT自定義交易,我們得先來(lái)看看村民職業(yè)方面的改變。
在1.14版本之前,村民有一級(jí)職業(yè)(Profession標(biāo)簽決定)和二級(jí)職業(yè)(Career標(biāo)簽決定)。而在1.14版本更新后,就沒(méi)有什么一級(jí)二級(jí)之分,所有職業(yè)都有了單獨(dú)的命名空間ID,如農(nóng)民就有了minecraft:farmer。并且由于職業(yè)不再分一級(jí)二級(jí),所以在新版本只有一個(gè)標(biāo)簽決定著村民的職業(yè):VillagerData復(fù)合標(biāo)簽下的profession標(biāo)簽。
profession標(biāo)簽的值就是該村民的職業(yè)ID。截止Java1.19版本,原版村民14個(gè)職業(yè)的ID分別是:
minecraft:armorer——盔甲匠
minecraft:butcher——屠夫
minecraft:cartographer——制圖師
minecraft:cleric——牧師
minecraft:farmer——農(nóng)民
minecraft:fisherman——漁夫
minecraft:fletcher——制箭師
minecraft:leatherworker——皮匠
minecraft:librarian——圖書(shū)管理員
minecraft:mason——石匠
minecraft:nitwit——傻子(這也是職業(yè)?)
minecraft:shepherd——牧羊人
minecraft:toolsmith——工具匠
minecraft:weaponsmith——武器匠
舉個(gè)例子,假設(shè)我們要生成一個(gè)農(nóng)民,只需要這樣子:
/summon villager ~~~{VillagerData:{profession:“minecraft:farmer“}}
然后游戲就會(huì)生成一個(gè)沒(méi)有任何職業(yè)的村民。等等,怎么不是農(nóng)民?
因?yàn)槲覀儧](méi)有指定工作站點(diǎn)。村民由于沒(méi)有工作站點(diǎn),所以就變成了無(wú)職業(yè)的村民。我們會(huì)在待會(huì)了解到如何解決這個(gè)問(wèn)題。
VillagerData內(nèi)不僅僅有profession標(biāo)簽用來(lái)決定村民職業(yè),還有另外兩個(gè)比較重要的標(biāo)簽:
level(Int整形)——村民的職業(yè)等級(jí),新手為1級(jí),大師為5級(jí)。如果設(shè)定的等級(jí)高于職業(yè)的最高等級(jí),村民將不會(huì)開(kāi)放新的交易項(xiàng)目。(沒(méi)錯(cuò),這就等同于1.14更新前的CareerLevel標(biāo)簽)
type(字符串)——村民的種類(lèi),它指定了這個(gè)村民是沙漠村民(minecraft:desert)還是平原村民(minecraft:plains)還是其他類(lèi)型的村民。
其中的type標(biāo)簽不用管,除非你想要給村民弄點(diǎn)兒不一樣的衣服。我們重點(diǎn)看看level標(biāo)簽。舉個(gè)例子:
/summon villager ~~~{VillagerData:{profession:“minecraft:farmer“,level:5}}
這將會(huì)生成一個(gè)大師級(jí)別的農(nóng)民。等等,怎么不變回?zé)o職業(yè)了?
正常情況下,level字段只能由交易改變,也就是說(shuō)玩家是個(gè)關(guān)鍵因素。新版本的村民雖然有『工作站沒(méi)掉就失業(yè)』的性質(zhì),但如果游戲發(fā)現(xiàn)這個(gè)村民好像和其他玩家交易過(guò),就不會(huì)讓這個(gè)村民失業(yè)。在這邊,由于我們改變了level標(biāo)簽的值,導(dǎo)致游戲認(rèn)為這個(gè)村民已經(jīng)和玩家交易過(guò)了,所以這個(gè)村民不會(huì)失業(yè)。
上面這些也是1.14更新后與自定義交易關(guān)系相當(dāng)大的內(nèi)容,接下來(lái)我們來(lái)看看同樣也是1.14更新后自定義交易的核心:Offers標(biāo)簽。
Offers標(biāo)簽的內(nèi)容其實(shí)變化并不大,我們?cè)诘谝话傥迨恼滤v的內(nèi)容可以完美適配過(guò)來(lái),因此這里就不細(xì)講那些重復(fù)的內(nèi)容。我們就重點(diǎn)來(lái)看看1.14更新后,在交易項(xiàng)目中添加的4個(gè)新標(biāo)簽:
xp(Int整形)——村民每次交易能從該交易項(xiàng)目中獲取的經(jīng)驗(yàn)值
demand(Int整形)——價(jià)格調(diào)整因素之一:供需關(guān)系
specialPrice(Int整形)——價(jià)格調(diào)整因素之二:特惠
priceMultiplier(Float單精度浮點(diǎn)數(shù))——價(jià)格調(diào)整因素之三:價(jià)格乘數(shù)
xp標(biāo)簽我們就不講了,做自定義交易干嘛要管村民升級(jí)。我們重點(diǎn)來(lái)看看后面三個(gè)標(biāo)簽,這三個(gè)標(biāo)簽十分重要,因?yàn)樗鼈冴P(guān)系到一個(gè)非常重要的東西:價(jià)格
在村莊與掠奪更新后,每個(gè)交易項(xiàng)目的第一個(gè)收購(gòu)項(xiàng),也就是buy復(fù)合標(biāo)簽所規(guī)定的物品,其數(shù)量,也就是價(jià)格,會(huì)發(fā)生變化。所以我們有一個(gè)專(zhuān)門(mén)的公式來(lái)計(jì)算村民收購(gòu)的第一個(gè)物品的最終數(shù)量,也就是價(jià)格的計(jì)算公式:
?。ù斯礁掠?022年12月28日,僅適用于Java版)
當(dāng)a≥0且V≥1時(shí)
e=-〔(5A + B + C - D - 5E)× p〕-〔((V-1)×0.0625+0.3)×m〕+f
y = clamp(〔a×p×m〕+m +e, 1 ,M)
當(dāng)a<0且V≥1時(shí)
e=-〔(5A + B + C - D - 5E)× p〕-〔((V-1)×0.0625+0.3)×m〕+f
y = clamp( m +e, 1 , M )
當(dāng)a≥0且V<1時(shí)
e=-〔(5A + B + C - D - 5E)× p〕+f
y = clamp(〔a×p×m〕+m +e , 1 , M )
當(dāng)a<0且V<1時(shí)
e=-〔(5A + B + C - D - 5E)× p〕+f
y = clamp( m +e , 1 , M )
參數(shù)列表
a······該交易項(xiàng)目demand標(biāo)簽的值
f······該交易項(xiàng)目specialPrice標(biāo)簽在玩家打開(kāi)交易界面之前的值
p······價(jià)格乘數(shù)
m······原價(jià)
y·······最終價(jià)格
e······該交易項(xiàng)目specialPrice標(biāo)簽的值
A······major_positive類(lèi)言論強(qiáng)度
B······minor_positive類(lèi)言論強(qiáng)度
C······trading類(lèi)言論強(qiáng)度
D······minor_negative類(lèi)言論強(qiáng)度
E······major_negative類(lèi)言論強(qiáng)度
M······村民收購(gòu)的第一個(gè)物品的堆疊上限
V······玩家的村莊英雄效果等級(jí)(V < 1即無(wú)村莊英雄效果)
其中,作者自己定義的六角括號(hào)〔〕,代表此括號(hào)內(nèi)的運(yùn)算在得出結(jié)果后會(huì)被去除小數(shù)部分,只保留整數(shù)部分。比如〔18.5〕=18、〔-64.12〕=-65、〔0.1〕=0
上面的clamp(a,b,c)函數(shù),則用來(lái)限制a介于b、c之間(b≤c)。比如:
clamp(34,1,3)=3
\\ 34超過(guò)了最大值3,所以輸出3\\
clamp(12,8,88)=12
\\ 12介于8和88之間,所以還是輸出12\\
clamp(-44,9,73)=9。
\\-44低于最小值9,所以輸出9\\
你可能會(huì)感到疑惑:唉這個(gè)公式怎么和上一章的公式完全不一樣???
這個(gè)問(wèn)題很有趣。首先,上一章的公式僅僅只考慮了言論對(duì)價(jià)格的影響。仔細(xì)觀察,你也會(huì)發(fā)現(xiàn)這里的公式中含有上一章的公式。那這有趣究竟在哪里呢?
上一章的公式來(lái)自Minecraft Wiki。在中文Minecraft Wiki的村民頁(yè)面上,還有另一個(gè)價(jià)格計(jì)算公式。而這個(gè)公式,對(duì)于聲望的計(jì)算,是完全不一樣的!
y = m -〔(5A + B + C - D - 5E)× p〕
\\僅考慮言論的價(jià)格公式\\
y =〔a×p×m〕+〔p×D〕-〔p×C×10〕+e+m
a······該交易項(xiàng)目demand標(biāo)簽的值
p······價(jià)格乘數(shù)
e······該交易項(xiàng)目specialPrice標(biāo)簽的值
m······原價(jià)
C······trading類(lèi)言論強(qiáng)度
D······minor_negative類(lèi)言論強(qiáng)度
\\ Minecraft Wiki上的計(jì)算公式\\
于是,作者基于這兩個(gè)公式,通過(guò)一些實(shí)驗(yàn),總結(jié)出了上面的那個(gè)計(jì)算公式。
但不管如何,這個(gè)錯(cuò)誤仍是一個(gè)較為嚴(yán)重的錯(cuò)誤,因?yàn)樗呀?jīng)存在了很長(zhǎng)時(shí)間,并有許多教程引用了這個(gè)公式,影響范圍較大。
需要注意的是,上述公式都有涉及到言論系統(tǒng),但言論系統(tǒng)目前(2022年12月28日)僅僅存在于Java版中,所以上述公式不一定適用于基巖版。
PS: 2022年12月4日,Minecraft Wiki的用戶Nickid2018終于將百科的計(jì)算公式改了。新的計(jì)算公式如下:
e =聲望影響的降價(jià)+村莊英雄效果影響的降價(jià)
y = clamp(m×〔1+a×p〕+e,1,M)
a······該交易項(xiàng)目demand標(biāo)簽的值
p······價(jià)格乘數(shù)
e······該交易項(xiàng)目specialPrice標(biāo)簽的值
m······原價(jià)
M······村民收購(gòu)的第一個(gè)物品的堆疊上限
這個(gè)公式與上面作者自己得出的公式相差不大,但仍有一個(gè)可能的問(wèn)題:
e(specialPrice)的值的計(jì)算方式可能有誤
要說(shuō)明為什么有這個(gè)問(wèn)題,我們得先了解一下specialPrice的機(jī)制。
當(dāng)一名玩家打開(kāi)村民的交易界面時(shí),游戲會(huì)計(jì)算每個(gè)交易項(xiàng)目的實(shí)際價(jià)格。這時(shí)候,游戲會(huì)先計(jì)算言論和村莊英雄效果的影響,并將它們的值加到每個(gè)交易項(xiàng)目的specialPrice標(biāo)簽中。第二步,游戲才會(huì)根據(jù)demand等其他標(biāo)簽,綜合計(jì)算出每個(gè)交易項(xiàng)目的值。在這個(gè)過(guò)程中,specialPrice標(biāo)簽會(huì)加到計(jì)算的值中。第三步,也就是向玩家展示這些交易項(xiàng)目。最后,當(dāng)玩家關(guān)閉村民的交易界面時(shí),游戲會(huì)把每個(gè)交易項(xiàng)目的specialPrice標(biāo)簽清零。
也就是說(shuō),如果要使得交易打折,specialPrice的值必須要為負(fù)。
但是,如果根據(jù)Minecraft Wiki的計(jì)算方式,specialPrice為負(fù)的情況只有一種可能:村民對(duì)于玩家具有過(guò)多的負(fù)面言論。而這是不可能的。
當(dāng)然,我們也別過(guò)多糾結(jié)這個(gè)問(wèn)題,該改正的總會(huì)改正,只不過(guò)是時(shí)間問(wèn)題。我們更加需要關(guān)心的有兩件事情:
1.我們肯定不希望我們自定義的商品價(jià)格被隨意改變,所以我們?cè)撛趺崔k呢?
2.specialPrice的性質(zhì)可以弄出什么效果呢?
對(duì)于第一個(gè)問(wèn)題,我們的解決方法很簡(jiǎn)單——仔細(xì)觀察上面的公式,我們不難發(fā)現(xiàn)『p價(jià)格乘數(shù)』都是一個(gè)及其重要的變量。
既然是『乘數(shù)』,如果我們把這東西改為0,那問(wèn)題是不是就解決了?
試一試!當(dāng)p=0時(shí)
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 = clamp(〔a×0×m〕+m -〔((V-1)×0.0625+0.3)×m〕+f, 1 ,M)
y = clamp(m -〔((V-1)×0.0625+0.3)×m〕+f, 1 ,M)
不難發(fā)現(xiàn),就算p=0解決了大多數(shù)問(wèn)題,但村莊英雄效果和specialPrice的原始值仍然會(huì)影響到價(jià)格。但村莊英雄效果畢竟是很難得到的,specialPrice的原始值又是只能通過(guò)命令改變,所以總體上來(lái)說(shuō)影響很小。
總結(jié)下來(lái),相比更新之前,我們?cè)谛掳姹局凶远x村民交易,還需要注意將價(jià)格乘數(shù)priceMultiplier設(shè)為0.0(有沒(méi)有一種可能,不設(shè)置其實(shí)也默認(rèn)是0)。舉個(gè)例子:
/summon villager ~~~{VillagerData:{level:6,profession:“minecraft:farmer“},Offers:{Recipes:[{rewardExp: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:sharpness“,lvl:10}]}},priceMultiplier:0.0}]}}
這個(gè)例子是我們第一百五十四章的一個(gè)舊版例子的新版寫(xiě)法,只不過(guò)將暮色森林Mod的幻影騎士戰(zhàn)利品換成了普通的鉆石。
上面這條指令將會(huì)生成一個(gè)等級(jí)為6的農(nóng)民,并帶有一個(gè)『具有15萬(wàn)次使用次數(shù)、每次交易返回1點(diǎn)經(jīng)驗(yàn)值、價(jià)格乘數(shù)為0.0、能夠用1鉆石加上10綠寶石買(mǎi)一個(gè)附魔有鋒利X的鉆石劍』的交易項(xiàng)目。
那對(duì)于第二個(gè)問(wèn)題呢?
既然游戲在計(jì)算specialPrice時(shí)會(huì)將specialPrice的初始值加上,那么只要控制得當(dāng),在玩家打開(kāi)交易項(xiàng)目之前就更改specialPrice的值,就能做到自定義折扣。
另外,修改specialPrice的值并不會(huì)影響到村民給正在交易中的玩家的商品價(jià)格。
村莊與掠奪更新后的自定義交易到此就結(jié)束了,你現(xiàn)在可以嘗試去自定義一個(gè)新版本的村民,看看效果如何。
附表:新版本村民歷史
Java
1.14——對(duì)村民進(jìn)行了大改
1.14.3/1.14.4——優(yōu)化
1.15——傻子村民現(xiàn)在沒(méi)有徽章,村民會(huì)被玩家趕下床
1.16——優(yōu)化
1.16.2——工作站點(diǎn)優(yōu)化
攜帶/基巖版
1.10.0——大改
1.11.0——優(yōu)化
1.13.0——村民現(xiàn)在會(huì)在戰(zhàn)勝襲擊后歡呼
1.16.220——村民現(xiàn)在不再能夠穿墻過(guò)去睡覺(jué)
1.18.10——村民現(xiàn)在會(huì)發(fā)射煙花火箭慶祝,交易時(shí)頭頂不會(huì)再出現(xiàn)綠寶石圖標(biāo)
1.18.30——優(yōu)化