UU看書

第二十六章 更加精確的目標選擇器 下

天才一秒記住【UU看書】地址:www.uukanshu.co

——遊戲模式——

用遊戲模式篩選玩家的引數,在Java113及以上版本中是gamemode,在基岩版以及低於Java113的版本均為m。

那麼它們是怎麼用的呢?

眾所周知,基岩版伺服器並沒有像Java版伺服器一樣具有出生點保護,所以在基岩版,要讓伺服器主城不被惡意破壞,最基本的操作就是使用『範圍冒險模式』。比如這個中國版租貸服最初就用瞭如下指令:

gamemodeaax726,y89,z263,r50

重複執行這條指令,就可以讓主城範圍50格內的所有玩家都改為冒險模式。但這有個缺點:腐竹也被改為冒險模式了。為了解決這個問題,這個腐竹給該目標選擇器新增了一個引數,變成:

gamemodeaax726,y89,z263,r50,ms

這條指令和上一條指令的唯一區別就在於,它不會將不是生存模式的玩家改為冒險模式,這樣子腐竹開著創造就不會受到影響了。其中新新增的m引數,值是s,也就是survival(生存)的縮寫。

m引數可以使用遊戲模式的全稱,縮寫和數字ID。比如:

tpar20,m6100(僅適用於基岩版)

這條指令的作用是:將以基準點(在這是指令執行位置)為中心,半徑20格內的所有處於旁觀模式的玩家,全都傳送到執行者背後100米處(100為區域性座標,會在第五十九章講到。『6』在這是基岩版119及以上版本為實驗玩法的旁觀者模式的數字ID。沒錯,基岩版也有旁觀者模式了,只不過在測試而已)

而gamemode引數在Java113版本中,Mojang重寫了大量遊戲基礎程式碼,導致Java1122和113版本中,許多遊戲內容差異極大。所以在之前的章節中,你會發現許多指令都在Java113更新中發生了大改,這種情況在以後的章節中也會持續存在。遊戲模式也一樣,在Java113版本更新後,遊戲模式就僅支援全稱,即:

survival(生存模式)、creative(創造模式)、adventure(冒險模式)和spectator(旁觀模式)。

所以,雖然gamemode引數和m用法一樣,但它僅支援上面四個值。

現在我們知道如何選擇特定遊戲模式的玩家。但如果我們要反過來,排除特定模式的玩家該怎麼辦?

這位腐竹造了一個房子。為了防止他的房子被破壞,就做了一個簡易的安保措施:

killar15,mc

這條指令的意思是:將範圍15格內所有不處於創造模式的玩家全部殺死。

仔細觀察這條指令,你發現了什麼?

沒錯,m引數要反過來排除特定模式的玩家,只需要在值前面加一個英文半形感嘆號。和m引數一樣,gamemode引數也同理:

killadistance15,gamemodecreative

感嘆號的這種用法,其實就是不等號在計算機語言中的常見形式()。這種不等號反轉選擇的用法在接下來幾個目標選擇器引數中也會頻繁出現。

——目標名稱——

name引數可以用於選取指定名稱的實體。

使用give給予某位特定玩家物品時,一般不會用到目標選擇器,而是直接指定該玩家的玩家名(不會吧,不會吧,不會真的有人會用玩家的UUID來使用give指令吧)。

但如果要用目標選擇器,還要鎖定這名玩家該怎麼辦?

舉個例子:

giveanameJIE灬揮刀亂砍SkywardBlade

這樣子就可以鎖定這名玩家並給予物品了。

name引數不光可以用於玩家名上,還可以用於實體名上。

比如某位Java腐竹為了實現將寶箱隨機放在世界各處,用瞭如下指令:

summonminecraftarmorstandCustomName““A““

召喚一個名為A的盔甲架

spreadplayers3210000falseetypeminecraftarmorstand,nameA

將所有名為A的盔甲架隨機傳送到以該命令方塊為中心的20001×20001範圍內,且每個盔甲架間距不小於32格,不考慮盔甲架的隊伍屬性

executeasetypeminecraftarmorstand,nameAatsrun(後面省略)

將執行者、執行位置和旋轉角度都設定為名為A的盔甲架,並執行

可以發現,該腐竹為了防止執行指令時和其他實體發生衝突,特別使用了名叫A的盔甲架並用name引數鎖定。同時,這位腐竹還用到了type引數。關於這個引數待會會講到。

