首頁 游戲

Minecraft指令手冊

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

Minecraft指令手冊 你好MC 1964 2020-01-10 20:23:16

  ——游戲模式——

  用游戲模式篩選玩家的參數,在Java1.13及以上版本中是gamemode,在基巖版以及低于Java1.13的版本均為m。

  那么它們是怎么用的呢?

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

  /gamemode a @a[x=726,y=89,z=-263,r=50]

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

  /gamemode a @a[x=726,y=89,z=-263,r=50,m=s]

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

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

  /tp @a[r=20,m=6]^^^-100(僅適用于基巖版)

  這條指令的作用是:將以基準點(在這是指令執(zhí)行位置)為中心,半徑20格內的所有處于旁觀模式的玩家,全都傳送到執(zhí)行者背后100米處(^^^-100為局部坐標,會在第五十九章講到?!?』在這是基巖版1.19及以上版本為實驗玩法的旁觀者模式的數字ID。沒錯,基巖版也有旁觀者模式了,只不過在測試而已)

  而gamemode參數.......在Java1.13版本中,Mojang重寫了大量游戲基礎代碼,導致Java1.12.2和1.13版本中,許多游戲內容差異極大。所以在之前的章節(jié)中,你會發(fā)現許多指令都在Java1.13更新中發(fā)生了大改,這種情況在以后的章節(jié)中也會持續(xù)存在。游戲模式也一樣,在Java1.13版本更新后,游戲模式就僅支持全稱,即:

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

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

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

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

  /kill @a[r=15,m=!c]

  這條指令的意思是:將范圍15格內所有不處于創(chuàng)造模式的玩家全部殺死。

  仔細觀察這條指令,你發(fā)現了什么?

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

  /kill @a[distance=..15,gamemode=!creative]

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

  ——目標名稱——

  name參數可以用于選取指定名稱的實體。

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

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

  舉個例子:

  /give @a[name=JIE灬揮刀亂砍] Skyward_Blade

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

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

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

  /summon minecraft:armor_stand ~~~{CustomName:“\“A\““}

  \\召喚一個名為A的盔甲架\\

  /spreadplayers ~~ 32 10000 false @e[type=minecraft:armor_stand,name=A]

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

  /execute as @e[type=minecraft:armor_stand,name=A] at @s run ......(后面省略)

  \\將執(zhí)行者、執(zhí)行位置和旋轉角度都設定為名為A的盔甲架,并運行.....\\

  可以發(fā)現,該腐竹為了防止執(zhí)行指令時和其他實體發(fā)生沖突,特別使用了名叫A的盔甲架并用name參數鎖定。同時,這位腐竹還用到了type參數。關于這個參數待會會講到。

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

  /kill @e[name=!A]

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

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

  /kill @e[name=“genshin impact“]

  ——垂直旋轉角度——

  ——水平旋轉角度——

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

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

  在Java1.13及以上版本中,垂直旋轉角度參數是x_rotation,水平旋轉角度參數是y_rotation。在Java1.13以下和基巖版中,兩類角度分別是rx、rxm和ry、rym。

  唉,你發(fā)現了沒有?這和我們之前了解過的經驗參數(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:重復,無條件,始終活動

  /execute @e[type=snowball]~~~ execute @p[r=1.5,rx=90,rxm=60]~~~ execute @e[type=snowball,c=1]~~~ tag @s add back_home

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

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

  /execute @e[type=snowball,tag=back_home]~~~ tp @p[r=1.5] 323 65 72

  \\選取具有back_home標簽的雪球,并以它為中心將半徑1.5格內最靠近它的玩家傳送到(323,65,72)。\\

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

  /kill @e[type=snowball,tag=back_home]

  \\清除所有具有back_home標簽的雪球\\

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

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

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

  /kill @a[ry=180,rym=-180]

  這條指令可以殺死所有面向正北的玩家(神奇的是這并不會框選住所有活著的玩家,@a[ry=180,rym=179]才會框選住幾乎所有活著的玩家)

  至于x_rotation和y_rotation參數,你應該知道怎么用了吧?

  @a[x_rotation=35..]——所有頭水平線朝下35°及以上的玩家

  @a[x_rotation=..35]——所有頭沒有水平線朝下35°以上的玩家

  @a[x_rotation=0..35]——所有頭水平線朝下0到35°(含)的玩家

  @a[x_rotation=35]——所有頭水平線朝下35°的玩家

  @a[y_rotation =60..]——所有朝向是在南偏西60°順時針到正北這個范圍內的玩家

  @a[y_rotation =..60]——所有朝向是在南偏西60°逆時針到正北這個范圍內的玩家

  @a[y_rotation =60..120]——所有朝向是在南偏西60°順時針到北偏西60°這個范圍內的玩家

  @a[y_rotation =60]——所有朝著南偏西60°的玩家

  ——實體類型——

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

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

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

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

  /kill @e[type=minecraft:villager]

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

  type一般來說僅用于@e,因為只有@e是包含非玩家實體的。在Java1.13以下和基巖版中,你也可以用在@r中來隨機選擇特定類型的實體。

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

  /kill @e[type=!player]

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

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

  @e[type=cow,type=player]

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

  ——實體家族——

  我們知道通過type可以選取特定類型的實體。但如果我們要選取一堆不同類型的實體用于執(zhí)行同一種指令呢?

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

  Mojang估計看我們這么可憐,于是在基巖版1.16.100中,加入了family參數。

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

  什么是實體家族?

  舉個例子:

  僵尸知道吧?僵尸一般來說有三類變種:

  尸殼、僵尸村民、溺尸

  雖然它們客觀上并不屬于同一種實體,但主觀上我們仍然會將它們歸類到一個大類:僵尸類。

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

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

  舉個例子:

  /tp @e[family=creeper]@s

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

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

  你可以在Minecraft Wiki上搜索『族』詞條來查看原版所有可用的實體家族。

  ——物品——

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

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

  hasitem目標選擇器參數

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

  背包具有很多個物品欄,每個物品欄具有多個欄位,欄位儲存著物品。因此,每個放在背包中的物品都具有欄位標簽。物品有很多個種類,因此,物品還具有id標簽。大部分類型的物品可以堆疊,因此,物品還具有數量標簽。在Java1.13以下版本和基巖版中,同id的物品也可能不同,因此,物品在這些版本中還具有數據值標簽。

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

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

  一個條件項目可以檢測單個類型的物品,具體來說可以指定以下的參數:

  item——物品id

  data——物品的數據值[可選]

  quantity——限制所選范圍內物品的總數量[可選]

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

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

  比如:

  {item=bed,data=1}

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

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

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

  {item=dirt,quantity=100..}

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

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

  {item=dirt,quantity=!100..}

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

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

  {item=dirt,quantity=0}

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

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

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

  {item=dirt,quantity=0,location=slot.enderchest}

  這將會選取所有在其末影箱內沒有泥土的實體。需要注意,對于玩家來說,默認是不會檢測到末影箱的。也就是說,如果你在末影箱內放了一塊泥土,那么{item=dirt,quantity=0}這個條件還是會選擇到你,但{item=dirt,quantity=0,location=slot.enderchest}這個條件則不會。另外,即使是對于沒有末影箱的非玩家實體,游戲仍然會假裝其具有末影箱,然后又因為游戲假裝出來的末影箱內沒有泥土,導致上述條件也會選擇到非玩家實體。

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

  {item=dirt,quantity=1..,location=slot.enderchest,slot=0}

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

  {item=dirt,quantity=1..,location=slot.enderchest,slot=1..}

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

  {item=dirt,quantity=1..,location=slot.enderchest,slot=!0}

  \\同上\\

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

  /testfor @a[hasitem={item=dirt,quantity=1..,location=slot.enderchest,slot=!0}]

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

  @a[hasitem=[{item=dirt},{item=apple}]]

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

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

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

  ——NBT——

  ——進度——

  ——謂詞——

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

  附錄:目標選擇器發(fā)展歷史

  Java

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

  1.8——加入了@e變量和dx、dy、dz參數

  1.9——m參數現在接受游戲模式全稱和縮寫,在此版本之前只支持數字ID。并加入了tag參數。

  1.11——移除了隱含目標選擇器(如@a[26,65,-28],代表@a[x=26,y=65,z=-28]),并且錯誤的目標選擇器不再略過,而是會報錯。

  1.12——加入了@s變量

  1.13——加入了NBT和進度advancements參數,并對原本的參數進行大改

  1.15——加入了謂詞predicate

  基巖版

  1.16.100——加入了family參數

  1.17.10——加入@initiator變量用于NPC

  1.18.30——加入了hasitem參數

 ?。ㄗⅲ壕W易版我的世界截止目前[2022.8.3]僅僅更新到1.18.10版本,因此沒有hasitem參數)

按 “鍵盤左鍵←” 返回上一章  按 “鍵盤右鍵→” 進入下一章  按 “空格鍵” 向下滾動
目錄
目錄
設置
設置
書架
加入書架
書頁
返回書頁
指南