name引數也可以像m、gamemode引數一樣,使用感嘆號反轉為排除指定名稱的實體,比如:

killenameA

這條指令的作用就是:殺死名字不是A的實體。

需要注意一點,如果名字中包含空格,需要用雙引號括起。比如:

killename“genshinimpact“

——垂直旋轉角度——

——水平旋轉角度——

還記得第九章的tp嗎?我們就在那第一次接觸到了垂直旋轉角度和水平旋轉角度:

這兩個由於是同類,本書就合起來講了。

在Java113及以上版本中,垂直旋轉角度引數是xrotation,水平旋轉角度引數是yrotation。在Java113以下和基岩版中,兩類角度分別是rx、rxm和ry、rym。

唉,你發現了沒有?這和我們之前瞭解過的經驗引數(l、lm和level)還有距離引數(r、rm和distance)差不多。那麼格式是不是也是一樣呢?

還真是一樣的。既然格式一樣,這裡就不多說它的格式了。

rx、ry引數的作用是:選取垂直、水平旋轉角度小於等於RX或RY的實體

rxm、rym引數的作用是:選取垂直、水平旋轉角度大於等於RXM或RYM的實體

垂直旋轉角度其範圍是:90度(看地上)到90度(看天空)。

水平旋轉角度其範圍是:180度(北)到180度(還是北),或者說是上北180°,下南0°。左西90°,右東90°。

等等,我們在講tp時,不是說水平旋轉角度是:『以實體為中心,以正南(z軸正方向)為0°,順時針下來,實體朝向和正南方向的夾角(也或者說實體在真南方位角體系中朝向的角度),就是該實體的水平旋轉角度。』

那這怎麼跑出來負數了?

其實在Minecraft中,水平旋轉角度雖然可以像我們之前在第九章講tp時那麼用,但大多數時候,你都得這麼用:

以正南(z軸正方向)為0°,順時針旋轉180°透過正西至正北,用正數,逆時針旋轉180°透過正東至正北,用負數。比如45°,就代表以正南為基準,逆時針旋轉45°的方向;30°,就代表以正南為基準,順時針旋轉30°的方向。

也就是說,在Minecraft中,水平旋轉角度的正確範圍是180°180°,而不是0°360°。至於為什麼我要在第九章那麼講,只是怕一下子就把負數搬出來會嚇你們一跳。

現在我們回到正題。

舉個例子。某網易手機租貸服為了讓玩家回城方便,搞了一個“回城雪球”,其指令如下:

A→B→C→

A:重複,無條件,始終活動

executeetypesnowballexecutepr15,rx90,rxm60executeetypesnowball,c1tagsaddbackhome

選取雪球作為指令執行者,再以這個雪球為中心尋找半徑15格內最近的低著頭(頭自水平線向下90°到向下60°)的玩家。如果找到,再以該玩家為中心尋找最靠近他的雪球,並給這個雪球賦予backhome標籤。

B:連鎖,有條件的,始終活動

executeetypesnowball,tagbackhometppr153236572

選取具有backhome標籤的雪球,並以它為中心將半徑15格內最靠近它的玩家傳送到323,65,72。

C:連鎖,有條件的,始終活動

killetypesnowball,tagbackhome

清除所有具有backhome標籤的雪球

其中就有用到rx和rxm引數,用於篩選那些低著頭扔雪球的玩家。

至於其中出現的tag引數,我們在上一章已經略過了。關於tag會在以後講到計分板時提到。

ry和rym引數目前來說沒有特別廣的用途,只能舉個沒啥用的例子:

killary180,rym180

這條指令可以殺死所有面向正北的玩家(神奇的是這並不會框選住所有活著的玩家,ary180,rym179才會框選住幾乎所有活著的玩家)

至於xrotation和yrotation引數,你應該知道怎麼用了吧?

axrotation35——所有頭水平線朝下35°及以上的玩家

axrotation35——所有頭沒有水平線朝下35°以上的玩家

axrotation035——所有頭水平線朝下0到35°(含)的玩家

axrotation35——所有頭水平線朝下35°的玩家

ayrotation60——所有朝向是在南偏西60°順時針到正北這個範圍內的玩家

ayrotation60——所有朝向是在南偏西60°逆時針到正北這個範圍內的玩家

ayrotation60120——所有朝向是在南偏西60°順時針到北偏西60°這個範圍內的玩家

ayrotation60——所有朝著南偏西60°的玩家

——實體型別——

實體型別是type,上面我們已經見過了。

type和name本質上是差不多的,但是它篩選不是透過名字,而是透過實體種類。

什麼是實體種類?比如一個玩家叫Notch,另一個玩家叫Herobrine,雖然名字不同,但他們都是『玩家』種類的。又比如這裡有一隻馬,那裡有一隻叫馬的驢,雖然它們都叫馬,但前者是馬,後者是驢,並不是一個種類的。

type可以選定指定型別的實體,比如:

killetypeminecraftvillager

就可以殺死全部已生成的村民。

type一般來說僅用於e,因為只有e是包含非玩家實體的。在Java113以下和基岩版中,你也可以用在r中來隨機選擇特定型別的實體。

和name一樣,type也支援感嘆號反轉:

killetypeplayer

這條指令的作用是:殺死所有非玩家實體。

需要注意的是,name和type這兩個引數在非感嘆號反轉的情況下都是不可重疊的,比如:

etypecow,typeplayer

像上面那樣是不可以的,Minecraft中可沒有既是牛又是玩家的動物。如果真有,那麼也應該合併成為一個新的實體,也許會叫作cowplayer(牛人)呢。

——實體家族——

我們知道透過type可以選取特定型別的實體。但如果我們要選取一堆不同型別的實體用於執行同一種指令呢?

記分板、NBT和標籤可以很好的解決這個問題。但在瞭解這三個東西之前,我們暫且沒有除多弄命令方塊以外的更好的辦法。

Mojang估計看我們這麼可憐,於是在基岩版116100中,加入了family引數。

family引數和type引數差不多,只不過它是透過實體家族篩選的。

什麼是實體家族?

舉個例子:

殭屍知道吧?殭屍一般來說有三類變種:

屍殼、殭屍村民、溺屍

雖然它們客觀上並不屬於同一種實體,但主觀上我們仍然會將它們歸類到一個大類:殭屍類。

用Mojang的說法,它們都是屬於同一個族(family)的。

現在你應該知道實體家族到底是什麼了吧?

舉個例子:

tpefamilycreepers

這條指令的作用是:將所有屬於苦力怕家族的實體傳送到自己身旁。

當然,你也可以使用感嘆號將作用反轉。需要注意,和type、name引數不同的是,family引數在非反轉情況下也是可以疊加使用的,因為有些實體可能會屬於多個族。

你可以在MinecraftWiki上搜尋『族』詞條來檢視原版所有可用的實體家族。

——物品——

我們知道,在Java版中,如果要篩選具有指定物品的實體,可以使用NBT或clear。那在基岩版中該怎麼辦?使用replaceitem或clear嗎?

這的確是兩種可行的方法,但Mojang還給了我們第三個方法:

hasitem目標選擇器引數

這個引數可能會比較複雜,因此在瞭解這個引數之前,我們得先了解一下:揹包中的物品

揹包具有很多個物品欄,每個物品欄具有多個欄位,欄位儲存著物品。因此,每個放在揹包中的物品都具有欄位標籤。物品有很多個種類,因此,物品還具有id標籤。大部分型別的物品可以堆疊,因此,物品還具有數量標籤。在Java113以下版本和基岩版中,同id的物品也可能不同,因此,物品在這些版本中還具有資料值標籤。

hasitem引數可以用來選取具有指定物品的實體。更準確一點來說,hasitem引數可以透過檢測已選實體的揹包中指定條件下的物品,來篩選實體。

hasitem引數的值比較特別,它的值可以是單個條件,也可以是由多個條件組成的條件列表。讓我們來看看hasitem引數的一個條件專案到底可以指定哪些東西。

一個條件專案可以檢測單個型別的物品,具體來說可以指定以下的引數:

item——物品id

data——物品的資料值可選

quantity——限制所選範圍內物品的總數量可選

location——需要檢測的物品欄可選

slot——需要檢測的槽位可選,必須配合location引數使用

比如:

itembed,data1

這個條件可以篩選揹包內具有橙色床的實體。不難發現,單個條件可以具有多個不同的篩選引數,並且外面要使用花括號()包裹起來。

需要注意的是,data引數目前有個BUG,就是不能適用於方塊類物品。如果你對一個方塊類物品使用了data引數,那麼不管你怎麼改data的值,遊戲總會認為該引數的值為0。怎麼判斷一個物品是不是方塊類的呢?看物品的圖示。如果圖示是直接給出了方塊的3D影象(也就是渲染圖),比如羊毛,那就是方塊類物品。像是床這種圖示是專門畫的就不是方塊類物品,所以能夠正常使用data引數。

quantity引數得好好講一講,它並不是說檢測單個欄位內物品的數量,而是檢測整個範圍內的指定型別物品數量總和。比如:

itemdirt,quantity100

這個條件可以選擇到那些揹包內泥土數量達到甚至超過100塊的實體。也就是說,假設這裡有一個張三,揹包內有兩組泥土,那麼這個條件就可以選擇到它。

不難發現,quantity的值簡直是基岩版的一股清流,竟然向Java113及以上的版本學習,採用了Java版先進的『兩點法』,不錯不錯,值得表揚。而且,這引數還在Java版的基礎上改造了一下,變成了還可以使用不等號進行反選:

itemdirt,quantity100

這將會選取擁有泥土數量<100的實體。

對了,如果你指定了這個引數為0,那就可以選擇『沒有指定物品的實體』:

itemdirt,quantity0

這將會選取揹包內沒有泥土的實體。

location引數可以縮小檢測的範圍到指定的物品欄。具體可以使用哪些物品欄以及這裡的物品欄是個啥東西這就需要你前往第三十八章瞭解replaceitem指令。

這裡就先假裝你已經搞懂了這些內容。舉個例子:

itemdirt,quantity0,locationslotenderchest

這將會選取所有在其末影箱內沒有泥土的實體。需要注意,對於玩家來說,預設是不會檢測到末影箱的。也就是說,如果你在末影箱內放了一塊泥土,那麼itemdirt,quantity0這個條件還是會選擇到你,但itemdirt,quantity0,locationslotenderchest這個條件則不會。另外,即使是對於沒有末影箱的非玩家實體,遊戲仍然會假裝其具有末影箱,然後又因為遊戲假裝出來的末影箱內沒有泥土,導致上述條件也會選擇到非玩家實體。

在使用location引數時,還可以更進一步使用slot引數來縮小檢測範圍到指定的欄位。比如:

itemdirt,quantity1,locationslotenderchest,slot0

這將會選取到所有在其末影箱左上角第一格內放有泥土的玩家。和quantity一樣,這引數同樣也支援升級後的『兩點法』:

itemdirt,quantity1,locationslotenderchest,slot1

選取到所有在其末影箱內除了左上角第一格外其他位置放有泥土的玩家

itemdirt,quantity1,locationslotenderchest,slot0

同上

上面這些都是一個條件內可以弄的引數,hasitem引數的值也確實可以直接放入單個條件:

testforahasitemitemdirt,quantity1,locationslotenderchest,slot0

但是如果要多個條件呢?這時候就需要用到列表:

ahasitemitemdirt,itemapple

這將會選擇到揹包內同時具有泥土和蘋果的玩家。

不難發現,在多個條件組成的列表中,每個條件也是使用逗號分開,列表最外側被中括號()包起來。

這就是hasitem引數的具體使用方法,其中部分內容超綱了一些,但總體上還是易於理解的。

——NBT——

——進度——

——謂詞——

上面這三個均為Java版獨有,且我們還未接觸到,暫時先留個坑,以後再填。

附錄:目標選擇器發展歷史

Java

142——加入目標選擇器,最初只有a、r、p三個變數

18——加入了e變數和dx、dy、dz引數

19——m引數現在接受遊戲模式全稱和縮寫,在此版本之前只支援數字ID。並加入了tag引數。

111——移除了隱含目標選擇器(如a26,65,28,代表ax26,y65,z28),並且錯誤的目標選擇器不再略過,而是會報錯。

112——加入了s變數

113——加入了NBT和進度advancements引數,並對原本的引數進行大改

115——加入了謂詞predicate

基岩版

116100——加入了family引數

11710——加入initiator變數用於NPC

11830——加入了hasitem引數

(注:網易版我的世界截止目前202283僅僅更新到11810版本,因此沒有hasitem引數)

如遇章節錯誤,請點選報錯(無需登陸)

新書推薦

電競之墨墨無聞 原神:從遇到旅行者開始 開局解約,我用足球征服歐洲 籃壇傳奇:雙能衛之王 地下城經營手冊 LOL:我的英雄海 極限之路,游泳之神